STM32实时时钟(RTC)技术详解

STM32 系列微控制器(MCU)因其功能强大、低功耗和灵活的外设配置,广泛应用于物联网、嵌入式系统等各类项目中。其中,实时时钟(RTC, Real-Time Clock) 是 STM32 的一个重要外设,它能够在主处理器休眠或掉电时保持准确的时间计数。RTC 主要用于计时、日期维护、低功耗唤醒等场景。本文将深入介绍 STM32 的 RTC 外设及其技术特点、配置方法、常见应用和功耗管理。

一、STM32 RTC 外设概述

STM32 的 RTC 是一个低功耗的外设,能够在系统掉电的情况下仍然保持运行。RTC 外设的主要功能包括:

  1. 实时计时:以秒、分钟、小时为单位的时间计数器。
  2. 日期功能:支持年、月、日、星期的日期计数器,能够识别闰年和不同月份的天数。
  3. 低功耗模式支持:在深度睡眠或待机模式下仍然保持运行,并能通过事件唤醒系统。
  4. 闹钟和定时功能:可以设置定时器和闹钟,用于定时触发事件或定时唤醒 MCU。
  5. 时间戳功能:记录某些事件发生的时间,例如外部引脚的触发时间。
  6. 硬件校准:支持通过软件对 RTC 进行细微的校准,保证长时间运行的精度。

RTC 通常使用一个低速时钟源来保持低功耗,一般是 32.768 kHz 的外部晶振(LSE,Low-Speed External),也可以使用内部低速振荡器(LSI,Low-Speed Internal)。

二、RTC 的技术特点

  1. 低功耗运行
    RTC 外设能够在 MCU 进入低功耗模式(如待机或关断模式)时继续计时。这是 RTC 外设的一大优势,特别适用于电池供电的设备,如手持设备、传感器节点、智能手表等。

  2. 灵活的时钟源选择
    STM32 的 RTC 外设可以使用多种不同的时钟源:

  3. LSE(Low-Speed External):通常是一个 32.768 kHz 的外部晶振,适合长期运行的高精度应用。
  4. LSI(Low-Speed Internal):STM32 自带的内部低速时钟振荡器,典型频率为 32 kHz 左右,但精度较差。
  5. HSE 分频(High-Speed External):某些 STM32 芯片允许将外部高速时钟(如 8 MHz)分频为低速时钟用于 RTC。
  6. 闹钟和定时功能
    RTC 外设提供了闹钟(Alarm)和周期性定时器(Wakeup Timer)功能。通过这些功能,用户可以设定闹钟时间,当时间到达时触发中断或唤醒系统。例如,可以设置设备每隔一段时间进入低功耗模式,然后在指定时间唤醒系统执行任务。

  7. 时间戳功能
    RTC 可以记录特定事件(如外部引脚的信号变化)发生的时间点。该功能对于事件驱动的系统非常实用,可以用于记录系统异常或外部事件的时间。

  8. 硬件校准功能
    STM32 RTC 提供了校准功能,通过调整预分频器的值,补偿时钟源的误差,以提高长时间运行的计时精度。这对于使用内部时钟(如 LSI)的应用尤为重要,因为 LSI 通常不如外部晶振精确。

三、RTC 的基本配置

以下是 STM32 RTC 的基本配置步骤,包括时钟源选择、时间设置、闹钟配置等。

1. 时钟源配置

首先,RTC 需要一个稳定的时钟源。通常使用 32.768 kHz 的外部晶振(LSE)作为时钟源,但也可以选择 LSI 或 HSE 分频。配置 RTC 时钟源时,需要启用备用域(Backup Domain)并配置相应的时钟。

void rtc_init(void) {
    // 启用 PWR 和备份寄存器时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
    PWR_BackupAccessCmd(ENABLE);  // 允许访问备份域

    // 启用 LSE 时钟
    RCC_LSEConfig(RCC_LSE_ON);
    while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);  // 等待LSE就绪

    // 设置 RTC 时钟源为 LSE
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
    
    // 启用 RTC 时钟
    RCC_RTCCLKCmd(ENABLE);

    // 等待RTC同步
    RTC_WaitForSynchro();
}
2. 设置时间和日期

配置 RTC 时间和日期,RTC 的时间和日期寄存器使用 BCD(Binary-Coded Decimal,二进制编码十进制)格式。

void rtc_set_time(uint8_t hour, uint8_t minute, uint8_t second) {
    RTC_TimeTypeDef RTC_TimeStruct;
    
    // 设置时间结构体
    RTC_TimeStruct.RTC_Hours = hour;
    RTC_TimeStruct.RTC_Minutes = minute;
    RTC_TimeStruct.RTC_Seconds = second;

    // 设置时间
    RTC_SetTime(RTC_Format_BIN, &RTC_TimeStruct);
}

void rtc_set_date(uint8_t year, uint8_t month, uint8_t day) {
    RTC_DateTypeDef RTC_DateStruct;
    
    // 设置日期结构体
    RTC_DateStruct.RTC_Year = year;
    RTC_DateStruct.RTC_Month = month;
    RTC_DateStruct.RTC_Date = day;

    // 设置日期
    RTC_SetDate(RTC_Format_BIN, &RTC_DateStruct);
}
3. 闹钟配置

可以通过设置闹钟来触发定时事件,RTC 提供了两个独立的闹钟(Alarm A 和 Alarm B)。

void rtc_set_alarm(uint8_t hour, uint8_t minute, uint8_t second) {
    RTC_AlarmTypeDef RTC_AlarmStruct;
    
    // 设置闹钟时间
    RTC_AlarmStruct.RTC_AlarmTime.RTC_Hours = hour;
    RTC_AlarmStruct.RTC_AlarmTime.RTC_Minutes = minute;
    RTC_AlarmStruct.RTC_AlarmTime.RTC_Seconds = second;
    
    // 启用闹钟A
    RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStruct);
    RTC_AlarmCmd(RTC_Alarm_A, ENABLE);

    // 使能闹钟中断
    RTC_ITConfig(RTC_IT_ALRA, ENABLE);
    NVIC_EnableIRQ(RTC_Alarm_IRQn);
}

void RTC_Alarm_IRQHandler(void) {
    if (RTC_GetITStatus(RTC_IT_ALRA) != RESET) {
        // 处理闹钟事件
        RTC_ClearITPendingBit(RTC_IT_ALRA);  // 清除闹钟中断标志
    }
}
4. 时间戳功能

时间戳功能可以在外部事件发生时记录当前的 RTC 时间,例如当外部引脚产生上升沿或下降沿时。

void rtc_timestamp_init(void) {
    // 配置外部引脚作为时间戳触发源,假设为 PC13 引脚
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    
    // 启用时间戳功能
    RTC_TimeStampCmd(RTC_TimeStampEdge_Falling, ENABLE);
}

void RTC_TAMP_STAMP_IRQHandler(void) {
    if (RTC_GetFlagStatus(RTC_FLAG_TSF) != RESET) {
        // 读取时间戳
        RTC_TimeTypeDef RTC_TimeStamp;
        RTC_GetTimeStamp(RTC_Format_BIN, &RTC_TimeStamp, NULL);

        // 处理时间戳事件
        RTC_ClearFlag(RTC_FLAG_TSF);  // 清除时间戳标志
    }
}
 

四、RTC 的低功耗应用

RTC 在低功耗场景中的应用非常广泛,它可以在系统进入待机、休眠模式时继续保持计时功能,并在指定的时间点唤醒系统。

  1. 待机模式唤醒
    系统进入待机模式时,RTC 可以设置为定时唤醒源。当达到设定的时间时,RTC 产生唤醒事件,系统退出待机模式并继续运行。

  2. 深度睡眠唤醒
    RTC 的闹钟功能可以用于低功耗模式下的周期性唤醒,例如在深度睡眠模式下,RTC 每隔一段时间唤醒 MCU 执行一次任务。

五、总结

STM32 的实时时钟(RTC)是一种低功耗、高精度的外设,非常适合应用于需要长期精确计时的场景。通过外部时钟源(如 32.768 kHz 晶振)和闹钟、时间戳等功能,STM32 的 RTC 可以保持系统的精确时间,并能在低功耗模式下继续工作。掌握 RTC 的配置和使用方法,能够有效提升 STM32 应用的性能和功耗效率。

作者:zxfly2013

物联沃分享整理
物联沃-IOTWORD物联网 » STM32实时时钟(RTC)技术详解

发表回复