打印
[MCU]

使用msp430低功耗延时函数遇到的问题和解决办法

[复制链接]
421|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
两只袜子|  楼主 | 2020-12-2 10:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在用MSP430做东西
对发热有一些要求
为了尽可能减少发热
单片机一直运行在低功耗模式
包括代码中的延时函数
自己写了一个低功耗延时函数
给定时器设置一个时间
然后让单片机进入睡眠状态
通过定时器中断唤醒并将一个标志清零
因为其它中断也有唤醒代码
醒后判断标志是否被定时器清零0
如果清零代码继续执行
如果没清零继续进入睡眠状态

代码是下边这样
  • void delay_ms_lpm3(uint16_t ms)
  • {
  •     if(ms > 5957)while(1);
  •     TA1CCTL0 = CCIE;                                                            // CCR0 interrupt enabled
  •     TA1CCR0 = 11*ms;
  •     TA1CTL = TASSEL_1 + MC_1;                                                   // ACLK = 11KHz, Up to CCR0
  •     delay_flag = 1;                                                             //设置延时标志
  •     while(delay_flag)                                                          //等待延时标志被中断清除
  •     {   
  •       __bis_SR_register(LPM3_bits + GIE);                                         // CPU off, interrupts enabled
  •     }
  • }
  • #pragma vector=TIMER1_A0_VECTOR
  • __interrupt void Timer1_A0 (void)
  • {
  •     delay_flag = 0;
  •     TA1CTL &= ~(MC_1);
  •     TA1CCTL0 &= ~(CCIE);
  •     __bic_SR_register_on_exit(LPM3_bits);        // Exit LPMx
  • }


复制代码



以前运行没发现问题,后来在串口中断里作了一些数据处理
现在的代码运行一会儿就会卡在while(delay_flag)
delay_flag会一直为1


经过分析发现这个延时函数存在一些隐患
比如
delay_flag = 1; 是在定时器配置好以后设置的
如果代码正好在定时器配置好,还没有将delay_flag置1
此时定时器已经工作,如果有其它中断产生,比如UART,然后在中断函数里占用了一定时间
这个时间超过定时器的定时时间
中断退出后此定时器到达指定时间会产生中断,将delay_flag置0,其实delay_flag本来就是0
接下来继续执行代码,将delay_flag置1,然后等待delay_flag被定时器中断清零
因为定时器中断函数已经执行过,所以delay_flag会一直为1,代码才会卡在这里
解决办法是将delay_flag=1放在配置定时器之前
修改后的代码运行了一段时间,还没有发现之前的问题
  • void delay_ms_lpm3(uint16_t ms)
  • {
  •     if(ms > 5957)while(1);
  •         delay_flag = 1;                                                             //设置延时标志
  •     TA1CCTL0 = CCIE;                                                            // CCR0 interrupt enabled
  •     TA1CCR0 = 11*ms;
  •     TA1CTL = TASSEL_1 + MC_1;                                                   // ACLK = 11KHz, Up to CCR0
  •     while(delay_flag)                                                          //等待延时标志被中断清除
  •     {   
  •       __bis_SR_register(LPM3_bits + GIE);                                         // CPU off, interrupts enabled
  •     }
  • }

复制代码



使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2034

主题

7330

帖子

10

粉丝