您好!
我正在使用 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 唤醒+计时器的提示或示例。
