STM32日历读取,设置和输出

一、什么是RTC

RTC(Real-Time Clock,实时时钟)是一种硬件设备,用于提供精确的时间和日期信息。它通常集成在微控制器或单片机中,可以在断电情况下继续运行并保持准确。RTC广泛应用于各种需要时间计数和日期记录的设备和系统,例如计时器、闹钟、数据日志等。
在这里插入图片描述
在断电情况下 RTC仍可以独立运行 只要芯片的备用电源一直供电,RTC上的时间会一直走。

RTC实质是一个掉电后还继续运行的定时器,从定时器的角度来看,相对于通用定时器TIM外设,它的功能十分简单,只有计时功能(也可以触发中断)。但其高级指出也就在于掉电之后还可以正常运行。

两个 32 位寄存器包含二进码十进数格式 (BCD) 的秒、分钟、小时( 12 或 24 小时制)、星期几、日期、月份和年份。此外,还可提供二进制格式的亚秒值。系统可以自动将月份的天数补偿为 28、29(闰年)、30 和 31 天。

上电复位后,所有RTC寄存器都会受到保护,以防止可能的非正常写访问。

无论器件状态如何(运行模式、低功耗模式或处于复位状态),只要电源电压保持在工作范围内,RTC使不会停止工作。

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 年左右,作为一般应用,这已经是足够了的。

二、创建CubeMX工程

创建STM32F103C8工程

配置RCC(设置高速外部时钟,使能外部晶振LSE)
在这里插入图片描述
配置RTC(激活时钟源(Activate Clock Source)和日历(Activate Calendar))
在这里插入图片描述
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
使能串口
在这里插入图片描述
在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);


重写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);
}

加上星期

/* 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");
		}


三、实验结果

在这里插入图片描述
在这里插入图片描述

四、总结

在进行STM32日历读取、设置和输出的实验过程中,我深刻体会到了实时时钟(RTC)模块的重要性以及其在嵌入式系统中的广泛应用。以下是我的一些心得体会:

首先,实验前期的准备工作至关重要。正确配置RTC模块的时钟源和初始化参数,是确保RTC正常运行的关键步骤。深入了解芯片手册和相关文档,能够更加熟练地进行初始化设置,确保系统的稳定性和准确性。

其次,通过实验,我更清晰地了解了RTC模块的读取和设置操作。利用STM32的RTC库函数,我们可以轻松地获取当前的日期和时间信息,并且能够方便地对系统的日期和时间进行设置。这对于需要时间戳或定时功能的应用非常实用。

在日期和时间的输出方面,通过串口或其他输出方式,我们能够直观地观察到系统的运行状态。这对于调试和监控是非常有帮助的,特别是在实际应用中需要时刻关注系统的时间变化的情境下。

此外,我发现在实际项目中,日期和时间的精准性对于某些任务至关重要。例如,对于数据日志、事件记录等应用场景,准确的时间戳是确保数据可靠性和完整性的重要因素。因此,在实际项目中,我们需要更加关注RTC模块的精确性和稳定性。

总的来说,通过这次实验,我不仅学到了如何在STM32上进行RTC模块的基本操作,还深刻理解了RTC在嵌入式系统中的重要性。这些知识对于我未来在嵌入式开发领域的工作和项目中都将起到积极的指导作用。在掌握了RTC模块的基础之后,我期待能够在实际项目中更灵活地运用这些知识,为系统的时间相关功能提供更为精准和可靠的支持。

  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值