STM32 RTC (Real Time Clock) Detailed Explanation

The Real-Time Clock (RTC) in STM32 microcontrollers is a critical peripheral for timekeeping applications. It operates independently from the main CPU, allowing it to maintain accurate time even in low-power modes. Below is a comprehensive guide to understanding and using the STM32 RTC.
1. RTC Overview
Key Features
Independent Power Domain: Can run from a backup battery (VBAT) when main power is off.
32-bit Programmable Counter: Counts seconds, minutes, hours, etc.
Calendar Support: Day, month, year, and weekday tracking.
Alarms: Can trigger interrupts or wake the MCU from sleep.
Periodic Wakeup Unit: Useful for low-power applications.
Tamper Detection: Protects against unauthorized time changes.
Clock Sources
LSE (Low-Speed External): 32.768 kHz crystal (most accurate).
LSI (Low-Speed Internal): ~32 kHz RC oscillator (less accurate, no crystal needed).
HSE (High-Speed External): Divided down (rarely used for RTC).
📌 Recommendation: Use LSE for best accuracy (e.g., with a 32.768 kHz crystal).
2. RTC Registers & Functional Blocks
Main Components
Prescaler
Divides the input clock (e.g., 32.768 kHz → 1 Hz for seconds counting).
Consists of:
Asynchronous Prescaler (PREDIV_A)
Synchronous Prescaler (PREDIV_S)
Example: For LSE = 32.768 kHz:
PREDIV_A = 127→ 256 HzPREDIV_S = 255→ 1 Hz
Counter Register (RTC_CNT)
- Holds the current time in binary format (typically Unix time or BCD).
Alarm Registers (RTC_ALR)
- Compare against
RTC_CNTto trigger an alarm.
- Compare against
Backup Registers (RTC_BKPxR)
- Retain data during power loss (if VBAT is connected).
3. Initializing the RTC
Using STM32 HAL (STM32CubeMX)
Enable RTC Clock & Power
c
__HAL_RCC_RTC_ENABLE(); // Enable RTC clock __HAL_RCC_PWR_CLK_ENABLE(); // Enable Power Control clock HAL_PWR_EnableBkUpAccess(); // Allow access to backup domainConfigure Clock Source (LSE/LSI)
c
RCC_OscInitTypeDef RCC_OscInit = {0}; RCC_OscInit.OscillatorType = RCC_OSCILLATORTYPE_LSE; RCC_OscInit.LSEState = RCC_LSE_ON; // Enable LSE crystal HAL_RCC_OscConfig(&RCC_OscInit);Initialize RTC
c
RTC_TimeTypeDef sTime = {0}; RTC_DateTypeDef sDate = {0}; // Set time (24-hour format) sTime.Hours = 14; sTime.Minutes = 30; sTime.Seconds = 0; HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN); // Set date sDate.WeekDay = RTC_WEEKDAY_MONDAY; sDate.Month = RTC_MONTH_JANUARY; sDate.Date = 1; sDate.Year = 23; // 2023 HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
4. Reading Time & Date
c
RTC_TimeTypeDef currentTime;
RTC_DateTypeDef currentDate;
HAL_RTC_GetTime(&hrtc, ¤tTime, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, ¤tDate, RTC_FORMAT_BIN);
printf("Time: %02d:%02d:%02d\n", currentTime.Hours, currentTime.Minutes, currentTime.Seconds);
printf("Date: %02d-%02d-20%02d\n", currentDate.Date, currentDate.Month, currentDate.Year);
5. Using RTC Alarms
Set an Alarm (Wake After 10 Seconds)
c
RTC_AlarmTypeDef sAlarm = {0};
sAlarm.AlarmTime.Hours = 0;
sAlarm.AlarmTime.Minutes = 0;
sAlarm.AlarmTime.Seconds = 10; // Trigger after 10 sec
sAlarm.AlarmMask = RTC_ALARMMASK_NONE; // Match all fields
sAlarm.Alarm = RTC_ALARM_A; // Use Alarm A
HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN);
Handle Alarm Interrupt
c
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) {
printf("Alarm triggered!\n");
}
6. Low-Power Operation
Wake from STOP Mode Using RTC Alarm
Enter STOP Mode
c
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);Configure RTC Wakeup
c
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 10, RTC_WAKEUPCLOCK_CK_SPRE_16BITS); // Wake every 10 sec
7. Backup Domain & Tamper Detection
Retain Data During Power Loss
c
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR0, 0x1234); // Write to backup register
uint32_t data = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0); // Read after reset
Enable Tamper Detection
c
RTC_TamperTypeDef sTamper = {0};
sTamper.Tamper = RTC_TAMPER_1;
sTamper.Trigger = RTC_TAMPERTRIGGER_RISINGEDGE;
HAL_RTCEx_SetTamper(&hrtc, &sTamper);
8. Common Issues & Fixes
| Problem | Solution |
| RTC not keeping time | Check LSE crystal & backup battery. |
| Alarm not triggering | Verify NVIC interrupts are enabled. |
| Time drifts | Calibrate LSI or use LSE. |
| Backup data lost | Ensure VBAT is connected. |
9. Advanced Topics
RTC Smooth Calibration (Adjust for crystal inaccuracies).
Time Stamp (Record external events).
Digital Trimming (Fine-tune clock accuracy).
Conclusion
The STM32 RTC is a versatile peripheral for timekeeping, alarms, and wakeup events. Key steps:
Initialize with LSE/LSI.
Set/Read time and date.
Use Alarms for interrupts.
Enable Backup Domain for data retention.




