实时时钟是一个独立的计时器,RTC提供一套持续运行的计数器,这些计数器可以配合适合的软件用来提供一个时钟日历功能。计数器的值可以被写入以设置系统当前时间/日期
可编程的余分频器:分频因子可以高达220
用于长期测量的32位可编程的计数器
2个独立的时钟:PCLK1时钟(用于APB1接口)和RTC时钟(必须比PCLK1时钟慢至少4倍)
两个单独的复位类型:
APB1由系统复位复位
RTC内核(分频器、警告、计数器、除法器)通过备份区域复位来复位
三个专用的可屏蔽中断线:
警告中断线,用来产生一个软件可编程的警告中断
秒中断线,用来产生一个周期性(周期长度可编程,高达1s)的中断信号
溢出中断线,用来检测内部可编程计数器什么时候翻滚到0
(1)概要:
RTC 由两个主要的单元组成,第一个(APB1 接口)用于提供和 APB1
总线的接口,该单元还包括一套可以从 APB1总线以读或者写方式访问的16位的寄存器。APB1 接口由 APB1总线时钟驱动以和APB1总线连接。
另一个单元(RT内核)由一串可编程的计数器组成,这些计数器由两个模块构成:第
一个模块是RTC 预分频器模块,该模块产生RTC 时间基数 TR_CLK,时基可以被编程为1
个可以高达1秒的周期,它包含一个20位的可编程除法器(RTC预分频器)如果在RTC_CR
寄存器中使能了这个中断的话,每个TR_CLK 周期,RTC产生一个中断(秒中断);第二个
模块是一个32位的可编程的计数器,该计数器可以用当前的系统时间来初始化,系统时间
以 TR_CLK速率速率递增,并且和一个可编程的日期(存储在RTC_ALR 急存器中)进行比较以
产生一个警告中断(如果该中断在RTC_CR 控制寄存器中被使能了的话)
RTC简化结构图

RTC内核完全独立于RTC APB1接口
软件通过 APB1 接口访问RTC 预分频器,计数器和警告值,但是相关的可读寄存器在
每个由 RTC APB1 时钟再同步过的RTC时钟的上升沿期间内部更新。这对于RTC标志来说
也是一样的。
这意味着如果 APB1接口先前被禁用了在APB1接口使能后并且还没有进行第一次内
部更新之前迅速读取RTC APB1寄存器读出的值可能是错误的(一般读到0)。这在以下情
况下可能发生:
(1) 发生了系统复位或电源复位
(2)MCU刚从STANDBY模式唤醒
(3)MCU刚从停止模式唤醒
在以上所有的情况,APB1接口禁用(复位,无时钟驱动或者无电源供应)期间RTC
内核被保持在运行状态。
因此,当禁用 RTC APB1接口后读取RTC寄存器时,软件首先必须等待RTC_CRL寄存
器中的 RSF位(寄存器同步位)被硬件置位。
注意 RTC APB1 接口不受WFI和 WFE 低功耗模式影响。
为了写 RTC_PRL,RTC_CNT,RTC_ALR寄存器,外设必须进入配置模式,这是通过
设置 RTC_CRL 寄存器中的CNF位来完成。
另外,向任何RTC 寄存器的写操作仅当先前的写操作完成后才被进行。为了使软件能
够检测这种情况,RTC_CR 寄存器中的RTOFF 状态位专门用来指示寄存器是否正在进行更
新中,仅当 RTOFF 状态位值为‘1’的时候才能够向RTC 寄存器中写入新值。
配置的过程:
1.轮询 RTOFF 位,在它的值变为‘1’之前等待
2. 置位 CNF 位以进入配置模式
3.写一个或者多个RTC 寄存器
4.清除 CNF 位以退出配置模式
5.轮询 RTOFF,直到它的值变成‘1’以确认写操作结束
写操作仅当 CNF位被清除时才执行,需要至少3个RTCCLK周期才能够完成。
打开stm32cubemx 选择芯片


RTC使能日历 将初始时间设置为 2024年8月1日18时50分39秒 周四





使能串口2 波特率为115200 数据位为8 奇偶校验位无 停止位1



在main函数中可以找到rtc模块的初始化函数
时分秒设置
年月日 周几设置
找到hal库中存放时间和日期的结构体原型
时间数据结构体原型
日期数据结构体原型

在main函数开头定义时间数据结构体和日期数据结构体用来接收rtc模块的数据

找地方重写printf重定向函数
包含相关的头文件

函数源码
int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xffff); return ch; } hal库中获取rtc时间函数
hal库中获取rtc日期函数

调用函数获取时间

调用函数获取日期

串口发送 日期 
串口发送时间

调用延时函数延时1s 在循环内每隔1s读取时间和日期并将时间和日期发送出去

第一步:准备usb转tll模块
第二步:接线
单片机的 rx 对应usb转tll的tx tx 对应 usb转tll的rx
第三步:下载代码后打开串口调试助手 选择配置串口是时的波特率 数据位 校验位等
单片机发送出的日期和时间数据 实现1s发送一次 一次发送两行 第一行 为年 月 日 周几
第二行为时 分 秒

串口助手收不到数据时可以查看是否是魔术棒选项未勾选 Use MicroLIB
mian函数源码
int main(void) { /* USER CODE BEGIN 1 */ RTC_TimeTypeDef time_data; //接收时间数据结构体 时分秒 RTC_DateTypeDef date_data; //接收日期数据结构体 周几 几月 第几天 几几年 /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_RTC_Init(); MX_USART2_UART_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ //调用获取时间函数 HAL_RTC_GetTime(&hrtc,&time_data,RTC_FORMAT_BIN); //调用获取日期函数 HAL_RTC_GetDate(&hrtc,&date_data,RTC_FORMAT_BIN); //串口输出日期 printf("%02d/%02d/%02d %d",2000+date_data.Year,date_data.Month,date_data.Date,date_data.WeekDay); //串口输出时间 printf("%02d:%02d:%02d",time_data.Hours,time_data.Minutes,time_data.Seconds); HAL_Delay(1000); //单位ms 1000 = 1s } /* USER CODE END 3 */ }