波特律动
课程中心/STM32基础教程/【RTC】实时时钟 & 掉电走时

【RTC】实时时钟 & 掉电走时

下载例程代码: 

注意

CubeIDE:请按照 例程使用方法🔗 导入例程,否则下载的可能不是例程而是其他工程。

Keil:请使用 ArmCC V6 编译,否则可能会出现编译错误。点击此处查看切换编译器方法🔗

RTC 简介

RTC(Real Time Clock),即实时时钟,类似于钟表一般,能够持续记录时间,为程序提供精确的日期和时间信息,即使在断电期间也能确保准确运行。

原理和特点

  • 在STM32中,存在两个时钟源:高速时钟(8 MHz)和低速时钟(32.768 kHz)。高速时钟用于驱动CPU、外设和定时器等核心组件,而低速时钟则负责管理看门狗和RTC等功能。
  • RTC依赖低速时钟运行。
  • RTC模块内部包含了一个独立的32位寄存器来保存当前的时间戳信息。
  • 低速时钟以极低的功耗运行,即使在断电情况下,通过备用电源(如纽扣电池),RTC也能持续运行以确保时间准确性。

RTC的一般使用方法

  • 在CubeMX中找到Timers -> RTC,勾选Activate Clock Source,即可激活RTC时钟功能。
  • 即使学习板断电,RTC依然能够持续记录时间。
  • HAL库的RTC驱动未实现日期的断电走时功能,即断电后时间可以继续走时,但日期会重置。
  • keysking提供了RTC库,可以实现断电走时功能,具体代码见下文。
  • 需要获取当前日期和时间时,只需调用相应函数即可实现。

如何使用例程

下载程序,并连接硬件,即可看到效果

硬件连接

  • 使用配套TYPE-C数据线,将学习板连接到计算机

程序效果

  • 打开 波特律动 串口助手 (baud-dance.com) 在线串口调试助手,点击"选择串口",选择USB Single Serial
  • 在串口助手中,将持续看到实时打印的日期和时间。

例程讲解

下面介绍了如何自己实现该例程的功能

1、工程配置

  • 开启外部晶振:在Pinout&Configuration -> System Core -> RCC 页面,将 High Speed Clock (HSE) 以及 Low Speed Clock (LSE) 都配置为 Crystal/Ceramic Resonator
  • 配置主时钟频率:在Clock Configuration 页面,将PLL Source 选择为 HSE,将System Clock Mux 选择为 PLLCLK,然后在HCLK (MHz) 输入72并回车,将HCLK频率配置为 72 MHz
  • 配置RTC时钟频率:在Clock Configuration 页面,将RTC时钟源选择为 LSE
  • 激活RTC:在Pinout&Configuration -> Timers -> RTC -> Mode,勾选 Activate Clock Source、Activate Calendar,以启用RTC时钟并激活日历功能。仅开启RTC时钟将仅记录时间,而不包括日期信息。
  • 打开串口2外设:Pinout&Configuration -> Connectivity -> USART2,将Mode选择为Asynchronous

2、代码

在工程的Core/Inc文件夹上右键,选择New -> File,创建kk_rtc.h文件,将以下代码粘贴到kk_rtc.h文件中

C语言
1#ifndef INC_KK_RTC_H_
2#define INC_KK_RTC_H_
3#include "stm32f1xx_hal.h"
4#include "rtc.h"
5#include "time.h"
6
7HAL_StatusTypeDef KK_RTC_SetTime(struct tm *time);
8struct tm *KK_RTC_GetTime();
9void KK_RTC_Init();
10
11#endif /* INC_KK_RTC_H_ */

在工程的Core/Src文件夹上右键,选择New -> File,创建kk_rtc.c文件,将以下代码粘贴到kk_rtc.c文件中

找到MX_RTC_Init的定义,在此文件中引用#include "kk_rtc.h",并在MX_RTC_Init函数的USER CODE RTC_Init 0注释对中调用KK_RTC_Init()函数
并且通过return 绕过MX_RTC_Init函数后面生成的代码

C语言
1hrtc.Instance = RTC;
2hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
3hrtc.Init.OutPut = RTC_OUTPUTSOURCE_ALARM;
4KK_RTC_Init();
5return;

在main函数的while循环中获取并通过串口输出当前时间

C语言
1 now = KK_RTC_GetTime();
2 sprintf(message, "%d-%d-%d %02d:%02d:%02d", now->tm_year + 1900,now->tm_mon + 1,now->tm_mday,
3 now->tm_hour,now->tm_min,now->tm_sec);
4 HAL_UART_Transmit(&huart2, (uint8_t*)message, strlen(message), HAL_MAX_DELAY);
5 HAL_Delay(1000);