您好!
我正在使用 LPM3.5下的 MSP430FR2476、并由 RTC 唤醒。 一旦微控制器 从 LPM3.5启动、我就会在向上向下 计数模式下使用计时器 A0 、以便在函数内实现超时、这样我就可以得到超时、以防时间过长、但我无法进入 TIMER0_A1_ISR。
我还没有见过任何将定时器与 RTC 一起用作从 LPM3.5唤醒的定时器(不用于从 LPM3.5唤醒)的示例。
我想知道是否在 RTC 侧或 LPM3.5侧缺少某些配置。
当我使用 LPM4并通过端口中断从 LPM4模式唤醒时、计时器超时工作正常。
我正在使用来自 MSP430FR2476的 SDK 的驱动程序库 RTC.h 和 timer_a.h
这是我的 RTC 初始化:
void initRTC(bool irqEnable,bool minsOrSec, uint16_t t) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer uint16_t modulo; uint32_t mod; if(minsOrSec) { mod = t * 32 * 60; // Dado que al hacer 32 * t_tick = 1s * 60 = 1m } else { mod = t * 32; } //Testing //modulo = 32; //-->IRQs cada 1seg modulo = 57600; // --> IRQs cada 30mins if(mod < modulo) { modulo = (uint16_t)mod; } else { cantIRQs = (uint16_t)(mod/modulo); // A priori nos va a dar un numero entero. (seconds = 21600 --> 6h) } *(unsigned int*)(BKMEM_BASE) = (unsigned int)cantIRQs; *(unsigned int*)(BKMEM_BASE+2) = (unsigned int)countIRQs; P2SEL0 |= BIT0 | BIT1; // set XT1 pin as second function do { CSCTL7 &= ~(XT1OFFG | DCOFFG); // Clear XT1 and DCO fault flag SFRIFG1 &= ~OFIFG; } while (SFRIFG1 & OFIFG); // Test oscillator fault flag // Initialize RTC // Source = 32kHz crystal, divided by 1024 RTC_clearInterrupt(RTC_BASE,RTC_OVERFLOW_INTERRUPT_FLAG); __bis_SR_register(GIE); //Enable interrupts RTC_init(RTC_BASE, modulo - 1, RTC_CLOCKPREDIVIDER_1024); RTC_enableInterrupt(RTC_BASE, RTC_OVERFLOW_INTERRUPT); RTC_clearInterrupt(RTC_BASE,RTC_OVERFLOW_INTERRUPT_FLAG); RTC_start(RTC_BASE,RTC_CLOCKSOURCE_XT1CLK);//RTC_CLOCKSOURCE_XT1VLOCLK }
这就是我进入 LPM3.5模式的方式
PMMCTL0_H = PMMPW_H; // Open PMM Registers for write PMMCTL0_L |= PMMREGOFF; // and set PMMREGOFF __bis_SR_register(LPM3_bits | GIE); // Enter LPM3.5 and Enable Interruptions
我通过这种方式初始化计时器 A 实例0、
//Initialize Timer0_A3 --> Up-Down Mode Timer_A_initUpDownModeParam upDownCtr; upDownCtr.clockSource = TIMER_A_CLOCKSOURCE_ACLK; upDownCtr.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1; upDownCtr.timerPeriod = 65535; //From 0h to 0FFFFh --> ~ 4 seg (updown) upDownCtr.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE; upDownCtr.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE; upDownCtr.timerClear = TIMER_A_DO_CLEAR; upDownCtr.startTimer = false; Timer_A_initUpDownMode(TIMER_A0_BASE ,&upDownCtr);
从 RTC 唤醒时、我再次运行所需的一切的初始化、然后使用 Timer_A_startCounter (timer_a0_BASE、timer_a_updown_mode)启动计时器 A; 但我从未遇到计时器中断:
// Timer0_A3 CC1-2, TA Interrupt Handler #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = TIMER0_A1_VECTOR __interrupt void TIMER0_A1_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(TIMER0_A1_VECTOR))) TIMER0_A1_ISR (void) #else #error Compiler not supported! #endif { switch(__even_in_range(TA0IV,TA0IV_TAIFG)) { case TA0IV_NONE: // No interrupt break; case TA0IV_TACCR1: // CCR1 not used break; case TA0IV_TACCR2: // CCR2 not used break; case TA0IV_TAIFG: // overflow counterTimer--; if(counterTimer <= 0) { timeOut = true; } break; default: break; } }
此外、Code Composer Studio 编译器不允许我在中断内部放置一个断点(第23行)、因此我认为 LPM3.5模式或 RTC 模式的配置存在问题。
为了防止这种情况、我将包含 RTC 中断矢量的代码:
// RTC interrupt service routine #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=RTC_VECTOR __interrupt void RTC_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(RTC_VECTOR))) RTC_ISR (void) #else #error Compiler not supported! #endif { cantIRQs = *(unsigned int*)BKMEM_BASE; countIRQs = *(unsigned int*)(BKMEM_BASE+2) + 1; switch(__even_in_range(RTCIV,RTCIV_RTCIF)) { case RTCIV_NONE: break; // No interrupt case RTCIV_RTCIF: // RTC Overflow { RTC_clearInterrupt(RTC_BASE,RTC_OVERFLOW_INTERRUPT_FLAG); if(countIRQs == cantIRQs) { cbStatus = true; countIRQs=0; } else { cbStatus = false; } *(unsigned int*)(BKMEM_BASE+2) = 0; *(unsigned int*)(BKMEM_BASE+2) = countIRQs; } break; default: break; } }
非常感谢您提供使用 LPM3.5 + RTC 唤醒+计时器的提示或示例。