W tym poście chciałem krótko opisać sposób obsługi zegara RTC.
Dane z czasem przechowywane są w następującej strukturze
- typedef struct {
- uint32_t time[RTC_TIMETYPE_LAST];
- } RTC_TIME_T;
- typedef enum {
- RTC_TIMETYPE_SECOND, /*!< Second */
- RTC_TIMETYPE_MINUTE, /*!< Month */
- RTC_TIMETYPE_HOUR, /*!< Hour */
- RTC_TIMETYPE_DAYOFMONTH, /*!< Day of month */
- RTC_TIMETYPE_DAYOFWEEK, /*!< Day of week */
- RTC_TIMETYPE_DAYOFYEAR, /*!< Day of year */
- RTC_TIMETYPE_MONTH, /*!< Month */
- RTC_TIMETYPE_YEAR, /*!< Year */
- RTC_TIMETYPE_LAST
- } RTC_TIMEINDEX_T;
Zegar zostaje uruchomiony standardowo. Bez dodatkowej obsługi alarmów. Przerwanie od rtc generowane co 1 sekundę.
- void RTC_Init(void) {
- Chip_RTC_Init(LPC_RTC);
- Chip_RTC_CntIncrIntConfig(LPC_RTC, RTC_AMR_CIIR_IMSEC, ENABLE);
- Chip_RTC_AlarmIntConfig(LPC_RTC, RTC_AMR_CIIR_IMSEC | RTC_AMR_CIIR_IMMIN | RTC_AMR_CIIR_IMHOUR, ENABLE);
- Chip_RTC_ClearIntPending(LPC_RTC, RTC_INT_COUNTER_INCREASE | RTC_INT_ALARM);
- NVIC_EnableIRQ((IRQn_Type) RTC_IRQn);
- Chip_RTC_Enable(LPC_RTC, ENABLE);
- }
Ustawienie alarmu:
- void SetAlarm(uint32_t year, uint8_t month, uint16_t dayOfYear, uint8_t dow, uint8_t dom,
- uint8_t hour, uint8_t minute, uint8_t second)
- {
- RTC_TIME_T AlarmTime;
- AlarmTime.time[RTC_TIMETYPE_SECOND] = second;
- AlarmTime.time[RTC_TIMETYPE_MINUTE] = minute;
- AlarmTime.time[RTC_TIMETYPE_HOUR] = hour;
- AlarmTime.time[RTC_TIMETYPE_DAYOFMONTH] = dom;
- AlarmTime.time[RTC_TIMETYPE_DAYOFWEEK] = dow;
- AlarmTime.time[RTC_TIMETYPE_DAYOFYEAR] = dayOfYear;
- AlarmTime.time[RTC_TIMETYPE_MONTH] = month;
- AlarmTime.time[RTC_TIMETYPE_YEAR] = year;
- Chip_RTC_SetFullAlarmTime(LPC_RTC, &AlarmTime);
- }
Obsługa przerwania:
- static void InterruptCheckTimeRoutine(void)
- {
- //Wykonanie akcji co 30 sekund
- uint32_t sec = Chip_RTC_GetTime(LPC_RTC, RTC_TIMETYPE_SECOND);
- if (!(sec % 30)) {
- generateNewCardData = 1;
- }
- }
- void RTC_IRQHandler(void)
- {
- if (Chip_RTC_GetIntPending(LPC_RTC, RTC_INT_COUNTER_INCREASE)) {
- Chip_RTC_ClearIntPending(LPC_RTC, RTC_INT_COUNTER_INCREASE);
- }
- InterruptCheckTimeRoutine();
- if (Chip_RTC_GetIntPending(LPC_RTC, RTC_INT_ALARM)) {
- Chip_RTC_ClearIntPending(LPC_RTC, RTC_INT_ALARM);
- }
- }
Ustawienie czasu w systemie:
- void SetTime(uint8_t *buffor) {
- // Ustawienie wartości RTC odebranych od PC
- RTC_TIME_T FullTime;
- FullTime.time[RTC_TIMETYPE_SECOND] = buffor[5];
- FullTime.time[RTC_TIMETYPE_MINUTE] = buffor[4];
- FullTime.time[RTC_TIMETYPE_HOUR] = buffor[3];
- FullTime.time[RTC_TIMETYPE_DAYOFMONTH] = buffor[2];
- FullTime.time[RTC_TIMETYPE_DAYOFWEEK] = buffor[6];
- FullTime.time[RTC_TIMETYPE_MONTH] = buffor[1];
- FullTime.time[RTC_TIMETYPE_YEAR] = buffor[0] + 1996;
- Chip_RTC_SetFullTime(LPC_RTC, &FullTime);
- }
- void SetTime_FromData(uint32_t year, uint8_t month, uint16_t dayOfYear, uint8_t dow, uint8_t dom,
- uint8_t hour, uint8_t minute, uint8_t second) {
- RTC_TIME_T FullTime;
- FullTime.time[RTC_TIMETYPE_SECOND] = second;
- FullTime.time[RTC_TIMETYPE_MINUTE] = minute;
- FullTime.time[RTC_TIMETYPE_HOUR] = hour;
- FullTime.time[RTC_TIMETYPE_DAYOFMONTH] = dom;
- FullTime.time[RTC_TIMETYPE_DAYOFYEAR] = dayOfYear;
- FullTime.time[RTC_TIMETYPE_DAYOFWEEK] = dow;
- FullTime.time[RTC_TIMETYPE_MONTH] = month;
- FullTime.time[RTC_TIMETYPE_YEAR] = year;
- Chip_RTC_SetFullTime(LPC_RTC, &FullTime);
- }
Pobranie aktualnego czasu:
- RTC_TIME_T GetTime(void)
- {
- RTC_TIME_T FullTime;
- Chip_RTC_GetFullTime(LPC_RTC, &FullTime);
- return FullTime;
- }
- void GetTimeIntoBuffer(uint8_t *buffer)
- {
- RTC_TIME_T nowTime = GetTime();
- *(buffer + 0) = nowTime.time[RTC_TIMETYPE_YEAR] - 1996;
- *(buffer + 1) = nowTime.time[RTC_TIMETYPE_MONTH];
- *(buffer + 2) = nowTime.time[RTC_TIMETYPE_DAYOFMONTH];
- *(buffer + 3) = nowTime.time[RTC_TIMETYPE_HOUR];
- *(buffer + 4) = nowTime.time[RTC_TIMETYPE_MINUTE];
- *(buffer + 5) = nowTime.time[RTC_TIMETYPE_SECOND];
- *(buffer + 6) = nowTime.time[RTC_TIMETYPE_DAYOFWEEK];
- }