3

我需要使用实时时钟每 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
4

1 回答 1

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);

当计时器达到 60 时,您应该将计时器重新设置为 0,而不是 1,否则您的警报将在 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) 的定义混合

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

于 2011-08-30T09:45:16.430 回答