[stm32 HAL库] RTC和BKP驱动

本文档介绍了如何在STM32CubeMX中配置外部时钟源,激活时钟和日历,并切换到外部低速时钟。重点在于解决单片机复位后RCC时钟清零的问题,通过开启BKP备用寄存器并设置标志位,确保复位后时钟依然保持。此外,还展示了如何使用串口进行调试,并详细说明了如何利用HAL库设置和获取RTC时间及日期,确保时间的准确读取和更新。

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

CubeMX 配置

  1. 打开外部时钟
    在这里插入图片描述

  2. 激活时钟和日历
    在这里插入图片描述

  3. 更改RCC时钟为外部低速时钟
    在这里插入图片描述
    以上在CubeMX中的配置就已经完成,点击生成代码即可。

4.这里我需要使用串口进行调试,因此打开了串口一
在这里插入图片描述

工程修改

以上配置后,RCC可以正常走时运行,但是当单片机复位后,RCC时钟会清零,这可不符合我们的目的。
因此,在RCC初始化函数中我们添加这两行代码:
开启BKP备用寄存器时钟和取消其写保护。
在这里插入图片描述
之后在我们添加55行56行57行和83行代码进行是否第一次设置时间进行判断,如果是第一次进行时间的初始化,然后将标志位改变,之后无论如何操作,复位,关闭电源,这个标志位都不会改变。
在这里插入图片描述

实现基本时间走时并读取

  1. 在主函数中定义两个保存时间和数据的结构体,并配置时间和日期等数据在这里插入图片描述
  2. 写入时间数据
HAL_RTC_SetTime(&hrtc, &RtcTime, RTC_FORMAT_BIN)
HAL_RTC_SetDate(&hrtc, &RtcDate, RTC_FORMAT_BIN)
  1. 读取时间数据
HAL_RTC_GetTime(&hrtc, &RtcTime,RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &RtcDate,RTC_FORMAT_BIN);

在这里插入图片描述

### STM32 HALRTC使用教程 #### 配置工程环境 在开始之前,确保已经安装并配置好了STM32CubeMX工具以及相应的开发环境。通过STM32CubeMX可以方便地初始化项目参数,包括但不限于时钟配置、GPIO设置以及其他必要的外设启用。 对于RTC模块而言,在STM32CubeMX界面中找到对应的选项开启此功能,并根据实际需求调整其工作模式(如是否使能备份域访问权限)。完成这些初步设定之后导出至IDE继续后续操作[^1]。 #### 初始化与基本操作 当利用HAL处理RTC相关事务时,通常先要执行一次性的初始化过程: ```c // 定义全局变量用于存储RTC句柄 RTC_HandleTypeDef hrtc; void MX_RTC_Init(void){ /* USER CODE BEGIN RTC_Init 0 */ /* USER CODE END RTC_Init 0 */ /* USER CODE BEGIN RTC_Init 1 */ /* USER CODE END RTC_Init 1 */ /** Initialize RTC Only */ hrtc.Instance = RTC; hrtc.Init.HourFormat = RTC_HOURFORMAT_24; hrtc.Init.AsynchPrediv = 127; hrtc.Init.SynchPrediv = 255; hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; if (HAL_RTC_Init(&hrtc) != HAL_OK) { Error_Handler(); } } ``` 这段代码展示了如何定义一个`RTC_HandleTypeDef`类型的对象来表示RTC设备实例,并对其进行初始化配置。这里设置了异步预分频器(Asynchronous Prescaler)为127同步预分频器(Synchronous Prescaler)为255,意味着每秒钟计数一次;同时也指定了小时制式其他一些输出特性。 #### 设置时间与日期 一旦完成了上述准备工作就可以着手于具体的应用场景了,比如更新当前的时间戳或者查询现有的记录: ```c RTC_TimeTypeDef sTime = {0}; RTC_DateTypeDef DateToUpdate = {0}; sTime.Hours = 18; sTime.Minutes = 30; sTime.Seconds = 0; DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY; DateToUpdate.Month = RTC_MONTH_JANUARY; DateToUpdate.Date = 1; DateToUpdate.Year = 21; if(HAL_RTC_SetTime(&hrtc,&sTime,RTC_FORMAT_BIN)!= HAL_OK){ // 错误处理... } if(HAL_RTC_SetDate(&hrtc,&DateToUpdate,RTC_FORMAT_BIN)!= HAL_OK){ // 错误处理... } ``` 以上片段说明了怎样向RTC写入新的时间日期数据。需要注意的是所有数值均采用二进制格式传递给API接口函数。 #### 处理备用寄存器 除了常规的功能之外,某些情况下可能还会涉及到对后备区域(BACKUP REGISTERS)的操作,这允许开发者保存少量重要信息即使系统断电也能保持不变: ```c uint32_t rtcBackup = 240630; read = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0); printf("%lu\r\n", read); HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR0, rtcBackup); ``` 此处演示了从指定位置读取现有值并通过控制台打印出来,接着又往同一地址处覆盖新内容的过程[^2]。 #### 实现周期性唤醒 为了实现低功耗下的定时任务调度,可以借助RTC产生的周期信号触发MCU进入活动状态从而执行特定程序段落: ```c RTC_AlarmTypeDef sAlarm = {0}; sAlarm.AlarmTime.Hours = 9; sAlarm.AlarmTime.Minutes = 0; sAlarm.AlarmTime.Seconds = 0; sAlarm.AlarmMask = RTC_ALARMMASK_NONE; sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL; sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE; sAlarm.AlarmDateWeekDay = 1; sAlarm.Alarm = RTC_ALARM_A; if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK) { // 错误处理... } ``` 在此基础上进一步定制化警报条件直至满足应用层面的要求为止。例如上面的例子就是每天早上九点钟发出中断请求通知处理器去做某件事情[^4]。 #### 关闭闹钟 不再需要某个已激活的报警机制时应当及时释放资源以免造成不必要的干扰或浪费电力消耗: ```c HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A); ``` 这条语句能够有效地停止选定通道上的任何正在进行中的响铃行为并将关联的状态位重置回初始状况[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

おもいね

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值