STM32F429(寄存器版本)获取RTC时间(精确到毫秒)

获取RTC时间(精确到毫秒)

本文记录一下做项目时的一些经验——基于STM32F429开发板的RTC获取时间,精确到毫秒。

RTC相关寄存器

STM32F429 的RTC(Real_Time Clock)是一个独立的 BCD 定时器/计数器,提供一个日历时钟(包含年月日时分秒信息)、两个可编程闹钟(ALARM A 和 ALARM B)中断,以及一个具有中断功能的周期性可编程唤醒标志。 RTC 还包含用于管理低功耗模 式的自动唤醒单元。两个 32 位寄存器(TRDR)包含二进码十进数格式 (BCD) 的秒、分钟、小时(12 或24 小时制)、星期、日期、月份和年份。此外,还提供一个32位寄存器SSR用于亚秒值(毫秒)。下面主要介绍这三个寄存器。

TR寄存器

存储时间(时、分、秒),其结构下图所示(参考开发手册)
在这里插入图片描述
这个寄存器比较简单,注意数据保存时 BCD 格式的,读取之后需要稍加转换,才是十进制的时分秒等数据,在初始化模式下,对该寄存器进行写操作,可以设置时间。

DR寄存器

在这里插入图片描述
同样,该寄存器的的数据采用 BCD 码格式,在初始化模式下,对该寄存器进行写操作,可以设置日期。

SSR寄存器

亚秒寄存器,读取寄存器的值并按照公式进行转换即得到毫秒。

在这里插入图片描述

式子中的PREDIV_S为RTC配置的同步分频值,源码中初始化函数内可以找到,这里为0X3FF。式子中的SS为亚秒值,直接读取SSR寄存器即可获得。将值代入公式中得出:

( PREDIV_S - SS ) / ( PREDIV_S + 1 ) * 1000
= (3FF - SS )/( 3FF+ 1 ) * 1000

代码

话不多说直接上代码:

rtc.c源文件

需要修改初始化函数中的异步分频值为0X1F,同步分频值为0X3FF,使时间精确到1ms

u8 RTC_Init(void)
{  
...
	//设置同步0X3FF异步0X1F可以精确到1ms
	RTC->PRER=0X3FF;//RTC同步分频系数(0~7FFF),必须先设置同步分频,再设置异步分频,Frtc=Fclks/((Sprec+1)*(Asprec+1))
	RTC->PRER|=0X1F<<16;//RTC异步分频系数(1~0X7F)
...

}
//获取RTC时间
//*hour,*min,*sec:小时,分钟,秒钟 
//*ampm:AM/PM,0=AM/24H,1=PM.
void RTC_Get_Time(u8 *hour,u8 *min,u8 *sec,u16 *msec,u8 *ampm)
{
	u32 temp=0;
	u16 ms = 0;
 	while(RTC_Wait_Synchro());	//等待同步  	 
	temp=RTC->TR;
	*hour=RTC_BCD2DEC((temp>>16)&0X3F);
	*min=RTC_BCD2DEC((temp>>8)&0X7F);
	*sec=RTC_BCD2DEC(temp&0X7F);
	ms=RTC->SSR;//获取亚秒
	//根据公式计算精确到1ms的毫秒值
	*msec = (0X3FF - ms)*1000/(0X3FF + 1);//1000在分子,防止值为0
	*ampm=temp>>22; 
	temp=RTC->DR;//读一次日期,防止时间不更新
}

//BCD码转换为十进制数据
//val:要转换的BCD码
//返回值:十进制数据
u8 RTC_BCD2DEC(u8 val)
{
	u8 temp=0;
	temp=(val>>4)*10;
	return (temp+(val&0X0F));
}

STM32F429寄存器版本的源码只精确到了秒,这里需要修改RTC_Init和RTC_Get_Time函数,使其精确到毫秒,其他的不变。

用法

项目中用来记录主控板(STM32)通过网络接收上位机下发文件的时间,文件发送请求时记录开始接收时间,文件发送完毕记录结束接收时间

tcpserver.c源文件

//获取开始接收时间
	RTC_Get_Time(&hour,&min,&sec,&msec,&ampm);
	printf("Start time:%02dh:%02dm:%02ds:%03dms\r\n",hour,min,sec,msec);
//获取接收结束时间
	RTC_Get_Time(&hour,&min,&sec,&msec,&ampm);
	printf("End time:%02dh:%02dm:%02ds:%03dms\r\n",hour,min,sec,msec);

串口输出如图

在这里插入图片描述

可以看到主控板接收上位机发送1M左右的bmp图片文件耗时2s多。

总结

**

1. 设置同步和异步分频系数精度,使得毫秒精确到1ms
2. 获取时分秒,读取TR寄存器并进行BCD转十进制转换
3. 获取日历,读取DR寄存器并进行BCD转十进制转换
4. 获取毫秒,读取SSR寄存器,根据公式转换
5. 最后获取一次日期,防止下次读取时间时不更新

  • 5
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用STM32F407芯片的RTC自动获取时间日期的代码示例: ``` #include "stm32f4xx.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_rtc.h" #include "stm32f4xx_pwr.h" #include "misc.h" void RTC_Config(void); int main(void) { RTC_Config(); while(1) { RTC_TimeTypeDef RTC_TimeStructure; RTC_DateTypeDef RTC_DateStructure; RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure); RTC_GetDate(RTC_Format_BIN, &RTC_DateStructure); // 在这里使用RTC_TimeStructure和RTC_DateStructure来执行你需要的操作 } } void RTC_Config(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); PWR_BackupAccessCmd(ENABLE); RCC_LSEConfig(RCC_LSE_ON); while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); RCC_RTCCLKCmd(ENABLE); RTC_InitTypeDef RTC_InitStructure; RTC_InitStructure.RTC_AsynchPrediv = 0x7F; RTC_InitStructure.RTC_SynchPrediv = 0xFF; RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; RTC_Init(&RTC_InitStructure); RTC_TimeTypeDef RTC_TimeStructure; RTC_TimeStructure.RTC_Hours = 0x00; RTC_TimeStructure.RTC_Minutes = 0x00; RTC_TimeStructure.RTC_Seconds = 0x00; RTC_SetTime(RTC_Format_BIN, &RTC_TimeStructure); RTC_DateTypeDef RTC_DateStructure; RTC_DateStructure.RTC_Year = 0x00; RTC_DateStructure.RTC_Month = 0x01; RTC_DateStructure.RTC_Date = 0x01; RTC_DateStructure.RTC_WeekDay = RTC_Weekday_Monday; RTC_SetDate(RTC_Format_BIN, &RTC_DateStructure); } ``` 这段代码使用了STM32F407芯片的RTC模块来获取当前的时间和日期。在主循环中,我们可以使用RTC_TimeStructure和RTC_DateStructure来执行我们需要的操作。请注意,这段代码假定你已经正确地配置了RTC的时钟源和预分频器,并且已经启用了备份电源。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值