stm32F1RTC

RTC

概述

STM32 的实时时钟(RTC)是一个独立的定时器。 STM32 的 RTC 模块拥有一组连续计数

的计数器, 在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当

前的时间和日期。

RTC 模块和时钟配置系统(RCC_BDCR 寄存器)是在后备区域,即在系统复位或从待机模式唤醒后 RTC 的设置和时间维持不变。但是在系统复位后,会自动禁止访问后备寄存器和 RTC,以防止对后备区域(BKP)的意外写操作。所以在要设置时间之前, 先要取消备份区域(BKP)写保护。(每次在操作RTC时要先使能后备寄存器的访问)

RTC可以实现的功能

1:时钟日历的显示

2:闹钟功能

3:秒中断操作

配置过程

1:开启时钟源

//开启电源时钟和备份域时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

2:使能后备寄存器的访问

//上面提到过系统复位后会自动禁止访问后备寄存器和RTC

PWR_BackupAccessCmd(ENABLE);

3:复位备份域

//取消写保护后要清除备份域的数据,清除之前的设置(看情况而定,并不是每次都要复位)

BKP_DeInit();

4:开启外部低速振荡器

RCC_LSEConfig(RCC_LSE_ON);

5:等待LSE启动稳定

while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)

6:选择RTC的时钟

RTC 时钟的选择,还有 RCC_RTCCLKSource_LSI 和 RCC_RTCCLKSource_HSE_Div128

两个,前者为 LSI,后者为 HSE 的 128 分频

RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

7:使能RTC时钟

RCC_RTCCLKCmd(ENABLE);

8:等待最近一次对RTC寄存器的写操作完成,等待RTC寄存器同步

RTC_WaitForLastTask();

RTC_WaitForSynchro();

9:相关配置

下面这几步操作顺序可以替换,但是逻辑不能乱

RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能 RTC 秒中断

RTC_WaitForLastTask(); //等待最近一次对 RTC 寄存器的写操作完成

RTC_EnterConfigMode(); // 允许配置

RTC_SetPrescaler(32767); //设置 RTC 预分频的值

RTC_WaitForLastTask(); //等待最近一次对 RTC 寄存器的写操作完成

RTC_SetCounter(seccount);//设置时间

RTC_ExitConfigMode(); //退出配置模式

 

从上面的过程中我们可以看出,RTC时钟的配置过程主要分为以下几个模块

1:允许访问

2:时钟源选择

3:允许配置设置相关参数(分频值,时间,中断)

只是在操作的时候我们有些要求

1:必须取消写保护(系统复位后会自动禁止访问后备寄存器和RTC)

2:每次配置前要先寄存器同步,允许配置,等待上次操作完成

3:要记得退出配置

这些要求手册中的寄存器介绍中都有描述

### STM32F1 RTC时钟配置教程及使用方法 #### 一、RTC概述 STM32RTC(Real-Time Clock)是一个独立于其他系统的定时器,能够提供精确的时间和日期功能。其工作原理基于一个持续运行的32位向上计数器,该计数器可以从三个不同的源获取时钟信号:低速外部晶振(LSE),低速内部RC振荡器(LSI),以及高速外部晶振(HSE)除以128后的频率[^3]。 #### 二、硬件连接与电源管理 为了确保即使在主电源关闭的情况下也能保持时间准确性,RTC模块位于后备区域(VBAT供电),这意味着只要电池存在电量,RTC就能继续运作而不受VDD状态的影响。值得注意的是,在系统复位之后,默认情况下禁止对这些寄存器进行任何修改;因此,在执行任何读取或写入之前,必须先解除这种保护机制。 #### 三、软件初始化流程 对于STM32F1来说,可以通过调用HAL库中的API来进行RTC的初始化设置: ```c // 初始化结构体定义 RTC_HandleTypeDef hrtc; void MX_RTC_Init(void){ __HAL_RCC_PWR_CLK_ENABLE(); // 开启PWR时钟 HAL_PWREx_EnableBkUpAccess();// 解锁BKPSRAM访问权限 /* 配置LSE作为RTC时基 */ RCC_OscInitTypeDef OscInitStruct; OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; OscInitStruct.PLL.PLLState = RCC_PLL_NONE; OscInitStruct.LSEState = RCC_LSE_ON; if (HAL_RCC_OscConfig(&OscInitStruct)!= HAL_OK){ Error_Handler(); } /* 设置RTC实例参数 */ hrtc.Instance = RTC; hrtc.Init.AsynchPrediv = 99; hrtc.Init.SynchPrediv = 255; hrtc.Init.HourFormat = RTC_HOURFORMAT_24; hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE; hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; if (HAL_RTC_Init(&hrtc) != HAL_OK){ Error_Handler(); } } ``` 这段代码展示了如何启用备用域访问并选择合适的时钟源来驱动RTC。此外还设置了异步预分频器(Asynchronous Prescaler Register, APR) 和同步预分频器(Synchronous Prescaler Register, SPR), 这些值决定了最终供给RTC使用的脉冲速率[^1]。 #### 四、时间和日期的操作 一旦完成了上述初始化过程,则可以进一步设定具体的时间和日期信息: ```c RTC_TimeTypeDef sTime = {0}; RTC_DateTypeDef DateToUpdate = {0}; sTime.Hours = 14; sTime.Minutes = 48; sTime.Seconds = 5; if (HAL_RTC_SetTime(&hrtc,&sTime,RTC_FORMAT_BIN) != HAL_OK){ Error_Handler(); } DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY; DateToUpdate.Month = RTC_MONTH_JANUARY; DateToUpdate.Date = 1; DateToUpdate.Year = 21; if (HAL_RTC_SetDate(&hrtc,&DateToUpdate,RTC_FORMAT_BIN) != HAL_OK){ Error_Handler(); } ``` 以上片段说明了怎样通过`HAL_RTC_SetTime()` 函数指定当前时刻,并利用 `HAL_RTC_SetDate()` 方法输入相应的日历数据。需要注意的是,所有数值都应采用二进制格式传递给这两个函数。 #### 五、保存至备份存储区 为了让设备能够在重新启动后依然保留最新的时间记录,有必要将最新调整过的信息储存在RTC的备份寄存器里。这一步骤同样依赖于前面提到过的解锁操作,即允许程序向这些特殊位置写入新值[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值