为什么我的高优先中断打断不了低优先呢~~~~(>_<)~~~~
时间:10-02
整理:3721RD
点击:
当 进入自动行驶状态后 (EN=1)无法通过红外遥控进入 受控状态(EN=0)
- //*1.红外遥控:状态转换、转弯、变速;2.测距<30cm时车右转,<20cm向右急转*//
- #include<reg52.h>
- sbit Trig=P1^7;
- sbit IRIN=P3^2;// 外部中断0 红外遥控
- sbit Echo=P3^3;//外部中断1 超声波测距
- sbit Moto_R=P2^1;
- sbit Moto_L=P2^0;
- sbit LED_Y=P2^2;//遥控状态指示灯
- sbit LED_G=P2^3;//自动转弯指示灯
- void Int_0();
- void Timer();
- void measure();
- void Moto_1();
- void Moto_2();
- void Delay_100us();
- void Delay_2ms();
- void Delay_1ms();
- void DelayMs(unsigned int x);
- void RC();
- void LessSpeed();
- unsigned char code display_1[] = " Measuring... ";
- unsigned char code display_2[] ="Distance: . cm";
- unsigned char code display_3[] =">4m ";
- unsigned char code display_4[] =">4mTEST";
- unsigned char A1=48,B1=48,C1=48,D1=48;
- unsigned int a,b,c,d;
- unsigned int l;
- unsigned char IrValue[3];
- unsigned char Time,EN=0;
- void main()
- {
- EA=1;// 打开总中断
- Int_0();
- Timer();
- Moto_R=0;
- Moto_L=0;
- LED_Y=LED_G=0;
- while(1)
- {
- if(EN==1) //进入自动行驶状态
- {
- LED_Y=0;
- Moto_R=1,Moto_L=0;
- measure();
- if(IrValue[2]==0x45)
- EN=0;
- }
- else //受控状态
- {
- TR0=0; //关闭定时器0
- EX1=0;
- Moto_R=Moto_L=0;
- while(EN==0)
-
- {
- LED_G=0;
- LED_Y=1;
- RC();
- }
-
- }
-
-
- }
- }
- //外部中断设置
- void Int_0()
- {
- IT0=1;//外部中断0跳变沿触发方式(下降沿)
- EX0=1;//打开INT0的中断允许
- IT1=1;//外部中断1跳变沿触发方式(下降沿)
- EX1=0;//关闭INT1的中断允许
- }
- //定时器设置
- void Timer()
- {
- TMOD=0X01;//定时器0选择工作方式
- TR0=0; //关闭定时器0
- }
- //测量长度程序
- void measure()
- {
- EX1=1;//打开INT1的中断允许
- TH0=0X00;//设置初始值
- TL0=0X00;
- Trig=1;
- Delay_1ms();
- Trig=0;
- while(Echo==1)
- ;
- TR0=1; //打开定时器0
- }
- //外部中断0(判断是否转弯)
- void Judge() interrupt 2
- {
- l=(TH0*256+TL0)*1.0/58; //测量长度 单位cm
- TR0=0;//关闭定时器
- if(l<30)
- Moto_1(),LED_G=1;
- else if(l<20)
- Moto_2(),LED_G=1;
- else LED_G=0;
- }
- //pwm调制右轮减速向右转
- void Moto_1()
- {
- Moto_R=Moto_L=0;
- Delay_100us();
- Moto_R=1,Moto_L=0;
- Delay_100us();
- Delay_100us();
- }
- //急转
- void Moto_2()
- {
- Moto_R=Moto_L=0;
- Delay_2ms();
- }
- void Delay_100us()
- {
- unsigned char a,b,c;
- for(a=0;a<1;a++)
- for(b=0;b<1;b++)
- for(c=0;c<28;c++);
- }
- void Delay_2ms()
- {
- unsigned char a,b,c;
- for(a=0;a<2;a++)
- for(b=0;b<3;b++)
- for(c=0;c<220;c++);
- }
- void Delay_1ms()
- {
- unsigned char a,b,c;
- for(a=0;a<1;a++)
- for(b=0;b<3;b++)
- for(c=0;c<219;c++);
- }
- void ReadIr() interrupt 0
- {
- unsigned char j,k;
- unsigned int err;
- Time=0;
- DelayMs(70);
- if(IRIN==0) //确认是否真的接收到正确的信号
- {
-
- err=1000; //1000*10us=10ms,超过说明接收到错误的信号
- /*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
- 侯,程序死在这里*/
- while((IRIN==0)&&(err>0)) //等待前面9ms的低电平过去
- {
- DelayMs(1);
- err--;
- }
- if(IRIN==1) //如果正确等到9ms低电平
- {
- err=500;
- while((IRIN==1)&&(err>0)) //等待4.5ms的起始高电平过去
- {
- DelayMs(1);
- err--;
- }
- for(k=0;k<4;k++) //共有4组数据
- {
- for(j=0;j<8;j++) //接收一组数据
- {
- err=60;
- while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
- // while (!IRIN)
- {
- DelayMs(1);
- err--;
- }
- err=500;
- while((IRIN==1)&&(err>0)) //计算高电平的时间长度。
- {
- DelayMs(1);//0.14ms
- Time++;
- err--;
- if(Time>30)
- {
- EX0=1;
- return;
- }
- }
- IrValue[k]>>=1; //k表示第几组数据
- if(Time>=8) //如果高电平出现大于565us,那么是1
- {
- IrValue[k]|=0x80;
- }
- Time=0; //用完时间要重新赋值
- }
- }
- }
- if(IrValue[2]!=~IrValue[3])
- {
- return;
- }
- }
- }
- void DelayMs(unsigned int x) //0.14ms误差 0us
- {
- unsigned char i;
- while(x--)
- {
- for (i = 0; i<13; i++)
- {}
- }
- }
- void LessSpeed()
- {
- while(IrValue[2]==0x15)
- {
- Moto_R=1;
- Moto_L=0;
- Delay_100us();
- Moto_R=Moto_L=0;
- Delay_100us();
- }
- }
- void RC()
- {
- if(IrValue[2]==0x45)
- EN=0;
- else if(IrValue[2]==0x44)
- EN=1;
- else if(IrValue[2]==0x16)
- Moto_R=Moto_L=0;
- if(IrValue[2]==0x15)
- LessSpeed();
- else if(IrValue[2]==0x09)
- Moto_R=1, Moto_L=0;
- }
51单片机的中断优先级别分为两种,一种是响应优先级别,指多个中断同时发生时,谁先执行。这个优先级系统默认了,也就是你所谓的高优先级 低优先级的关系。
另一种是抢占优先级,指一个到来的中断可否打断一个正在执行的中断。中断A在执行函数在执行时,来了另一中断B,B的抢占级别如果大于A,则a的中断会被打断,执行B的。 如果B的抢占优先级小于或等于A的,则无法打断。
51默认中断的抢占优先级相同。
如果想要设置抢占优先级,可以通过中断优先级寄存器IP(#include<reg51.h>)进行设置。相应位设为1即可。
这个总结的非常清晰。好。我就曾经在抢占优先级这里迷糊过。后来发现一旦进入中断,即使同样的触发信号来了,也不能再次执行中断程序的。自动被屏蔽了。