zoukankan      html  css  js  c++  java
  • 程序延时里的思维

    程序延时里的思维

      大概所有的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原地转几万圈来延时,这太对不起人家了~

  • 相关阅读:
    多叉树
    PowerDesigner设置集锦(2)
    Delphi应用程序在命令行下带参数执行返回命令行提示的问题
    不允许在 '*******' 上使用扩展属性,或对象不存在
    仓库管理系统开发完成
    动态创建Frame窗体(根据类名,除T以外的字母)
    Access中的常用TSQL
    批量删除同类文件(带通配符)
    判断Access数据库中的表或查询是否存在的SQL
    序列化FastReport,重要提示少走弯路
  • 原文地址:https://www.cnblogs.com/wcw12580/p/8158422.html
Copyright © 2011-2022 走看看