/************************************************************************************
简单的小车驱动 小车学会了躲避障碍物
*************************************************************************************/
#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里能进中断退不出来,麻烦师傅看一下,谢谢了
|