我需要每15分钟设置一次闹钟(00:15,00:00,00:45,01:00 ......) 使用实时时钟执行某些过程然后设置新的警报值。 好吧,我有一个代码编写,它运行时钟很好。但是没有发生期间警报。
对代码进行反馈
会很棒void rtc_init(void)
{
RTCCTL01 = RTCMODE + RTCTEVIE + RTCTEV_0;
RTCCTL01 |= RTCHOLD;
RTCSEC = 0x00;
RTCMIN = 0x28;
RTCHOUR = 0x12;
RTCDOW = 0x05;
RTCDAY = 0x1A;
RTCMON = 0x08;
RTCYEAR = 0x07DB;
RTCAMIN = timer;
RTCCTL01 &= ~RTCHOLD;
__enable_interrupt();
}
#pragma vector=RTC_VECTOR
__interrupt void handle_rtc_interrupt(void)
{
switch(__even_in_range(RTCIV,8))
{
case 6:
get_fix();
timer += timer;
if (timer == 60) timer = 1;
RTCAMIN = timer;
RTCCTL1 &= ~RTCHOLD;
break;
}//switch
}//ISR
答案 0 :(得分:2)
至少你需要在RTCAMIN寄存器中设置AE位,以便在分钟匹配时闹钟响起:
RTCAMIN = AE | (timer & 0x7F);
看起来您选择在每分钟更改一次时发生事件中断(“RTCCTL01 = RTCMODE + RTCTEVIE + RTCTEV_0;”),这与您似乎想要使用的用户可编程警报不同。您需要设置警报中断位:
RTCCTL01 = RTCMODE + RTCTAIE;
您递增计时器值的方法不正确,因为它每次都会加倍,而不会超过15分钟。你应该在你的ISR中使用它:
timer += 15;
如果需要更改此期间,则需要两个变量,一个用于存储新的计时器值,另一个用于存储警报的周期。您可以使用寄存器来存储计时器值,因此它会是这样的(假设“计时器”是用户想要的警报周期):
next_timer = RTCAMIN & 0x7F;
next_timer += timer;
if (next_timer) >= 60
{
next_timer -= 60;
}
RTCAMIN = AE | (next_timer & 0x7F);
你应该将计时器重新设置为0,而不是1,当它达到60时,否则你的警报将在xx:00:xx xx:15:xx xx:30:xx xx:45:xx xx:01时关闭:xx xx:16:xx等。
您不应该在计时器变量中准确比较60分钟。它没那么重要,但是在上面的其他两个错误中你将永远不会在第二次迭代中获得正好60。此外,如果60不能被您的警报周期完全整除,那么您将超过60并且需要减少它而不是将其设置为特定值以保持正确的时间。你应该这样做更安全:
if (timer >= 60) timer -= 60;
最后,数据表说您应该在修改警报值时禁用警报中断标志。请记住在ISR中这样做。
其他要检查的事项是:
我无法判断中断是否正确(看起来应该是这样),因为你还没有告诉我们这个部件号是什么。