piątek, 2 października 2020

LPC1769 - Obsługa RTC

 W tym poście chciałem krótko opisać sposób obsługi zegara RTC. 

Image of LPCXpresso1769/CD

Dane z czasem przechowywane są w następującej strukturze

  1. typedef struct {
  2.     uint32_t time[RTC_TIMETYPE_LAST];
  3. } RTC_TIME_T;
  4.  
  5. typedef enum {
  6.     RTC_TIMETYPE_SECOND,        /*!< Second */
  7.     RTC_TIMETYPE_MINUTE,        /*!< Month */
  8.     RTC_TIMETYPE_HOUR,          /*!< Hour */
  9.     RTC_TIMETYPE_DAYOFMONTH,    /*!< Day of month */
  10.     RTC_TIMETYPE_DAYOFWEEK,     /*!< Day of week */
  11.     RTC_TIMETYPE_DAYOFYEAR,     /*!< Day of year */
  12.     RTC_TIMETYPE_MONTH,         /*!< Month */
  13.     RTC_TIMETYPE_YEAR,          /*!< Year */
  14.     RTC_TIMETYPE_LAST
  15. } RTC_TIMEINDEX_T;

Zegar zostaje uruchomiony standardowo. Bez dodatkowej obsługi alarmów. Przerwanie od rtc generowane co 1 sekundę. 

  1. void RTC_Init(void) {
  2.     Chip_RTC_Init(LPC_RTC);
  3.     Chip_RTC_CntIncrIntConfig(LPC_RTC, RTC_AMR_CIIR_IMSEC, ENABLE);
  4.     Chip_RTC_AlarmIntConfig(LPC_RTC, RTC_AMR_CIIR_IMSEC | RTC_AMR_CIIR_IMMIN | RTC_AMR_CIIR_IMHOUR, ENABLE);
  5.     Chip_RTC_ClearIntPending(LPC_RTC, RTC_INT_COUNTER_INCREASE | RTC_INT_ALARM);
  6.     NVIC_EnableIRQ((IRQn_Type) RTC_IRQn);
  7.     Chip_RTC_Enable(LPC_RTC, ENABLE);
  8. }

Ustawienie alarmu:

  1. void SetAlarm(uint32_t year, uint8_t month, uint16_t dayOfYear, uint8_t dow, uint8_t dom,
  2.                 uint8_t hour, uint8_t minute, uint8_t second)
  3. {
  4.     RTC_TIME_T AlarmTime;
  5.  
  6.     AlarmTime.time[RTC_TIMETYPE_SECOND] = second;
  7.     AlarmTime.time[RTC_TIMETYPE_MINUTE] = minute;
  8.     AlarmTime.time[RTC_TIMETYPE_HOUR] = hour;
  9.     AlarmTime.time[RTC_TIMETYPE_DAYOFMONTH] = dom;
  10.     AlarmTime.time[RTC_TIMETYPE_DAYOFWEEK] = dow;
  11.     AlarmTime.time[RTC_TIMETYPE_DAYOFYEAR] = dayOfYear;
  12.     AlarmTime.time[RTC_TIMETYPE_MONTH] = month;
  13.     AlarmTime.time[RTC_TIMETYPE_YEAR] = year;
  14.  
  15.     Chip_RTC_SetFullAlarmTime(LPC_RTC, &AlarmTime);
  16. }

Obsługa przerwania:

  1. static void InterruptCheckTimeRoutine(void)
  2. {
  3.     //Wykonanie akcji co 30 sekund
  4.     uint32_t sec = Chip_RTC_GetTime(LPC_RTC, RTC_TIMETYPE_SECOND);
  5.     if (!(sec % 30)) {
  6.         generateNewCardData = 1;
  7.     }
  8. }
  9.  
  10. void RTC_IRQHandler(void)
  11. {
  12.     if (Chip_RTC_GetIntPending(LPC_RTC, RTC_INT_COUNTER_INCREASE)) {
  13.         Chip_RTC_ClearIntPending(LPC_RTC, RTC_INT_COUNTER_INCREASE);
  14.     }
  15.  
  16.     InterruptCheckTimeRoutine();
  17.  
  18.     if (Chip_RTC_GetIntPending(LPC_RTC, RTC_INT_ALARM)) {
  19.         Chip_RTC_ClearIntPending(LPC_RTC, RTC_INT_ALARM);
  20.     }
  21. }

Ustawienie czasu w systemie:

  1. void SetTime(uint8_t *buffor) {
  2.     // Ustawienie wartości RTC odebranych od PC
  3.     RTC_TIME_T FullTime;
  4.  
  5.     FullTime.time[RTC_TIMETYPE_SECOND]      = buffor[5];
  6.     FullTime.time[RTC_TIMETYPE_MINUTE]      = buffor[4];
  7.     FullTime.time[RTC_TIMETYPE_HOUR]        = buffor[3];
  8.     FullTime.time[RTC_TIMETYPE_DAYOFMONTH]  = buffor[2];
  9.     FullTime.time[RTC_TIMETYPE_DAYOFWEEK]   = buffor[6];
  10.     FullTime.time[RTC_TIMETYPE_MONTH]       = buffor[1];
  11.     FullTime.time[RTC_TIMETYPE_YEAR]        = buffor[0] + 1996;
  12.  
  13.     Chip_RTC_SetFullTime(LPC_RTC, &FullTime);
  14. }

  1. void SetTime_FromData(uint32_t year, uint8_t month, uint16_t dayOfYear, uint8_t dow, uint8_t dom,
  2.                     uint8_t hour, uint8_t minute, uint8_t second) {
  3.     RTC_TIME_T FullTime;
  4.  
  5.     FullTime.time[RTC_TIMETYPE_SECOND]      = second;
  6.     FullTime.time[RTC_TIMETYPE_MINUTE]      = minute;
  7.     FullTime.time[RTC_TIMETYPE_HOUR]        = hour;
  8.     FullTime.time[RTC_TIMETYPE_DAYOFMONTH]  = dom;
  9.     FullTime.time[RTC_TIMETYPE_DAYOFYEAR]   = dayOfYear;
  10.     FullTime.time[RTC_TIMETYPE_DAYOFWEEK]   = dow;
  11.     FullTime.time[RTC_TIMETYPE_MONTH]       = month;
  12.     FullTime.time[RTC_TIMETYPE_YEAR]        = year;
  13.  
  14.     Chip_RTC_SetFullTime(LPC_RTC, &FullTime);
  15. }

Pobranie aktualnego czasu:

  1. RTC_TIME_T GetTime(void)
  2. {
  3.     RTC_TIME_T FullTime;
  4.     Chip_RTC_GetFullTime(LPC_RTC, &FullTime);
  5.     return FullTime;
  6. }
  7.  
  8. void GetTimeIntoBuffer(uint8_t *buffer)
  9. {
  10.     RTC_TIME_T nowTime = GetTime();
  11.  
  12.     *(buffer + 0) = nowTime.time[RTC_TIMETYPE_YEAR] - 1996;
  13.     *(buffer + 1) = nowTime.time[RTC_TIMETYPE_MONTH];
  14.     *(buffer + 2) = nowTime.time[RTC_TIMETYPE_DAYOFMONTH];
  15.     *(buffer + 3) = nowTime.time[RTC_TIMETYPE_HOUR];
  16.     *(buffer + 4) = nowTime.time[RTC_TIMETYPE_MINUTE];
  17.     *(buffer + 5) = nowTime.time[RTC_TIMETYPE_SECOND];
  18.     *(buffer + 6) = nowTime.time[RTC_TIMETYPE_DAYOFWEEK];
  19. }