微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 为什么我的高优先中断打断不了低优先呢~~~~(>_<)~~~~

为什么我的高优先中断打断不了低优先呢~~~~(>_<)~~~~

时间:10-02 整理:3721RD 点击:
当 进入自动行驶状态后 (EN=1)无法通过红外遥控进入 受控状态(EN=0)

  1. //*1.红外遥控:状态转换、转弯、变速;2.测距<30cm时车右转,<20cm向右急转*//
  2. #include<reg52.h>


  3. sbit Trig=P1^7;
  4. sbit IRIN=P3^2;// 外部中断0 红外遥控
  5. sbit Echo=P3^3;//外部中断1  超声波测距
  6. sbit Moto_R=P2^1;
  7. sbit Moto_L=P2^0;
  8. sbit LED_Y=P2^2;//遥控状态指示灯
  9. sbit LED_G=P2^3;//自动转弯指示灯



  10. void Int_0();
  11. void Timer();
  12. void measure();
  13. void Moto_1();
  14. void Moto_2();
  15. void Delay_100us();
  16. void Delay_2ms();
  17. void Delay_1ms();
  18. void DelayMs(unsigned int x);
  19. void RC();
  20. void LessSpeed();

  21. unsigned char code display_1[] = "  Measuring...  ";
  22. unsigned char code display_2[] ="Distance:   . cm";
  23. unsigned char code display_3[] =">4m    ";
  24. unsigned char code display_4[] =">4mTEST";

  25. unsigned char A1=48,B1=48,C1=48,D1=48;
  26. unsigned int a,b,c,d;

  27. unsigned int l;
  28. unsigned char IrValue[3];
  29. unsigned char Time,EN=0;

  30. void main()
  31. {
  32.         EA=1;// 打开总中断
  33.         Int_0();
  34.         Timer();
  35.         Moto_R=0;
  36.         Moto_L=0;
  37.         LED_Y=LED_G=0;
  38.         while(1)
  39.         {
  40.                 if(EN==1)  //进入自动行驶状态
  41.                 {   
  42.                         LED_Y=0;
  43.                         Moto_R=1,Moto_L=0;
  44.                     measure();
  45.                         if(IrValue[2]==0x45)
  46.                                         EN=0;
  47.                 }
  48.                 else                //受控状态
  49.                 {
  50.                         TR0=0;         //关闭定时器0
  51.                         EX1=0;
  52.                         Moto_R=Moto_L=0;
  53.                         while(EN==0)
  54.                         
  55.             {
  56.                                 LED_G=0;
  57.                                 LED_Y=1;
  58.                                 RC();
  59.                         }
  60.                         
  61.             }
  62.                         
  63.                
  64.         }
  65. }

  66. //外部中断设置
  67. void Int_0()
  68. {
  69.         IT0=1;//外部中断0跳变沿触发方式(下降沿)
  70.         EX0=1;//打开INT0的中断允许
  71.         IT1=1;//外部中断1跳变沿触发方式(下降沿)
  72.         EX1=0;//关闭INT1的中断允许
  73. }
  74. //定时器设置
  75. void Timer()
  76. {
  77.         TMOD=0X01;//定时器0选择工作方式
  78.         TR0=0;         //关闭定时器0
  79. }
  80. //测量长度程序
  81. void measure()
  82. {

  83.         EX1=1;//打开INT1的中断允许
  84.         TH0=0X00;//设置初始值
  85.         TL0=0X00;
  86.         Trig=1;
  87.         Delay_1ms();
  88.         Trig=0;
  89.         while(Echo==1)
  90.                 ;
  91.         TR0=1;         //打开定时器0
  92. }
  93. //外部中断0(判断是否转弯)
  94. void Judge() interrupt 2
  95. {

  96.         l=(TH0*256+TL0)*1.0/58; //测量长度 单位cm
  97.         TR0=0;//关闭定时器
  98.         if(l<30)
  99.                 Moto_1(),LED_G=1;
  100.         else if(l<20)
  101.                 Moto_2(),LED_G=1;
  102.         else LED_G=0;
  103. }
  104. //pwm调制右轮减速向右转
  105. void Moto_1()
  106. {
  107.         Moto_R=Moto_L=0;
  108.         Delay_100us();
  109.         Moto_R=1,Moto_L=0;
  110.         Delay_100us();
  111.         Delay_100us();

  112. }
  113. //急转
  114. void Moto_2()
  115. {
  116.         Moto_R=Moto_L=0;
  117.         Delay_2ms();
  118. }



  119. void Delay_100us()
  120. {
  121. unsigned char a,b,c;
  122. for(a=0;a<1;a++)
  123. for(b=0;b<1;b++)
  124. for(c=0;c<28;c++);
  125. }  
  126. void Delay_2ms()
  127. {
  128. unsigned char a,b,c;
  129. for(a=0;a<2;a++)
  130. for(b=0;b<3;b++)
  131. for(c=0;c<220;c++);
  132. }  
  133. void Delay_1ms()
  134. {
  135. unsigned char a,b,c;
  136. for(a=0;a<1;a++)
  137. for(b=0;b<3;b++)
  138. for(c=0;c<219;c++);
  139. }  
  140. void ReadIr() interrupt 0
  141. {
  142.         unsigned char j,k;
  143.         unsigned int err;
  144.         Time=0;                                         
  145.         DelayMs(70);

  146.         if(IRIN==0)                //确认是否真的接收到正确的信号
  147.         {         
  148.                
  149.                 err=1000;                                //1000*10us=10ms,超过说明接收到错误的信号
  150.                 /*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
  151.                 侯,程序死在这里*/        
  152.                 while((IRIN==0)&&(err>0))        //等待前面9ms的低电平过去                  
  153.                 {                        
  154.                         DelayMs(1);
  155.                         err--;
  156.                 }
  157.                 if(IRIN==1)                        //如果正确等到9ms低电平
  158.                 {
  159.                         err=500;
  160.                         while((IRIN==1)&&(err>0))                 //等待4.5ms的起始高电平过去
  161.                         {
  162.                                 DelayMs(1);
  163.                                 err--;
  164.                         }
  165.                         for(k=0;k<4;k++)                //共有4组数据
  166.                         {                                
  167.                                 for(j=0;j<8;j++)        //接收一组数据
  168.                                 {

  169.                                         err=60;               
  170.                                         while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
  171. //                                        while (!IRIN)
  172.                                         {
  173.                                                 DelayMs(1);
  174.                                                 err--;
  175.                                         }
  176.                                         err=500;
  177.                                         while((IRIN==1)&&(err>0))         //计算高电平的时间长度。
  178.                                         {
  179.                                                 DelayMs(1);//0.14ms
  180.                                                 Time++;
  181.                                                 err--;
  182.                                                 if(Time>30)
  183.                                                 {
  184.                                                         EX0=1;
  185.                                                         return;
  186.                                                 }
  187.                                         }
  188.                                         IrValue[k]>>=1;         //k表示第几组数据
  189.                                         if(Time>=8)                        //如果高电平出现大于565us,那么是1
  190.                                         {
  191.                                                 IrValue[k]|=0x80;
  192.                                         }
  193.                                         Time=0;                //用完时间要重新赋值                                                        
  194.                                 }
  195.                         }
  196.                 }
  197.                 if(IrValue[2]!=~IrValue[3])
  198.                 {
  199.                         return;
  200.                 }
  201.         }                        
  202. }

  203. void DelayMs(unsigned int x)   //0.14ms误差 0us
  204. {
  205. unsigned char i;
  206.   while(x--)
  207. {
  208.   for (i = 0; i<13; i++)
  209. {}
  210. }
  211. }
  212. void LessSpeed()
  213. {
  214.         while(IrValue[2]==0x15)
  215.         {
  216.         Moto_R=1;
  217.         Moto_L=0;
  218.         Delay_100us();
  219.         Moto_R=Moto_L=0;
  220.         Delay_100us();
  221.         }
  222. }
  223. void RC()
  224. {        
  225.         if(IrValue[2]==0x45)
  226.                 EN=0;
  227.         else if(IrValue[2]==0x44)
  228.                 EN=1;
  229.         else if(IrValue[2]==0x16)
  230.                 Moto_R=Moto_L=0;
  231.         if(IrValue[2]==0x15)
  232.                 LessSpeed();
  233.         else if(IrValue[2]==0x09)
  234.                 Moto_R=1, Moto_L=0;
  235. }

复制代码



       51单片机的中断优先级别分为两种,一种是响应优先级别,指多个中断同时发生时,谁先执行。这个优先级系统默认了,也就是你所谓的高优先级 低优先级的关系。
      另一种是抢占优先级,指一个到来的中断可否打断一个正在执行的中断。中断A在执行函数在执行时,来了另一中断B,B的抢占级别如果大于A,则a的中断会被打断,执行B的。 如果B的抢占优先级小于或等于A的,则无法打断。
      51默认中断的抢占优先级相同。
      如果想要设置抢占优先级,可以通过中断优先级寄存器IP(#include<reg51.h>)进行设置。相应位设为1即可。

这个总结的非常清晰。好。我就曾经在抢占优先级这里迷糊过。后来发现一旦进入中断,即使同样的触发信号来了,也不能再次执行中断程序的。自动被屏蔽了。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top