MSP430低功耗模式-while循环失效

如下代码实现MSP430G2553单片机两个led交替闪烁

#include <msp430.h> 
/**
 * main.c
 */
int main(void)
{
	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
	P1DIR|=BIT0+BIT6;
	P1OUT|=BIT0;
	while(1)
	{
	    unsigned int i;
	    i=50000;
	    while(i--);
              P1OUT^=BIT0+BIT6;
	}
}

发现灯光显示异常两灯常亮。

为什么呢?在老师帮助下了解了是因为Msp430这款板子默认的低功耗模式导致了cpu不干预而使这种while(i--)的空循环失效。

MSP430G2553单片机有6种功耗模式如下:

1、活动模式-----AM

正常的工作模式,这时CPU消耗的电能最大.

2、低功耗模式0-----LPM0

CPUOff置位,CPU停止活动,但外围模块继续工作,ACLK和MCLK信号保持活动,MCLK的锁频坏控制正常工作.有关控制位设置为:SCG0=0,SCG1=0,OscOff=0,CPUOff=1。

3、低功耗模式1-----LPM1

CPUOff置位,CPU停止活动,但外围模块继续工作,MCLK的锁频环控制停止工作,ACLK与MCLK保持活动,有关控制位设置为:SCG0=0,SCG1=1,OscOff=0,CPUOff=1。

4、低功耗模式2-----LPM2

CPUOff置位,CPU停止活动,但外围模块继续工作,MCLK的锁频环控制停止,ACLK活动,MCLK停止,有关控制位设置为:SCG0=0,SCG1=1,OscOff=0,CPUOff=1。

5、低功耗模式3-----LPM3

CPUOff置位,CPU停止活动,但外围模块继续工作,MCLK的锁频环控制和MCLK停止工作,DCO的DC发生器关闭,但ACLK信号仍保持活动,有关控制位设置为:SCG0=1,SCG1=1,OscOff=0,CPUOff=1。

6、低功耗模式4-----LPM4

CPUOff置位,CPU停止活动,但外围模块继续工作,MCLK的锁频环控制和MCLK停止工作,晶振停止,有关控制位设置为:SCG0=x,SCG1=x,OscOff=1,CPUOff=1。

处理器进入低功耗模式以后,一般由中断来唤醒。可以是外部中断,也可以是内部的定时器等中断。

而具体到上述问题从TI网站上查到相应的资料:翻译后如下

MSP430提供各种类型的定时器和时钟,可配置为无需CPU干预即可运行。当需要延迟时,可以利用其中一个定时器外设来产生这种延迟,而CPU不会保持活动状态。该方法显着降低了设备的功耗。这些定时器可使MSP430微控制器保持低功耗模式,直到定时器唤醒CPU。

风险,严重程度
在微控制器中,CPU是整体功耗的最大贡献者。当应用程序执行延迟时,如果CPU保持活动模式,则会浪费大量的功率和能量。

为什么会这样
当在项目中的任何代码文件中发现延迟时,将发出此注释。
检查代码中是否包含仅包含以下任一行的循环,而不包含任何其他代码:

 __no_operation();
 _NOP();
任何空循环。例如:

 volatile int i = MAX_VALUE;
 而(i--> 0);
 出现这种情况://上述问题所在

 __delay_cycles(NUMBER_OF_CYCLES);
补救
利用其中一种MSP430低功耗模式,并使用MSP430器件中的一个定时器模块在一段时间后唤醒。

代码示例
 // ********* ******************************
 // MSP430G2xx3演示 -  Timer_A,切换P1.0,CCR0续。模式ISR,DCO SMCLK
 //
 //描述:使用软件和TA_0 ISR切换P1.0。切换每一个
 // 50000个SMCLK周期。 SMCLK为TACLK提供时钟源。
 //在TA_0 ISR期间,切换P1.0并添加50000个时钟周期
 // CCR0每50000个周期触发TA_0 ISR。 CPU通常是关闭的
 //仅在TA_ISR期间使用。
 // ACLK = n / a,MCLK = SMCLK = TACLK =默认DCO
 //
 // MSP430G2xx3
 // ---------------
 // / | \ | XIN |  - 
 // | | |
 //  -  | RST XOUT |  - 
 // | |
 // | P1.0 |  - > LED
 //
 // D. Dang
 #include <msp430g2553.h>
 void main(void)
 {
   WDTCTL = WDTPW + WDTHOLD; //停止WDT
   P1DIR | = 0x01; // P1.0输出
   CCTL0 = CCIE; //启用CCR0中断
   CCR0 = 50000;
   TACTL = TASSEL_2 + MC_2; // SMCLK,contmode
 
   _BIS_SR(LPM0_bits + GIE); //输入LPM0 w / interrupt
 }
 
 //定时器A0中断服务程序
 #pragma vector = TIMER0_A0_VECTOR
 __interrupt void Timer_A(void)
 {
   P1OUT ^ = 0x01; //切换P1.0
   CCR0 + = 50000; //将偏移添加到CCR0
 }

具体代码现在搞不太懂,但是大体上两种解决方法,第一用delay函数实现用时钟定时,第二个就是用中断进入其他的例如AM退出低功耗模式,然后就可以调用cpu来实现循环。

应该是这样,现在第一次学真的搞不来这些代码,只能这样了。
 

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值