实时时钟,MSP430

时间:2011-08-30 00:17:43

标签: c msp430

我需要每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

1 个答案:

答案 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中这样做。

其他要检查的事项是:

  • 确保您不会进入阻止RTC更新的低功耗模式
  • 您已使用组合寄存器RTCCTL01的正确定义,而不是将它们与用于各个寄存器的定义混合(RTCCTL0)

我无法判断中断是否正确(看起来应该是这样),因为你还没有告诉我们这个部件号是什么。