Часы реального времени, MSP430 - PullRequest
2 голосов
/ 30 августа 2011

Мне нужно устанавливать будильник каждые 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

1 Ответ

2 голосов
/ 30 августа 2011

Как минимум, вам нужно установить бит AE в регистре RTCAMIN, чтобы сработал будильник, когда минуты совпадают:

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)

Я не могу сказать, является ли прерывание правильным (онопохоже, так и должно быть) так как вы до сих пор не сказали нам, что это за номер детали.

...