C语言 实时时钟,MSP430



我需要每隔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)的定义混合在一起

我无法判断中断是否是正确的中断(看起来应该是),因为您仍然没有告诉我们零件号是什么。

最新更新