打印

51单片机中断问题 进入 后不能退出

[复制链接]
4674|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
rdfeps|  楼主 | 2014-5-10 22:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/************************************************************************************
简单的小车驱动  小车学会了躲避障碍物
*************************************************************************************/


#include <reg52.h>
#include <intrins.h>
#define  NOP() _nop_()  /* 定义空指令 */

//SPI IO
sbit MOSIO =P1^0;
sbit R_CLK =P1^1;
sbit S_CLK =P1^2;  //移位寄存器时钟
sbit EN=P1^3;         //使能端
sbit flag =P1^7;
sbit zhong =P3^2;
void delay10ms(unsigned char e);   //误差 -0.000000000002us
void delay1s(unsigned char d);      //函数声名
void HC595SendData(unsigned char dat);

//unsigned char code table[]={ 0x27,0x27, 0x27,0x27} ;  //定义电机驱动数组0x27,0xc6, 0xd8,0x39 包含前进,原声左转,后退,原声右转


main()
{ // unsigned char i;
      EN=0;   //595
           S_CLK=0;  //595
                R_CLK=0;   //595
                delay1s(1);

  EA=1;  // 打开总中断
  EX0=1;  //允许外部中断0申请中断
  IT0=1;  // 下降沿触发
  
  while(1)
  {
  HC595SendData(0x27);
  delay1s(100);
/*********并口数据转换成串行发送节省I/O口*********************       
     i=0;
                  for (i;i<4;i++)    //4个数据,循环4次
                 {   
                 HC595SendData (table[i]);
    //   if (i==1|i==3)
                                delay1s(10);
        //                        else  delay1s(2);
         }       
***********以下一段用于躲避障碍物**************************/                         
                 
  }   
}       
/*****************************************************************************
*  延时子程序                                                                                                                             *
*                                                                                                                                                         *
******************************************************************************/
void delay1s(unsigned char d)   //误差 0us
{
    unsigned char a,b,c;
    while (d--)
         {
      for(c=46;c>0;c--)
        for(b=152;b>0;b--)
            for(a=70;a>0;a--);
      _nop_();  
     }
}
void delay10ms(unsigned char e)   //误差 -0.000000000002us
{
    unsigned char a,b;
while (e--)
   { for(b=249;b>0;b--)
       for(a=17;a>0;a--);

                  }
}

/*********************************************************************************************************
** 函数名称: HC595SendData
*********************************************************************************************************/
void HC595SendData(unsigned char dat)
{  
  unsigned char j;
               
  for(j=0;j<8;j++)
   {
        if((dat<<j)&0x80) MOSIO=1; //set dataline high  0X80  最高位与SendVal左移的最高位 进行逻辑运算
        else MOSIO=0;                                   // 如果为真 MOSIO = 1  

        S_CLK=0;
        NOP();        //移位寄存器时钟
        NOP();
        S_CLK=1;
        NOP();                      //修正驱动轮只有一个转
        S_CLK=0;                    //修正驱动轮只有一个转
   }
   
   EN=1;                     //修正正反转太快
        delay10ms (10);             //修正正反转太快
        EN=0;                        //修正正反转太快
  R_CLK=0;
  NOP();   //存储寄存器时钟
  NOP();
  R_CLK=1;
  NOP();                      //修正驱动轮只有一个转
  R_CLK=0;                   //修正驱动轮只有一个转

}

/*************小车用中断0进行避障 **********************/
void zhongduan()  interrupt 0
{

  unsigned char x;
  
HC595SendData(0x00);
  flag=1;
  EX0=0;  //暂时关闭中断0
  x=P2;  // 保护现场
  switch (x)
    {
                 case 0x9f: { HC595SendData (0x39);
                               delay10ms (50);
                       while ( P3^2==0) ;                          //
                          HC595SendData(0x27);
                                                        } break;      //前防撞
      case 0xef: { HC595SendData (0x39);
                               delay10ms (50);
                        while ( P3^2==0) ;
                         HC595SendData(0x27);
                                                        } break;      //左后防撞
      case 0xdf: { HC595SendData (0x39);
                               delay10ms (50);
                         while ( P3^2==0) ;
                                              HC595SendData(0x27);
                                                        } break;      //左前防撞
      case 0xbf: { HC595SendData (0x39);
                                 delay10ms (50);
                      while ( P3^2==0) ;
                                              HC595SendData(0x27);
                                                        } break;      //右前防撞
      case 0x7f:  {HC595SendData (0x39);
                               delay10ms (50);
                        while ( P3^2==0) ;
                                              HC595SendData(0x27);
                                                        } break;      //右后防撞
          }
          IE0=0; // 标志 位清零
   HC595SendData(0x27);
          EX0=1;
          zhong=1;

        flag=0;  
        delay10ms (1);
        }


问题出在中断这里   case 0xdf: { HC595SendData (0x39);
                               delay10ms (50);
                         while ( P3^2==0) ;
                      HC595SendData(0x27);
                        } break;      //左前防撞
         我把while (P3^2==0)去掉了不行,再去掉HC595SendData (0x27) 才可以正常进退中断,不知道为什么  ? 只要去掉这两句,或者 把HC595SendData (0x27)放在switch语句后面就能正常进退中断,放到case里能进中断退不出来,麻烦师傅看一下,谢谢了

相关帖子

沙发
ayb_ice| | 2014-5-11 06:56 | 只看该作者
这什么程序嘛,中断还延时那么久,还死等等

使用特权

评论回复
板凳
ayb_ice| | 2014-5-11 07:01 | 只看该作者
你的
P3^2==0
原意是异或意思吗?
还是P3口的位2,如果是那就写错了,不能这样写

使用特权

评论回复
地板
ayb_ice| | 2014-5-11 07:04 | 只看该作者
怎么发了这么多,手机还是没有电脑方便

使用特权

评论回复
5
rdfeps|  楼主 | 2014-5-11 11:47 | 只看该作者
ayb_ice 发表于 2014-5-11 07:01
你的
P3^2==0
原意是异或意思吗?

这是四驱小车的程序,自己写的,用52单片机通过74HC595 串行发送数据 驱动两片L293D   HC595SendData(0x27)是前行代码    HC595SendData (0x39)是光电传感器遇到障碍后进入中断的转弯指令,用的是外部中断0,下降沿触发,当在switch语句中写HC595SendData(0x27)后就不能退出中断了,现象就是进入中断后,再遇到障碍不能躲避,当把 前进代码写在seitch语句后面就可以正常进退。while ( P3^2==0) 等待P3.2变成高电平这样不对吗?

使用特权

评论回复
6
272| | 2014-5-11 11:50 | 只看该作者
中断延时太久了

使用特权

评论回复
7
xy123151| | 2014-5-11 12:20 | 只看该作者
有测过执行一次中断里的代码需要多久吗?
可能是你中断里面的程序还没执行完,它又响应中断了,然后就一直在中断里面。
如果实时性要求不是非常高的话,你可以把中断里的东西放到while(1)循环里面,中断只设置一个标记。
一般不在中断里面用很长的循环,会死机的。
还没来及接触51就开始用112引脚的单片机了
不过有些是想通的吧

使用特权

评论回复
8
ayb_ice| | 2014-5-11 13:59 | 只看该作者
rdfeps 发表于 2014-5-11 11:47
这是四驱小车的程序,自己写的,用52单片机通过74HC595 串行发送数据 驱动两片L293D   HC595SendData(0x2 ...

P3^2==0;
可不是判断P3.2电平等于0的意思

使用特权

评论回复
9
ayb_ice| | 2014-5-11 14:28 | 只看该作者
"while ( P3^2==0) 等待P3.2变成高电平这样不对吗?"

确实不对

应该是

sbit P3_2 = P3^2;

while ( P3_2==0)

使用特权

评论回复
10
思宁| | 2014-5-11 16:33 | 只看该作者
楼上大侠真是热心 赞一个

使用特权

评论回复
11
rdfeps|  楼主 | 2014-5-12 23:20 | 只看该作者
ayb_ice 发表于 2014-5-11 14:28
"while ( P3^2==0) 等待P3.2变成高电平这样不对吗?"

确实不对

谢谢了师傅

使用特权

评论回复
12
rdfeps|  楼主 | 2014-5-12 23:20 | 只看该作者
xy123151 发表于 2014-5-11 12:20
有测过执行一次中断里的代码需要多久吗?
可能是你中断里面的程序还没执行完,它又响应中断了,然后就一直 ...

谢谢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

23

帖子

1

粉丝