Other Parts Discussed in Thread: MSP430FR6989
我正在尝试设置延迟功能、该功能将进入 LMP3 1小时、然后使用 TimerA1中断退出 LMP3。 在此期间不应执行其他操作、省电实用程序只会延迟1小时。 我已修改 msp430fr69xx_TA1_06.c 示例代码。 以下是我的当前代码:
#include <msp430.h>
void delay_hour(float hour)
{
TA1CCR0 = (int)(16524 * hour); //Set count target, up to 65535, or 3.96 hours
TA1CTL |= MC__UP; //Set count mode to up (Changed from TA1CTL = MC__UP;)
__bis_SR_register(LPM3_bits | GIE); //Enter LPM3
//while((TA1CTL & TAIFG) == 0) { __no_operation(); } //Wait until count target is reached and interrupt flag turns on
}
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop WDT
// Configure GPIO
P1DIR |= BIT0; // LED interrupt
P1OUT |= BIT0;
PJSEL0 |= BIT4 | BIT5;
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
// Clock setup
CSCTL0_H = CSKEY >> 8; // Unlock CS registers
CSCTL1 = DCOFSEL_0; // Set DCO to 1MHz
CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK; // Set ACLK = VLO; MCLK = DCO
CSCTL3 = DIVA__32 | DIVS__1 | DIVM__1; // Set S and M dividers to 1, ACLK to 239.75Hz
CSCTL0_H = 0; // Lock CS registers
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 0; // Set count target to 0 by default
// Set timer clock speed to 4.5898 ticks/s, or 16524 ticks/hour
TA1CTL = TASSEL__ACLK | MC__UP | ID__8; //Set clock source to ACLK, the count mode to stop, and the clock divider to 8
TA1EX0 = TAIDEX_7; //Set expansion clock divider to 8
__bis_SR_register(LPM3_bits | GIE); // Enter LPM3 w/ interrupt
while(1)
{
delay_hour(0.000278); //Delay for one second (0.000278hr or 4.59 ticks) for fast toggling of LED (testing purposes)
P1OUT ^= BIT0; //Toggle LED
}
}
// Timer A1 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER1_A0_VECTOR
__interrupt void Timer1_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER1_A0_VECTOR))) Timer1_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
TA1CTL |= MC__STOP; // Stop timer to prevent repeat counting (Changed from TA1CTL = MC__STOP;)
__bic_SR_register_on_exit(LPM3_bits);
}
我将在 MSP430FR6989 Launchpad 上运行此功能。 P1.0 LED 亮起、但不会熄灭。 我知道使用 VLOCLK 的 ACLK 设置工作正常。 我通过制作此脚本对其进行了测试、该脚本以大约每秒一次的速率打开和关闭 LED、如下所示:
#include <msp430.h>
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop WDT
// Configure GPIO
P1DIR |= BIT0; // LED interrupt
P1OUT |= BIT0;
PJSEL0 |= BIT4 | BIT5;
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
// Clock system setup
CSCTL0_H = CSKEY >> 8; // Unlock CS registers
CSCTL1 = DCOFSEL_0; // Set DCO to 1MHz
CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK; // Set ACLK = VLO; MCLK = DCO
CSCTL3 = DIVA__32 | DIVS__1 | DIVM__1; // Set all dividers to 1
CSCTL0_H = 0; // Lock CS registers
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 2; // 2 ticks or 0.44s
TA1CTL = TASSEL__ACLK | MC__UP | ID__8; //Set clock source to ACLK, the count mode to stop, and the clock divider to 8
TA1EX0 = TAIDEX_7; //Set expansion clock divider to 8
__bis_SR_register(LPM3_bits | GIE); // Enter LPM3 w/ interrupt
}
// Timer A1 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER1_A0_VECTOR
__interrupt void Timer1_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER1_A0_VECTOR))) Timer1_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
P1OUT ^= BIT0;
}
由于时钟设置和计时器设置正确、我假设我的错误位于延迟函数或中断中。 延迟函数设置计数并在进入 LPM3之前开始计时器计数。 一旦计数达到、中断应该将计数器设置为停止模式以避免计数重复。 然后、它应该退出 LPM3。
我在主函数中使用 while 循环。 延迟函数应进入 LPM3、以1为单位达到定时器目标计数、然后退出 LPM3。 我假设由于 LPM3中的 CPU 关闭、主函数在退出 LPM3之前无法继续进行 LED 切换。 因此、一旦定时器中断退出 LPM3、LED 将切换、while 环路将返回到延迟功能。 这种假设是错误的吗? 如果是、则在退出 LPM3后、主函数从何处恢复? 如果每次离开 LPM3时它在主函数开始时重新启动、我可以理解它永远不会达到 LED 切换。 在这种情况下、如何修改延迟函数以获得所需的结果?