[51单片机] 实时性的探讨-------基于51单片机的外部中断

[复制链接]
978|3
 楼主| 无超~吞立吉 发表于 2017-3-24 15:09 | 显示全部楼层 |阅读模式
在进入实验2时,要求如下:
(1)开机后控制四个发光管循环点亮,规律如下图所示:
O X X X
X O X X
X X O X
X X X O   
循环运行,间隔一秒变化一次,显示出闪烁效果。
当有中断信号(INT0)出现时(用手按一下负脉冲发生器的按键),停止闪烁,四个发光管的状态分别受四个开关的控制,对应的开关推上去时发光管亮,对应的开关推下来时发光管灭。
(2)使得上述两种工作状态在每按一次按中断键后发生一次变化。
程序设想:封装函数1实现四个发光二极管循环点亮,封装函数2实现四个开关控制四个发光二极管。在中断中设置标志位flag,在主函数中判断flag的状态,若为1,则进入函数1,若为0则进入函数2。
实际效果:实时性差,每次触发中断的时候不能立即的在函数1与函数2之间切换。
原因:进入中断前,主函数while(1)大循环中正在执行函数1或函数2,在中断服务函数中只是进行flag标志位的翻转,然后又接着返回主函数继续执行函数1或函数2,使得从外界看来不能立即进行功能的翻转,表现为宏观上的实时性差
如何修改程序,可以在中断的每次触发立即进行功能上的翻转?

 楼主| 无超~吞立吉 发表于 2017-3-24 15:09 | 显示全部楼层
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. uchar temp,count;
  6. bit flag=1;
  7. sbit LED0=P1^0;
  8. sbit LED1=P1^1;
  9. sbit LED2=P1^2;
  10. sbit LED3=P1^3;

  11. sbit KEY0=P1^4;
  12. sbit KEY1=P1^5;
  13. sbit KEY2=P1^6;
  14. sbit KEY3=P1^7;
  15. void Delay(unsigned int z)
  16. {
  17.         unsigned int x,y;
  18.         for(x=z;x>0;x--)
  19.                 for(y=110;y>0;y--);
  20. }

  21. void main()
  22. {
  23.   EA=1;
  24.   EX0=1;
  25.   IT0=1;
  26.   P1=0xff;
  27.   temp=0xfe;
  28.   while(1)
  29.   {
  30.     if(flag)
  31.     {
  32.       for(count = 0;count < 4;count ++ )
  33.       {
  34.         P1=temp;
  35.         Delay(300);
  36.         P1=0xff;
  37.         Delay(300);
  38.         temp=_crol_(temp,1);
  39.         if(count==3)
  40.         {
  41.           temp = 0xfe;
  42.         }
  43.       }
  44.     }
  45.     else
  46.     {
  47.          if(KEY0 == 0)
  48.         {
  49.           Delay(5);
  50.           if(KEY0 == 0)
  51.           LED0=0;
  52.           while(!KEY0);
  53.           LED0=1;
  54.         }
  55.         if(KEY1 == 0)
  56.         {
  57.           Delay(5);
  58.           if(KEY1 == 0)
  59.           LED1=0;
  60.           while(!KEY1);
  61.           LED1=1;
  62.         }
  63.         if(KEY2 == 0)
  64.         {
  65.           Delay(5);
  66.           if(KEY2 == 0)
  67.           LED2=0;
  68.           while(!KEY2);
  69.           LED2=1;
  70.         }
  71.         if(KEY3 == 0)
  72.         {
  73.           Delay(5);
  74.           if(KEY3 == 0)
  75.           LED3=0;
  76.           while(!KEY3);
  77.           LED3=1;
  78.         }
  79.      }
  80.   }
  81. }

  82. void int0() interrupt 0
  83. {
  84.   EX0=0;
  85.   flag=~flag;
  86.   EX0=1;
  87. }
NE5532 发表于 2017-3-24 15:56 | 显示全部楼层
停止闪烁和每个灯受1个开关独立控制,这两句话矛盾么?
lnulibin 发表于 2017-3-25 17:37 | 显示全部楼层
提高实时性,要避免在程序中的某一处死等.像你的程序中的DELAY(300)这样的语句,尽量不要用.
因为在执行这个函数的过程中,MCU不再进行其它任务的处理了.
实时性自然很差.
试试设置一个TICKS变量吧.
通过查询它的大小来实现延时,避免死等.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

14

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部