【RTC】实时时钟 & 掉电走时
下载例程代码:
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"67HAL_StatusTypeDef KK_RTC_SetTime(struct tm *time);8struct tm *KK_RTC_GetTime();9void KK_RTC_Init();1011#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);