基于stm32的RTC实时时钟 (HAL)

avatar
作者
猴君
阅读量:0

一:stm32的RTC功能概述 (基于stm32f10x)

        1:绪论

        实时时钟是一个独立的计时器,RTC提供一套持续运行的计数器,这些计数器可以配合适合的软件用来提供一个时钟日历功能。计数器的值可以被写入以设置系统当前时间/日期

        2:主要特性
   

        可编程的余分频器:分频因子可以高达220

                用于长期测量的32位可编程的计数器

        2个独立的时钟:PCLK1时钟(用于APB1接口)和RTC时钟(必须比PCLK1时钟慢至少4倍)

        两个单独的复位类型:

                APB1由系统复位复位

               RTC内核(分频器、警告、计数器、除法器)通过备份区域复位来复位

        三个专用的可屏蔽中断线:

                警告中断线,用来产生一个软件可编程的警告中断

                秒中断线,用来产生一个周期性(周期长度可编程,高达1s)的中断信号

                溢出中断线,用来检测内部可编程计数器什么时候翻滚到0

        3:功能描述

                (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简化结构图

        4:读取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 低功耗模式影响。

                               
        5:配置RTC寄存器

         为了写 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配置       

        1:第一步 创建工程

                 打开stm32cubemx  选择芯片

                

                

        2:第二步 配置RTC

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

                

 

        3:第三步 配置调试接口

 

        4:第四步 配置时钟

 

        5:第五步 配置串口

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

        

        6:生成工程        

三:实现RTC读取时钟

       1:  第一步 打开工程 编译一下

        在main函数中可以找到rtc模块的初始化函数 

         

        时分秒设置 

        年月日 周几设置 

       2:  第二步 定义声明接收时间数据和日期数据的结构体

                找到hal库中存放时间和日期的结构体原型

        时间数据结构体原型

日期数据结构体原型

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

       3:  第三步 重定向串口函数

        找地方重写printf重定向函数

         包含相关的头文件

        函数源码 

int fputc(int ch, FILE *f) {     HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xffff);     return ch;   }

       4:  第四步 在HAL库函数中找到获取时间和日期的函数

        hal库中获取rtc时间函数

        hal库中获取rtc日期函数

         

       5:  第五步 调用函数将RTC时钟的时间数据存放到接收数据的结构体中

                        调用函数获取时间

                        

                        调用函数获取日期

        

         

       6:  第六步 通过串口将时间和日期发送出去 

        串口发送 日期       

         串口发送时间

        

         

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

 

        7:通过usb转tll用串口调试助手在电脑端显示数据

                第一步:准备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 */ }

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!