嵌入式提高CPU利用率的编程方法(以按键消抖为实例)



《《《《《正文》》》》》


 

最初,我在按键消抖软件策略上的实现方法是获取按键电平后,延时一段时间后,再去判断按键电平,如果2次电平相同就确定为消抖成功,最后的电平就可作为判断按键操作的依据。大致伪代码如下:

  void main(void)
  {
    Key_Init(); //底层初始化
    
    while(1)
    {
      KeyIO_1 = GetKeyIO();
      delay_ms(100);         //延时50ms函数
      KeyIO_2 = GetKeyIO();
      
      if(KeyIO_2 == KeyIO_1)
      {
        KeyIO = KeyIO_1;
      }
    }
  }

如果项目只有一个按键的事务处理,那CPU都是按键事务的,那如上编程倒没有任何问题;如果项目还有其他事务需要处理,比如控制Led灯,这个时候CPU的使用权就有了2个事务!按上面的程序的话,led灯事务要等按键事务执行完了再执行led灯事务,同样,按键事务也要等led灯事务执行完了再执行;伪代码如下图:

  void main(void)
  {
    Key_Init(); //底层初始化
    
    while(1)
    {
      //按键事务
      KeyIO_1 = GetKeyIO();
      delay_ms(100);         //延时50ms函数
      KeyIO_2 = GetKeyIO();
      
      if(KeyIO_2 == KeyIO_1)
      {
        KeyIO = KeyIO_1;
      }
      
      //led事务
      LED_1();
      delay_ms(100);
      LED_0();
    }
  }

按上面的代码我们大概的算一下CPU花在处理事务上的使用率,假设上面while内的代码运行一次需要201ms(实际更小,基本接近于200ms),其中延时函数总共花了200ms,那CPU花在事务上的百分比%= 201-200/201 = 0.5%,那其余的时间CPU在干嘛呢?延时函数告诉你CPU就在那里死等!这段延时(死等)的时间,CPU没有做任何事情,那就是浪费CPU。

所以在实际编程中,我们一定要尽可能避免这种死等的操作,之所以用尽可能是因为不是说死等就是没用,在某些必要的情况下,仍然需要死等这个操作,比如一些需要同步操作的,或者延时时间很短不影响主程序等等。所以平时大都不要轻易使用延时(死等)这种操作,耗时是小事,死在里面就麻烦了!

 

《那怎么解决这种问题呢?》

这是今天的重点!下面这个例子应该可以让你秒懂!

 

大家平时都去过银行吧!拿完排队的票,发现还有很多人,你会怎么办?有人坐在大厅等有人就会先去干其他的事情,然后过段时间再来看看,要是还没排到就再去干其他事情先,直到排到;

这里坐在大厅等的人,就是上面的延时(死等)函数操作;而另一种人就是我们现在要说的,定期去看看,排到了就办理业务,没排到就继续去干其他事情;

那有人说,如果回去银行发现已经过了自己的号怎么办?这里大家注意一点思维,因为得益于单片机处理速度的快速,一个while(不含延时)里的程序我们都认为是同时运行的,虽然从微观看,肯定是有先后,但是从宏观看,就是同时运行的,所以我们单片机可以做到极快的回去看看轮到我们没有,不会把事务丢掉当然如果你事务也极快,那你回去看的频率当然要比它快,防止事务丢掉)。所以我们可以在时基中断里产生一个时间中断的标志位,比如2ms,对于按键事务,2ms足以满足检测频率,不会丢掉按键的电平变化操作(除非你在2ms以内来一次按键操作,你手可以吗?)。这样我们每2ms去处理一次按键事务,其他时间处理其他事务;这样子就提高了CPU的利用率!

伪代码如下:

uint8_t _2ms_Flag = 0; //2ms标志位

//2ms中断函数
void ISR_2ms(void)
{
    _2ms_Flag = 1;
}

void main(void)
{
    Key_Init(); //底层初始化
    Other_Init();
    
    while(1)
    {
      if(_2ms_Flag ==1) //定期回来看看
      {
        _2ms_Flag = 0
        
        Key_Deal();//这里用计数器实现消抖策略
      }
      
      Other_Deal(); //其他事务
    }
  }

这种方式其实叫前后台轮询系统,事务触发标志在中断里触发(后台),事务处理在主循环里处理(前台)!这里的中断可以扩展为外部输入事务,这样实时性、事务处理速度、CPU利用率都会大大提高!何乐不为?!


《《《《《END》》》》》



 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值