我需要每隔15分钟设置一次闹钟(00:15,00:30,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
至少您需要在RTCAMIN寄存器中设置AE位,以便在分钟匹配时闹铃响起:
RTCAMIN = AE | (timer & 0x7F);
它看起来也像你有事件中断选择发生在每一分钟的变化("RTCCTL01 = RTCMODE + RTCTEVIE + RTCTEV_0;"),这是不一样的用户可编程报警,你似乎想要使用。您需要设置报警中断位:
RTCCTL01 = RTCMODE + RTCTAIE;
你增加计时器值的方法是不正确的,因为它每次都会翻倍,而不是增加15分钟。你应该在你的ISR中使用这个:
timer += 15;
如果这个周期需要改变,那么你将需要两个变量,一个存储新的计时器值,一个存储告警的周期。您可以使用寄存器来存储计时器值,因此它将是这样的(假设"timer"是用户想要的警报周期):
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中这样做。
其他要检查的内容有:
- 确保你没有进入低功耗模式,阻止RTC更新
- 您已经为组合寄存器RTCCTL01使用了正确的定义,而不是将它们与用于单个寄存器(RTCCTL0)的定义混合在一起
我无法判断中断是否是正确的中断(看起来应该是),因为您仍然没有告诉我们零件号是什么。