前后台系统的低功耗编程思想——STM8平台

1.前言

    工作之后接触了“低功耗”,开始搜索各种各样的低功耗MCU。网络是一个非常自由的地方,你总可以看到各种关于哪个MCU功耗更低的论战,在这些论战中我查阅了几乎所有低功耗MCU的特性,例如MSP430、EFM32还有STM32L等,网络论战的核心便是哪款MCU的休眠电流更低。看多了资料我便发现,这些低功耗的MCU如何使用,低功耗MCU的程序编写和普通MCU编程有什么区别。
    带着这些疑问我继续品味关于低功耗MCU的”论战“,直到我购买了《MSP430系列单片机系统工程设计与实践》。在该书中提到了低功耗MCU编程的基本思想,大致可以总结为:
    1.善用节拍
    2.消除阻塞
    下面就结合STM8谈谈如何实践以上两点。(虽然STM8并不是严格意义上的低功耗MCU,但是只要有低功耗指令的MCU都可以使用以上两点,发挥它的低功耗特性)

2.善用节拍

    定时休眠是低功耗MCU常用的手段,定时休眠便是让MCU先休眠再工作,在休眠和工作之间不停转换。STM8有多种低功耗方式,例如 等待模式便是其中的一种,等待模式时仅MCU停止工作,其他外设可正常工作。使用等待模式可以保证定时器或UART等可以正常的进入中断。当然也可以使用停止模式进一步降低功耗,在这里则使用等待模式做一个“方法性质”的说明。

    图1 前后台系统中的低功耗节拍
    可以这样理解,定时进入低功耗模式也可以理解为一个任务,这个“任务”会阻塞CPU使得其他任务无法得到运行,但这并不是真正意义的阻塞CPU,而是使得CPU停止只能通过定时器中断才可以退出该”任务“。实现部分的代码如下:
  1. void main(void)  
  2. {  
  3.   /* Clock configuration -----------------------------------------*/  
  4.   CLK_Config();    
  5.   /* GPIO configuration -----------------------------------------*/  
  6.   GPIO_Config();    
  7.   /* TIM4 configuration -----------------------------------------*/  
  8.   TIM4_Config();      
  9.   while (1)  
  10.   {  
  11.     // 进入等待模式,CPU停止工作,所有中断打开  
  12.     Enter_WaitMode();  
  13.     // LED闪烁任务  
  14.     LED_Process();  
  15.   }  
  16. }  
  17.   
  18. void Enter_WaitMode(void)  
  19. {  
  20.   WaitFlag = 0;  
  21.   // 1ms之后CPU被TIM4中断唤醒,WaitFlag在中断中被置位  
  22.   while( WaitFlag == 0)  
  23.   {  
  24.     __wait_for_interrupt();   
  25.   }  
  26. }  
  27.   
  28. INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)  
  29. {  
  30.   WaitFlag = 1;  
  31.   /* Cleat Interrupt Pending bit */  
  32.   TIM4_ClearITPendingBit(TIM4_IT_UPDATE);  
  33. }  

    以上代码中出现了WaitFlag标志位,该标志位出现在Enter_WaitMode函数和TIM4_UPD_OVF_IRQHandler中断中,该标志位的作用是保证唤醒CPU继续工作的一定是定时器4溢出中断,其他中断例如UART接收中断则不能使CPU重新运行。STM8的等待模式和定时器4溢出中断组成了低功耗节拍”任务“。

3.消除阻塞

    从上文的分析可以看出,在整个的运行周期中总是希望低功耗任务所占的比重大(从时间角度切入),其他任务所占的比重小。那么其他任务应该尽量减少对CPU的占用,例如实现LED间隔闪烁便可使用以下代码:

  1. void LED_Process(void)  
  2. {  
  3.   static uint16_t LEDCounter = 0;  
  4.     
  5.   if( LEDCounter++ > 500 )  
  6.   {  
  7.     LEDCounter = 0;  
  8.     /* Toggles LEDs */  
  9.     GPIO_WriteReverse(LED_GPIO_PORT, (GPIO_Pin_TypeDef)LED_GPIO_PINS);  
  10.   }  
  11. }  

    由于LED_Process在低功耗任务之后运行,而低功耗任务所占用CPU的时间为固定时间—— 定时器4溢出周期,也就意味着 LED任务的调用周期为1ms,利用该特性可以结合一个 计数变量LEDCounter实现LED闪烁功能,当然更复杂的时序可以通过 有限状态机实现。

4.总结

    节拍运行和消除阻塞算是低功耗MCU编程的基本思想,理解了低功耗MCU编程的基本思路那么不是低功耗的MCU也可以用来开发出低功耗应用。前段时间上TB查看MCU的价格,STM8的价格真的把我吓了一跳,自己也购置了STM8开发板,结合低功耗方法于是总结了该文章。
    若结合操作系统实现低功耗,请参考以下 博文
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值