8.1 RTC实时时钟原理及代码实现_以GD32F303和SM32F103为例

8.1 RTC实时时钟原理及代码实现_以GD32F303和SM32F103为例
1.RTC实时时钟的定义实时时钟是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。RTC 电路分属于两个电源域。一部分位于备份域中,该部 分包括一个 32 位的累加计数器、一个闹钟、一个预分频器、一个分频器以及 RTC时钟配置寄存器。这表明系统复位或者从待机模式唤醒时,RTC的设置和时间都保持不变。另一部分位于 VDD 电源域中,该部分只包括APB接口以及一组控制寄存器。2.RTC实时时钟的资源和硬件结构以下是GD30F303(上)和STM32F103(下)的RTC实时时钟的主要特性总结出RTC的基本硬件结构为:1.RTC的时钟源有三种:外部高速时钟HSE(一般为8MHz),然后进行128分频、外部低速时钟LSE(一般为32.768kHz)、单片机内部的低速时钟LSI(40kHz);其中外部低速时钟LSE也是可以通过钮扣电池进行供电而产生时钟信号的。2.分频器(DIV),比如选择外部低速时钟源为LSE的32.768kHz,将分频器设置为32767,此时输出时钟的频率为1Hz,周期为1S,此时32位的计数器就1s加一个数。设置分频器可以产生秒中断。3.计数器(CNT),32位的,用来记录脉冲数;可以产生溢出中断;4.闹钟(ALRM),32位的,可设置数值,计数器到达设置的闹钟数后,闹钟可以产生闹钟中断。单片机手册上的RTC硬件框图(GD32和STM32一样)如下:RTC里面涉及到两部分时钟:其中备份域钟的RTCCLK时钟主要是给计数器计数工作用的,APB中的PCLK时钟主要是给获取和写入寄存器数据使用,因为RTC预分频器和计数器等寄存器的配置都需要从APB1的接口中进行访问。当主电源掉电后,PCLK1即APB1时钟不在工作,RTCCLK时钟可以因纽扣电池供电而继续工作。后备区域的预分频部分有两个寄存器,RTC_RPL寄存器和RTC_DIV寄存器,这两个主要起到计数的作用。比如 RTC时钟配置为32.768KHz,将预分频的数值32767写入到RTC_RPL寄存器中,RTC_DIV寄存器是一个向下递减的计数器,装载RTC_RPL寄存器中的32767向下递减,递减为0后产生一个 TR_CLK 上升沿信号后重新装载 32767 继续向下递减,此时 TR_CLK 信号产生频率就是1Hz,那么RTC_CNT计数器就会1秒钟记一次数。3.Unix时间戳只有计数器怎么变成日历时间?就要使用Unix时间戳。用32位计数器来存储时间戳,然后通过软件将时间戳转换成日历时间,就能获得对应的日期时间。3.1.Unix时间戳转换成日历时间的软件接口函数C标准库中的time模块(time.h)中的接口函数就能将时间戳转换成日历时间;在嵌入式中常使用 localtime 和 mktime 这两个接口函数进行时间戳和日历时间的转换。localtime 已经对闰年、平年,2月份应该有几天等问题已经做了判定,就不需要人为去控制了。上述图片的time模块中涉及到两个参数类型,time_t 类型和 struct tm 类型。其中 time_t 类型是Uint32_t 类型的重定义,是一个无符号整型变量;struct tm 类型是自定义的结构体数据类型,类型如下图:3.2.Unix时间戳转换成日历时间的代码例程#include time.h int mai