【嵌入式】STM32进阶-RTC日历读取,设置和输出

0.前言

实验前言:
在嵌入式系统和物联网应用开发中,STM32微控制器因其高效性能和广泛的应用支持而受到开发者的青睐。实时时钟(RTC)是一个重要的外围设备,它可以在微控制器休眠时保持计时,并在唤醒时进行日期和时间的读取。本实验将介绍如何使用STM32微控制器读取、设置和输出RTC日历。
通过本实验,我们将学习如何在STM32上配置RTC模块,如何读取和解析RTC日历数据,此外,我们还将探讨如何通过编程方式设置RTC日历数据,以便在需要时对时间进行精确控制。
通过本实验,我们将深入了解STM32微控制器和RTC模块的工作原理和应用方法。通过实际操作,我们将掌握如何在STM32上配置和使用RTC模块,并提高我们的嵌入式系统和物联网应用开发能力。同时,本实验还将提供一些实战技巧和经验,帮助我们在开发过程中更好地解决可能出现的问题。

1.什么是RTC

1.1概述

RTC(Real-Time Clock,实时时钟)是一种硬件设备,用于提供精确的时间和日期信息。它通常集成在微控制器或单片机中,可以在断电情况下继续运行并保持准确。RTC广泛应用于各种需要时间计数和日期记录的设备和系统,例如计时器、闹钟、数据日志等。
在这里插入图片描述
RTC实质是一个掉电后还继续运行的定时器,从定时器的角度来看,相对于通用定时器TIM外设,它的功能十分简单,只有计时功能(也可以触发中断)。但其高级指出也就在于掉电之后还可以正常运行。
两个 32 位寄存器包含二进码十进数格式 (BCD) 的秒、分钟、小时( 12 或 24 小时制)、星期几、日期、月份和年份。此外,还可提供二进制格式的亚秒值。系统可以自动将月份的天数补偿为 28、29(闰年)、30 和 31 天。
上电复位后,所有RTC寄存器都会受到保护,以防止可能的非正常写访问。
无论器件状态如何(运行模式、低功耗模式或处于复位状态),只要电源电压保持在工作范围内,RTC使不会停止工作。

1.2特性

以下是RTC的主要特性:

特性描述
精确度提供高精度的时间和日期信息
低功耗模式可以在低功耗模式下继续运行
时钟校准支持时钟校准功能,可以校正时钟的偏差
报警功能可以设置报警功能,当达到指定时间时触发中断
外部电池备份可以使用外部电池进行时间备份,即使断电也能保持准确
自动唤醒可以设置自动唤醒功能,根据预设条件唤醒系统

在这里插入图片描述RTC时钟的框图还是比较简单的,这里我们把他分成 两个部分:
APB1 接口:用来和 APB1 总线相连。 此单元还包含一组 16 位寄存器,可通过 APB1 总线对其进行读写操作。APB1 接口由 APB1 总 线时钟驱动,用来与 APB1 总线连接。
通过APB1接口可以访问RTC的相关寄存器(预分频值,计数器值,闹钟值)。
RTC 核心接口:由一组可编程计数器组成,分成 两个主要模块 。
第一个模块是 RTC 的 预分频模块,它可编程产生 1 秒的 RTC 时间基准 TR_CLK。RTC 的预分频模块包含了一个 20 位的可编程分频器(RTC 预分频器)。如果在 RTC_CR 寄存器中设置了相应的允许位,则在每个 TR_CLK 周期中 RTC 产生一个中断(秒中断)。
第二个模块是一个 32 位的可编程计数器 (RTC_CNT),可被初始化为当前的系统时间,一个 32 位的时钟计数器,按秒钟计算,可以记 录 4294967296 秒,约合 136 年左右,作为一般应用,这已经是足够了的。

1.3使用方法

使用RTC通常需要以下步骤:

  1. 配置RTC的时钟源和分频系数。
  2. 初始化RTC并设置初始时间和日期。
  3. 配置报警功能(可选)。
  4. 启动RTC时钟。
  5. 根据需要读取时间和日期信息或进行其他操作。

具体的使用方法可能因硬件设备和系统而异,因此请根据相应的文档和资料进行配置和控制。

注意:RTC的使用方法和特性可能因硬件设备而异,具体请参考相关文档和资料。

2.读取STM32F103内部的时钟

以下是读取STM32F103内部时钟的基本流程:

  1. 初始化系统时钟:在开始读取之前,首先需要初始化系统时钟。这可以通过配置RCC(Reset and Clock Control,复位和时钟控制)寄存器来实现。具体的初始化步骤包括设置PLL(Phase-Locked Loop,锁相环)参数、选择系统时钟源以及配置分频系数等。
  2. 选择和配置时钟源:根据需要,选择适当的时钟源。STM32F103支持多种时钟源,包括内部时钟(HSI)、外部时钟(HSE)以及PLL。根据具体要求,选择合适的时钟源并进行相应的配置。
  3. 读取时钟值:一旦系统时钟初始化并选择好时钟源,就可以读取时钟值了。STM32F103的内部时钟可以通过读取特定寄存器来获取。

具体的时钟寄存器可能因芯片型号而异,通常包括RCC_CIR、RCC_CFGR、RCC_CR等寄存器。根据芯片手册和参考资料,找到相应的寄存器并读取相应的时钟值。
以下是读取STM32F103内部时钟的流程图:

初始化系统时钟
选择和配置时钟源
读取时钟值

注意:具体的操作步骤和寄存器配置可能因芯片型号而异,请根据STM32F103的芯片手册和参考资料进行具体操作。

3.示例

使用STM32CubeMX创建工程

3.1设置RCC

  • 设置高速外部时钟HSE 选择外部时钟源
  • 使能外部晶振LSE

RTC设备因为其独特的运行方式(即掉电依旧运行)使用HSE分频时钟或者LSI的时候,在主电源VDD掉电的情况下,这两个时钟来源都会受到影响,资源消耗太大,小小的纽扣电池根本吃不消。没法保证RTC正常工作.所以RTC一般都时钟低速外部时钟LSE
在这里插入图片描述

3.2配置RTC

在这里插入图片描述

  • RTC_OUT: Not RTC_OUT
  • Tamper: ×
    第一个是是否使能 tamper(PC13)引脚上输出校正的秒脉冲时钟,
    第二个: RTC入侵检测校验功能

RTC校验功能,使能侵入检测功能。RTC时钟经64分频输出到侵入检测引脚TAMPER上
当 TAMPER引脚上的信号从 0变成1或者从 1变成 0(取决于备份控制寄存器BKP_CR的 TPAL位),会产生一个侵入检测事件。侵入检测事件将所有数据备份寄存器内容清除。
也就是第一个是使能tamper(PC13)引脚作为时钟脉冲输出
第二个是使能tamper(PC13)引脚作为入侵检测功能
下面是两个RTC的中断:
RTC全局中断RTC_IRQHandler()
闹钟中断函数RTCAlarm_IRQHandler()
在这里插入图片描述
此处设置时间

  • Data Format: 日期格式
  • Binary data format 十六进制
  • BCD data format BCD码进制

使用自动配置,初始化时间必须使用BCD data format,原因是库函数存在bug,如果使用Binary data format,月份配置会出错,比如说11月,配置时会赋值为RTC_MONTH_NOVEMBER,而此宏定义值为0x11,也就是说其十进制值为17

3.3使能串口

在这里插入图片描述

3.4创建项目

3.5设置代码并编译运行

1.在main.c中定义时间和日期的结构体用来获取时间和日期

RTC_DateTypeDef GetData;  //获取日期结构体
RTC_TimeTypeDef GetTime;   //获取时间结构体

2.在main函数的while循环中添加以下代码

/* Get the RTC current Time */
HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
 /* Get the RTC current Date */
 HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);
/* Display date Format : yy/mm/dd */
 printf("%02d/%02d/%02d\r\n",2000 + GetData.Year, GetData.Month, GetData.Date);
/* Display time Format : hh:mm:ss */
printf("%02d:%02d:%02d\r\n",GetTime.Hours, GetTime.Minutes, GetTime.Seconds);
printf("\r\n");
HAL_Delay(1000);

在这里插入图片描述
3.重写fputc函数,完成printf函数的重定向

///重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
		/* 发送一个字节数据到串口 */
		USART_SendData(USART3, (uint8_t) ch);
		
		/* 等待发送完毕 */
		while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);		
	
		return (ch);
}
 
///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
		/* 等待串口输入数据 */
		while (USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == RESET);
 
		return (int)USART_ReceiveData(USART3);
}

注意,如果重写了printf,build前一定要勾选Use MiscroLiB
在这里插入图片描述
加上星期

/* Display date Format : weekday */
		if(GetData.WeekDay==1){
			printf("星期一\r\n");
		}else if(GetData.WeekDay==2){
			printf("星期二\r\n");
		}else if(GetData.WeekDay==3){
			printf("星期三\r\n");
		}else if(GetData.WeekDay==4){
			printf("星期四\r\n");
		}else if(GetData.WeekDay==5){
			printf("星期五\r\n");
		}else if(GetData.WeekDay==6){
			printf("星期六\r\n");
		}else if(GetData.WeekDay==7){
			printf("星期日\r\n");
		}

在这里插入图片描述

4.实验效果

编译
在这里插入图片描述

烧录
在这里插入图片描述

打开串口助手接收信息
在这里插入图片描述

总结

在STM32的开发中,RTC(实时时钟)模块是一个非常重要的组件,它提供了实时时钟和日历功能。在本次实验中,我主要学习了如何读取、设置和输出RTC日历。
首先,我们需要配置RTC模块。在STM32CubeMX中,我可以选择打开RTC功能,并配置相应的时钟源和预分频器。然后,我需要在代码中初始化RTC模块设置RTC时钟和日历的时区,并启动RTC。
一旦RTC模块配置完成,我就可以通过读取和设置寄存器来访问RTC的日期和时间。读取日期和时间的方法是读取相应的寄存器值,并将其转换为易于理解的格式。例如,我可以读取RTC_DR寄存器来获取日历日期,读取RTC_TR寄存器来获取时钟时间。
设置日期和时间的方法是将相应的值写入寄存器。在进行写操作之前,我需要先禁用写保护功能,并在写入完成后重新启用写保护。
最后,我可以通过串口或LCD等外设来输出RTC日历。我可以将读取到的日期和时间值转换为字符串,并通过串口打印出来,或者显示在LCD屏幕上。
在实验中,我还可以扩展功能,例如添加闹钟功能、设置定时器中断等。这些功能可以通过配置RTC寄存器和相应的中断处理函数来实现。
总结来说,通过本次实验,我学习了如何配置和使用STM32的RTC模块,实现了对RTC日历的读取、设置和输出。RTC模块在很多应用中都是必不可少的,例如电子表、计时器等。掌握了RTC的使用,我可以更好地开发和设计STM32的应用程序。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值