[原创] [TI首届低功耗设计大赛]+低功耗延时

IC爬虫   2014-11-24 17:55 楼主
延时是很多时候无法回避的,在对功耗要求严苛的应用情景下非用延时不可时,降低延时所MCU自身所使用的功耗也是很有必要的。得力于430在进入低功耗模式时重新唤醒的时间小于1us,所以可以使用硬件延时的方法节省MCU使用软件延时所浪费的运行功耗。
  1. void TA1_sleep(unsigned int time)
  2. {
  3. TIMER_A_startUpMode(__MSP430_BASEADDRESS_T1A3__, TIMER_A_CLOCKSOURCE_ACLK, TIMER_A_CLOCKSOURCE_DIVIDER_8,
  4. time, TIMER_A_TAIE_INTERRUPT_DISABLE, TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE,
  5. TIMER_A_SKIP_CLEAR);
  6. __bis_SR_register(LPM3_bits + GIE);
  7. __no_operation();
  8. }
上面这段程序使用的是430的外设库函数写的,使用TIMER_A的增计数模式,选择时钟源为ACLK,将ACLK 8分频作为TIMER_A的是时钟,所以TIMER_A每计数一次的时间为1/(ACLK/8)。函数的输入参数time作为重载的定时器的计数值(也就是CCR0的值),开启CCR0的计数溢出中断。配置好这些后进入低功耗模式LPM3中,让MCU休眠。430MCU的进入低功耗模式后外设也是可以继续工作的,在进入LMP3模式下关闭的是SMCLK和ACLK的时钟,ACLK是继续工作的,所以定时器仍旧可以在这个模式下计数。
  1. #if defined (__TI_COMPILER_VERSION__) || defined (__IAR_SYSTEMS_ICC__)
  2. #pragma vector=TIMER1_A0_VECTOR
  3. __interrupt void TA1_ISR(void)
  4. #elif defined(__GNUC__)
  5. void TA1_ISR(void) __attribute__((interrupt(TIMER1_A0_VECTOR)));
  6. void TA1_ISR(void)
  7. #else
  8. #error Compiler not supported!
  9. #endif
  10. {
  11. TIMER_A_disableCaptureCompareInterrupt(__MSP430_BASEADDRESS_T1A3__, TIMER_A_CAPTURECOMPARE_REGISTER_0);
  12. TIMER_A_stop(__MSP430_BASEADDRESS_T1A3__);
  13. __bic_SR_register_on_exit(LPM3_bits);
  14. }
调用TA1_sleep函数后,当定时器寄满的次数达到了time后触发中断,执行上面这段程序。这段程序的功能为,首先关闭TMER_A的中断、清理定时器的寄存器,停止TIMER_A计数,然后退出低功耗模式LPM3,延时结束,重新回到原来的程序中执行。 上面这种延时方式是的在延时的时候MCU是休眠的,大大降低了MCU的功耗。但是这种延时的方式也有局限,这将降低MCU的实时性,比如有外设使用了SMCKL或者MCLK的话,使用这个也是将会关闭那个外设的功能。 wifi0s0-920151903IMG_20141121_175536.jpg wifi0s0-1533937375IMG_20141121_175514.jpg 本帖最后由 IC爬虫 于 2014-11-25 17:11 编辑

回复评论 (3)

非阻塞式的延时还是比较值得推荐的
点赞  2014-11-24 18:59
引用: wgsxsm 发表于 2014-11-24 18:59
非阻塞式的延时还是比较值得推荐的

实际测试了一下,这个延时函数也很准
点赞  2014-11-24 19:57
得力于430在进入低功耗模式时重新唤醒的时间小于1us,所以可以使用硬件延时的方法节省MCU使用软件延时所浪费的运行功耗。
这个对低功耗真的很重要
点赞  2014-11-27 11:24
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复