在 STM32 的 RTC(实时时钟) 模块中,异步预分频器 和 同步预分频器 是用于对 RTC 时钟源进行分频的两个模块。它们一起决定了 RTC 的工作频率,可以用来实现精确的时间跟踪。
1. 异步预分频器和同步预分频器的作用
RTC 预分频器的主要作用是将 RTC 时钟源的频率降低到适合 RTC 计数器工作的较低频率(通常是 1Hz,用于每秒计数一次)。它们分为两个部分:
- 异步预分频器 (Asynchronous Pre-divider):
- 主要用于实现较大的分频范围。
- 提供灵活的时钟调节功能。
- 分频后的时钟频率会提供给同步预分频器。
- 同步预分频器 (Synchronous Pre-divider):
- 精确地控制时钟频率,通常用来将时钟进一步分频到精确的 1Hz。
- 由于它是与 RTC 时钟同步工作的,必须使用较低的分频值,因此需要较高的计数频率。
2. RTC 时钟源和分频计算
RTC 可以从不同的时钟源获得输入时钟,如:
- LSE(低速外部晶振):32.768 kHz
- LSI(低速内部 RC 振荡器):约 40 kHz
- HSE(高速外部晶振,通常为 8 MHz,通过 PLL 分频)
根据选择的时钟源,异步和同步预分频器的组合可以将时钟分频到 1Hz,以便 RTC 每秒递增一次。
3. 异步预分频器和同步预分频器的分频原理
RTC 的时钟频率可以通过以下公式计算:
4. 示例配置
使用 LSE (32.768 kHz) 作为 RTC 时钟源
目标是将 32.768 kHz 分频为 1 Hz 的 RTC 计数频率。可以通过调整异步预分频器和同步预分频器来实现:
- LSE 时钟频率:32,768 Hz
- 为了得到 1 Hz 的 RTC 计数频率,假设使用以下值:
- 异步预分频器:127
- 同步预分频器:255
代入公式:
使用 LSI (约 40 kHz) 作为 RTC 时钟源
LSI 的频率不如 LSE 稳定,假设 LSI 的频率是 40,000 Hz。要将 40 kHz 分频为 1 Hz:
- LSI 时钟频率:40,000 Hz
- 异步预分频器:124
- 同步预分频器:319
代入公式:
5. 代码配置示例
以下是使用 STM32 HAL 库配置 RTC 异步和同步预分频器的代码示例。
RTC_HandleTypeDef hrtc; void RTC_Init(void) { // 使能电源和备份寄存器访问权限 __HAL_RCC_PWR_CLK_ENABLE(); HAL_PWR_EnableBkUpAccess(); // 使能 LSE 时钟 __HAL_RCC_LSE_CONFIG(RCC_LSE_ON); // 等待 LSE 准备好 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) {} // 选择 LSE 作为 RTC 时钟源 __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE); // 使能 RTC 时钟 __HAL_RCC_RTC_ENABLE(); // 配置 RTC 异步和同步预分频器 hrtc.Instance = RTC; hrtc.Init.HourFormat = RTC_HOURFORMAT_24; hrtc.Init.AsynchPrediv = 127; // 异步预分频器值 hrtc.Init.SynchPrediv = 255; // 同步预分频器值 hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; if (HAL_RTC_Init(&hrtc) != HAL_OK) { // 初始化失败处理 } }
6. 注意事项
- 异步预分频器 通常会影响 RTC 的功耗和计时精度。异步预分频器的分频值越小,功耗越高,但计时精度会更好。
- 同步预分频器 的计数频率越高,RTC 计数的精度越高,但如果分频系数设置不合理,RTC 可能无法正确计时。
总结
- 异步预分频器:用于较大范围的时钟分频,灵活性高。
- 同步预分频器:用于更精细的分频,确保 RTC 计时精度。
- 两者的组合用于将时钟源频率降低到 1Hz,以便 RTC 可以精确地进行每秒计时。