第三节:累计主循环次数使LED灯闪烁。

开场白:
上一节鸿哥提到delay()延时函数消耗的时间太长了,其它任务根本没有机会执行,我们该怎么改善?本节教大家利用累计主循环次数的方法来解决这个问题。这一节要教会大家两个知识点:
第一点:利用累计主循环次数的方法实现时间延时
第二点:switch核心语句之初体验。 鸿哥所有的实战项目都是基于switch语句实现多任务并行处理。
(1)硬件平台:基于朱兆祺51单片机学习板。
(2)实现功能:让一个LED闪烁。
(3)源代码讲解如下:

  1. #include "REG52.H"  
  2.   
  3.   
  4. /* 注释一: 
  5. * const_time_level是统计循环次数的设定上限,数值越大,LED延时的时间越久 
  6. */  
  7. #define const_time_level 10000    
  8.   
  9. void initial_myself();      
  10. void initial_peripheral();  
  11. void delay_long(unsigned int uiDelaylong);  
  12. void led_flicker();  
  13.   
  14. sbit led_dr=P3^5;    
  15.   
  16. /* 注释二: 
  17. * 吴坚鸿个人的命名风格:凡是switch语句里面的步骤变量后缀都是Step. 
  18. * 前缀带uc,ui,ul分别表示此变量是unsigned char,unsigned int,unsigned long. 
  19. */  
  20. unsigned char ucLedStep=0; //步骤变量  
  21. unsigned int  uiTimeCnt=0; //统计循环次数的延时计数器  
  22. void main()   
  23.   {  
  24.    initial_myself();    
  25.    delay_long(100);     
  26.    initial_peripheral();   
  27.    while(1)     
  28.    {  
  29.       led_flicker();     
  30.    }  
  31.   
  32. }  
  33.   
  34. void led_flicker() ////第三区 LED闪烁应用程序  
  35. {  
  36.     
  37.   switch(ucLedStep)  
  38.   {  
  39.      case 0:  
  40. /* 注释三: 
  41. * uiTimeCnt累加循环次数,只有当它的次数大于或等于设定上限const_time_level时, 
  42. * 才会去改变LED灯的状态,否则CPU退出led_flicker()任务,继续快速扫描其他的任务, 
  43. * 这样的程序结构就可以达到多任务并行处理的目的。 
  44. * 本程序基于朱兆祺51单片机学习板 
  45. */  
  46.           uiTimeCnt++;  //累加循环次数,  
  47.                   if(uiTimeCnt>=const_time_level) //时间到  
  48.                   {  
  49.                      uiTimeCnt=0; //时间计数器清零  
  50.              led_dr=1;    //让LED亮  
  51.                          ucLedStep=1; //切换到下一个步骤  
  52.                   }  
  53.               break;  
  54.      case 1:  
  55.           uiTimeCnt++;  //累加循环次数,  
  56.                   if(uiTimeCnt>=const_time_level) //时间到  
  57.                   {  
  58.                      uiTimeCnt=0; //时间计数器清零  
  59.              led_dr=0;    //让LED灭  
  60.                          ucLedStep=0; //返回到上一个步骤  
  61.                   }  
  62.               break;  
  63.     
  64.   }  
  65.   
  66. }  
  67.   
  68.   
  69. void delay_long(unsigned int uiDelayLong)  
  70. {  
  71.    unsigned int i;  
  72.    unsigned int j;  
  73.    for(i=0;i<uiDelayLong;i++)  
  74.    {  
  75.       for(j=0;j<500;j++)  //内嵌循环的空指令数量  
  76.           {  
  77.              ; //一个分号相当于执行一条空语句  
  78.           }  
  79.    }  
  80. }  
  81.   
  82.   
  83. void initial_myself()  //第一区 初始化单片机  
  84. {  
  85.   led_dr=0;  //LED灭  
  86. }  
  87. void initial_peripheral() //第二区 初始化外围  
  88. {  
  89.   ;   //本例为空  
  90. }   

总结陈词:
    在实际项目中,用累计主循环次数实现时间延时是一个不错的选择。这种方法能胜任多任务处理的程序框架,但是它本身也有一个小小的不足。随着主函数里任务量的增加,我们为了保证延时时间的准确性,要不断修正设定上限const_time_level 。我们该怎么解决这个问题呢?欲知详情,请听下回分解-----累计定时中断次数使LED灯闪烁。

永不止步步 发表于11-19 21:25 浏览65535次
分享到:

已有0条评论

暂时还没有回复哟,快来抢沙发吧

添加一条新评论

只有登录用户才能评论,请先登录注册哦!

话题作者

永不止步步
金币:67417个|学分:363791个
立即注册
畅学电子网,带你进入电子开发学习世界
专业电子工程技术学习交流社区,加入畅学一起充电加油吧!

x

畅学电子网订阅号