STM32F1系列的RTC毫秒级计数方法

文章介绍了在STM32F1系列微控制器上,如何利用RTC模块的预分频器余数寄存器实现毫秒级时间计数。通过设置RTC预分频器并读取RTC_DIVH和RTC_DIVL寄存器的值,计算出RTC当前的毫秒数值。程序设计中,RTC_GetDivider()函数用于获取RTC的分频值,然后通过公式转换得到毫秒值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

STM32F1系列的RTC毫秒级计数方法

引言


项目要求,需要使用到毫秒、微秒精度的时间计时。此前采取过TIM基础定时器、滴答定时器完成定时要求,查看手册RTC没有亚秒寄存器等,刚开始以为无法运行,后续查找发现有RTC预分频器余数寄存器,因此可以尝试进行毫秒级计时。

1 设计介绍


我项目是用的野火STM32F103ZET6开发板(无所谓不影响),RTC模块可采取两个时钟源,使用LSI内部时钟(40KHz),和LSE(32.768KHz),区别是只需要在下文调用预分频器余数寄存器相关函数时修改值即可。
RTC时钟源——中文参考手册

2 定时程序介绍


2.1 关键寄存器

RTC预分频器余数寄存器分为高低位,RTC_DIVH、RTC_DIVL。这个寄存器可以获取比秒单位更精确的值,是一个只读的自减寄存器,值和预分频寄存器相同,如果预分频寄存器设置为32767,那么该寄存器自减到0后也会重新装载为32767,自减到0表示经过1000ms。
因此设计程序读取该寄存器的值后,简单地设计计算程序就可以获取毫秒值。

预分频寄存器简介——中文参考手册

2.2 程序设计

首先介绍关键函数RTC_GetDivider()
在stm32f10x_rtc.c文件中可以查看该函数,我放在下面,能调用就可以。

/**
  * @brief  Gets the RTC divider value.
  * @param  None
  * @retval RTC Divider value.
  */
uint32_t RTC_GetDivider(void)
{
  uint32_t tmp = 0x00;
  tmp = ((uint32_t)RTC->DIVH & (uint32_t)0x000F) << 16;
  tmp |= RTC->DIVL;
  return tmp;
}

能获取寄存器的值后又该干啥捏?
我们定义从RTC模块获取的毫秒值为rtc_millisecond,那么:

rtc_millisecond = (32767 - RTC_GetDivider()) * 1000 / 32767; //LSE

就能计算出实际毫秒值了。

### 实现时间记录功能的方法STM32F103C8T6最小系统板上实现时间记录功能,通常可以通过使用定时器(Timer)模块或者RTC(实时时钟)模块来完成。以下是两种方法的具体说明: #### 使用定时器模块的时间记录功能 STM32系列微控制器内置多个通用定时器和高级定时器,这些定时器可以用来测量时间间隔或触发周期性事件。 - 定时器通过配置其计数寄存器和预分频器寄存器,能够精确控制时间间隔。 - 配置完成后,可以在中断服务程序中更新全局变量以记录流逝的时间。 具体步骤如下: 1. 初始化TIMx定时器并设置自动重装载模式。 2. 启动定时器并使能相应的中断。 3. 在中断处理函数中增加一个计数值,用于表示已过去的时间单位数量。 ```c #include "stm32f1xx_hal.h" volatile uint32_t timer_count = 0; void TIM2_IRQHandler(void){ if(__HAL_TIM_GET_FLAG(&htim2, TIM_IT_UPDATE) != RESET && __HAL_TIM_GET_IT_SOURCE(&htim2, TIM_IT_UPDATE) !=RESET ){ __HAL_TIM_CLEAR_IT(&htim2,TIM_IT_UPDATE); timer_count++; } } int main(){ HAL_Init(); // Initialize Timer (example with TIM2) htim2.Instance = TIM2; htim2.Init.Prescaler = 7999; // Set prescaler to get a tick every millisecond at APB clock of 8MHz. htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 999; // Auto-reload value for one second period. htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_Base_Init(&htim2); HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0); HAL_NVIC_EnableIRQ(TIM2_IRQn); HAL_TIM_Base_Start_IT(&htim2); while(1){ // Main application code here... } } ``` 上述代码片段展示了如何初始化TIM2作为毫秒级计时器,并通过中断方式累加`timer_count`变量[^1]。 #### 利用RTC模块进行长时间跨度的时间跟踪 对于更长时段的应用场景,则推荐采用实时钟(RTC)硬件单元。它提供了日历与时钟的功能支持,在低功耗状态下也能维持运行状态。 要启用此特性需满足以下条件之一:连接外部LSE晶振源至相应引脚;或者当内部LSI可用时可直接选用后者替代前者作为输入信号给到RTC电路里去驱动工作逻辑流程下去执行操作命令序列直至结束为止整个过程都需要遵循官方文档指导来进行实际部署实施计划安排表单填写完毕之后提交审核批准后再正式上线投入使用当中去发挥应有的作用效果表现出来供大家共同分享交流学习经验教训总结提升自我能力水平达到预期目标要求标准之上再进一步追求卓越成就辉煌未来前景无限美好光明灿烂前程似锦值得期待憧憬向往追寻探索发现未知领域奥秘真理所在之处找到属于自己的那片天空翱翔飞翔起来吧少年们加油努力奋斗拼搏进取向上向善向前看齐奔跑追逐梦想成真之路越走越宽广开阔平坦顺畅无阻拦障碍物阻挡前进的步伐节奏频率保持一致同步协调配合默契完美展现团队协作精神风貌风采魅力无穷尽也! 同样需要注意的是,如果希望保存断电后的当前日期时间和闹钟设定等重要数据信息的话那么就必须额外接入备用电池供电线路才行这样才能确保即使设备处于关机待机休眠模式下依然不会丢失任何关键性的参数指标统计分析报告资料档案文件等等一切相关内容事项都得以妥善保管维护管理好以便日后查询调阅参考借鉴之用处多多益善焉哉乎? --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值