程序延时里的思维

程序延时里的思维

  大概所有的51单片机初学者在用到延时的时候都有一个共同点,那就是使用一段空循环消耗CPU的时间从而达到延时目的,常见的函数就是图1-1中的delay函数。这种模式在初学阶段的确是简单易懂,学习起来会得心应手,这可以称得上是我们单片机生涯的童年时代,它使我们学会了走起来。但对于学习了三四年单片机的人来说,不能再单单走了,要跑起来!

1 void delay(unsigned int ms)    
2 { 
3     unsigned int i,j; 
4     for( i = 0; i < ms; i++ )
5     { 
6         for( j = 0; j < 1141; j++ );
7     }
8 }

 

                          图1-1

   为何说delay函数只是走起来?这得要看清楚作为初学者我们的思维是一种什么样的概念,其实我也说不清。。。只能打个比喻,假如有个空间里面有按键、显示屏、串口接收、led。在我的认知里有三种思维维度:

  一维度:一个平面里的一条直线。程序从开始就一步一个模块地走,我们都知道,按键存在这机械抖动,为了消除这个抖动,就需要在判断按键后延时10ms左右的时间再次判断,如图1-2,那么这10ms的时间被固定在了这条时间轴里面。10ms的时间对单片机来说是很长很长的,会导致显示屏刷新变慢,LED驱动迟钝,串口数据丢失。

                                        

 1 keyscan(void)
 2 {    
 3     unsigned char keynum;
 4     if(Key==0)   //检测是否有键按下
 5     {
 6         delay(10);    //延时10ms去抖动
 7         if(Key==0)    //再次检测是否依然有键按下
 8         {
 9             
10              keynum = 1;
11              while(Key==0);          //等待按键释放
12          }
13     }
14 }   

                           图1-2

二维度:一个平面里的曲线。串口接收采用了中断方式,按键扫描采用了定时器中断扫描方式,因为串口数据不是一直有,且按键不是一直被按,所以时间轴比一维度的要缩短了,但是当定时器中断时,进入中断扫描按键,delay函数依然占用了10ms的时间。

                                  

三维度:空间里不同维度交织的直线。立体图太难画了,就当串口和按键是来自不同的平面吧~这里引用了缓存的概念,通过变量buf缓存数据,串口通过中断把数据存到串口buf中,按键通过定时器中断扫描,把值存到按键buf中,这时候按键扫描用的是图1-3中的函数,配置定时器为2.5ms中断,如此一来,取消了delay函数,主函数轴中只需要几条指令的时间就把按键扫描的功能完成。在需要扫描按键的时候,读取按键buf的值,判断它是否大于10即可,而按键其实在另一个时间轴里完成了10*2,5个ms的滤波。串口和按键各自在不同的时间轴中运行,通过buf变量和主时间轴交织在一起,仿佛形成了一个三维的空间,用专业的术语描述这就叫做——分时系统。

                            

 1 void timer() interrupt 1 //定时器中断函数 2.5ms
 2 {
 3     if(key == 0)                     //如果按键按下
 4     {
 5         if(buf < 20)                //滤波20*2.5ms
 6         {
 7             buf++;    
 8         }
 9     }
10     else
11     {
12         if(buf > 0)
13         {
14             buf--;
15         }    
16     }        
17 }        

                       图1-3

  现在回过头来看看delay函数,是不是处在一维度里?这种思维会约束我们写代码的习惯,使我们的代码得不到高效率、高稳定性,我们必须要往上冲破更高维度的思维。CPU的时间是非常宝贵的,哪怕是1ms的时间。为了得到更快的速度,IC厂商不断地提高CPU时钟频率,主流的STM32F4系列达到了168M的主频;CPU架构也由冯诺依曼结构发展成了哈佛结构;过去取指令一个时钟,而后再执行指令又一个时钟,已经演变成多级流水线架构,,如图1-4。IC厂商如此努力把CPU速度提高,我们怎么能让CPU原地转几万圈来延时,这太对不起人家了~

posted @ 2018-01-05 21:36  WCW的故事  阅读(502)  评论(0编辑  收藏  举报