我使用以下代码使用定时器中断使LED闪烁:
#include <msp430.h>
#define LED1 BIT0 //define LED1 as bit 0 (0x00)
#define LED2 BIT6 //define LED2 as bit 6 (0x40)
int main(void)
{
//stop watchdog timer
WDTCTL = WDTPW | WDTHOLD;
//P1 initialization code
P1OUT &= 0x00; //clear all bits on P1
P1DIR |= (LED1|LED2); //set P1.0 and P1.6 to output direction
//Timer_0A3 initialization
TA0CCR0 = 12e3; //count limit (16 bit)
TA0CCTL0 = 0x10; //enable counter interrupts, set bit 4 high
TA0CTL = TASSEL_1 + MC_1; //Timer A0 with ACLK @ 12KHz (TASSEL_1), count UP (MC_1)
//low power mode
_BIS_SR(LPM0_bits + GIE); //LPM0 (low power mode) with interrupts enabled
}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0 (void) //service routine for Timer0 A0 interrupt
{
P1OUT ^= (LED1|LED2); //toggle P1.0 using exclusive-OR
}
猜猜看,它有效!但只有当我运行调试器时。当我关闭调试器时,它会停止它正在做的事情,并且当时点亮的LED仍然点亮。重置电路板根本没有帮助。
经过一些网上研究后,我尝试转到Tools -> Debugger Options -> MSP430 Debugger Options -> Clock Control
取消选中相应计时器的复选框。我有以下选项:[]ACLK []SMCLK []TACLK
。我已经尝试了每个检查/取消检查的组合,似乎没有任何东西似乎允许我的中断在调试器停止运行后运行。
如果我不得不猜测,我会说计时器正在运行,但不知何故中断标志没有正确设置。知道这里发生了什么吗?
答案 0 :(得分:1)
清除中断处理程序中的定时器中断标志:
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0 (void) //service routine for Timer0 A0 interrupt
{
TA0CTL &= ~TAIFG; // Reset interrupt
P1OUT ^= (LED1|LED2); //toggle P1.0 using exclusive-OR
}
答案 1 :(得分:0)
这听起来就像是从RAM运行你的应用程序。如果要在没有调试器的情况下运行,请仔细检查链接器配置并确保定位到Flash。
此外,您是否需要清除任何定时器中断标志?可能是在连接调试器的情况下,不使用低功耗模式,并且定时器中断不断触发。在低功耗模式下,如果没有清除中断标志,当定时器再次尝试设置中断标志时,它不会再次唤醒处理器。
答案 2 :(得分:0)
我发现需要在BCSCTL3 |= LFXT1S_2;
和TA0CTL = TASSEL_1 + MC_1;
之间添加代码行_BIS_SR(LPM0_bits + GIE);
。根据数据表,这是一个需要设置的基本时钟系统控制。它与晶体振荡器有关,但我不完全理解它的作用。如果有人能提供更多见解,那就太棒了。
答案 3 :(得分:0)
我遇到了同样的问题。过了一会儿,我意识到问题出现在ACLK中。当代码从调试器运行时,从VLO正确输入ACLK会安排调试器。但在相反的情况下,您必须通过设置LFXT1Sx = 10b手动设置ACLK的源,在C:
BCSCTL3 = LFXT1S_2;
在main()
的开头某处做。
答案 4 :(得分:-1)
尝试添加:
while (1);
之前 _BIS_SR(LPM0_bits + GIE);
while (1);
_BIS_SR(LPM0_bits + GIE);
之后