基于STM32CubeMX和keil采用RTC时钟周期唤醒和闹钟实现LED与BEEP周期开关

文章目录

  • 前言
  • [1. RTC概念](#1. RTC概念)
    • [1.1 RTC的时钟信号源](#1.1 RTC的时钟信号源)
    • [1.2 预分频器](#1.2 预分频器)
    • [1.3 实时时钟与日历数据](#1.3 实时时钟与日历数据)
    • [1.4 周期性自动唤醒](#1.4 周期性自动唤醒)
    • [1.5 可编程闹钟](#1.5 可编程闹钟)
  • [2. RTC相关中断](#2. RTC相关中断)
  • [3. STM32CubeMX配置](#3. STM32CubeMX配置)
    • [3.1 时钟配置](#3.1 时钟配置)
    • [3.2 引脚配置](#3.2 引脚配置)
    • [3.3 RTC配置](#3.3 RTC配置)
      • [3.3.1 模式选择](#3.3.1 模式选择)
      • [3.3.2 RTC基本参数配置](#3.3.2 RTC基本参数配置)
      • [3.3 中断配置](#3.3 中断配置)
  • [4. 代码编写](#4. 代码编写)
  • 总结

前言

RTC的功能有很多,这里主要介绍RTC的周期唤醒和闹钟功能。

本篇博客先阐述RTC的概念以及周期唤醒和闹钟的原理,并对STM32CubeMX的配置参数进行阐述,最后结合LED与BEEP进行效果演示。

最终效果:

每分钟的第5秒翻转LED0状态.

每分钟的第30秒翻转BEEP的状态。

每秒翻转LED1状态。


1. RTC概念

RTC(Real-Time Clock),实时时钟。它是由时钟信号驱动的日历时钟,提供日期和时间数据。在STM32F407ZET6里面,有一个RTC,由普中的开发板后面的电源VBAT供电,这个的好处在于它可以提供不间断的日期时间数据。不像我们写程序配置的时间,一般我们关闭了开发板的电源就丢失了。这个RTC其实在我使用中觉得最有用的大概就是使用ssh连接linux系统的时候,往里面传文件,可以看到文件的修改日期。如果没有这个RTC,传输进嵌入式系统的文件的修改日期大概率就是系统最初始的时间,比如1970-1-1。

RTC有两个可编程的闹钟,库函数中就是AlarmA和AlarmB。可以设定任意组合和重复性闹钟:有一个周期唤醒单元,可以作为一个普通定时器使用;还具有时间戳和入侵检测功能。这篇博客就写的是前半部分,后面会再写一篇后续的功能。

1.1 RTC的时钟信号源

我们RTC的时钟是哪里来的?打开看STM32CubeMX看一下时钟配置就知道了

通过上图可以看到RTC的时钟来源有三个:
LSI:MCU内部的32kHz时钟信号。
LSE:MCU外接的32.768kHz时钟信号。
HSE_RTC:MCU外接的高速晶振HSE经过2到31分频后的时钟信号。

在实际的时钟源选择上,我们一般选择LSE。因为外接的32.768kHz的时钟,经过多次二分频后就可以得到精确的1Hz的时钟信号,转成时间就是1s一个周期。

STM32CubeMx只给出RTC的时钟来源,RTC的具体框图如下。


1.2 预分频器

要想实现输出不同频率的时钟,就取决于预分频器的系数。对于给定的初始RTC时钟源信号,只有经过预分频器的分频,才可以在指定引脚输出我们想要的频率的时钟。

在上图中,以32.768kHz的LSE时钟源为例,RTC的时钟源经过精密校准后,通过异步分频器128分频,得到ck_apre为256Hz。256Hz的时钟信号经过同步分频256分频,得到1Hz的ck_spre信号。

ck_apre和ck_spre经过一个选择器后,可以选择其中一个时钟信号作为RTC_CALIB时钟信号,这个时钟信号经过输出控制选择,可以输出到复用引脚RTC_AF1,也就是可以向外部提供一个256Hz(异步分频)或1Hz(异步+同步分频)的时钟信号。


1.3 实时时钟与日历数据

上图RTC的总框图中有两个暗部的影子寄存器
RTC_SSR:亚秒计数器
RTC_TR:时间计数器
RTC_DR:日期计数器

系统每隔两个RTCCLK周期就讲当前的日历值复制到影子寄存器中。当程序读取日期时间数据时,读取的是影子寄存器的内容,而不会影响日历计数器的工作。

本质上我认为影子寄存器就是用来做一个数据备份,主要备份的就是亚秒,时间,日期。


1.4 周期性自动唤醒

我在写定时器TIM的相关博客的时候写到过一个自动重装载值。比如我将该值设定为10,那么计数器到10就触发一次事件,同时计数器从0开始计数。这个周期自动唤醒的功能也类似。

RTC内有一个16位自动重载递减计数器,可以产生周期性的唤醒中断,16位寄存器RTC_WURT存储用于设置定时周期的自动重载值。周期唤醒定时器的输入时钟有两个来源:

1.同步预分频器输出的clk_spre时钟信号,通常是1Hz
2.RTCCLK经过2、4、8、16分频后的时钟信号(结合一下RTC的原理框图)

一般可以在周期性唤醒中断里读取RTC当前时间。例如,设置周期唤醒时钟源为1Hz的ck_spre信号,并且每秒中断一次。唤醒中断产生时间信号WUTF,这个信号可以配置到复用引脚RTC_AF1。


1.5 可编程闹钟

在STM32F407ZET6中有两个可编程闹钟,闹钟A,闹钟B。

闹钟的时间和重复方式可以自定义,后面STM32CubeMX配置的时候阐述。闹钟触发的时候闹钟A,B分别产生事件信号ALRAF和ALRBF。这两个信号和周期唤醒事件WUTF一起经过一个选择器,可以选择一个信号作为输出信号RTC_ALARM,再通过输出控制可以输出到复用引脚RTC_AF1。


2. RTC相关中断

我这里只介绍用到的时钟周期唤醒以及闹钟对应的中断名称和ISR。

中断号 中断名称 说明 ISR
3 RTC_WKUP 连接到EXTI 22线的RTC唤醒中断 RTC_WKUP_IRQHandler()
41 RTC_Alarm 连接到EXTI 17线的RTC闹钟(A和B)中断 RTC_Alarm_IRQHandler()

两个中断可以触发的中断事件以及对应的回调函数如下表。

中断名称 中断事件源 中断事件类型 输出或输引脚 回调函数
RTC_Alarm 闹钟A RTC_IT_ALRA RTC_AF1 HAL_RTC_AlarmAEventCallback()
RTC_Alarm 闹钟B RTC_IT_ALRB RTC_AF1 HAL_RTCEx_AlarmBEventCallback()
RTC_WKUP 周期唤醒 RTC_IT_WUT RTC_AF1 HAL_RTCEx_WakeUpTimerEventCallback()

对于STM32F407ZET6,复用引脚RTC_AF1是引脚PC13,RTC_AF2是引脚PI8。但是只有178个引脚的MCU才有PI8,所以普中这款STM32F407开发板上面是没有RTC_AF2只有RTC_AF1。

写到这里,其实我们大概已经知道怎么做了。对于最终效果:

每分钟的第5秒翻转LED状态.

每分钟的第30秒翻转BEEP的状态。

每秒翻转LED1状态。

我们只需要在调用中断函数的时候翻转一下电平就可以了。

现在的问题是什么时候调用中断,怎么判定设置闹钟以及周期唤醒。

下面我们用STM32CubeMX来详细阐述一下。


3. STM32CubeMX配置

3.1 时钟配置

刚才讲到RTC的1Hz的分频,最好选择的是时钟源是外部的低速晶振。

3.2 引脚配置

LED和蜂鸣器配置

RTC时钟输出引脚

3.3 RTC配置

这里我们不涉及到时间戳等RTC其他功能,只考虑我们用到的周期唤醒和闹钟。

3.3.1 模式选择

对于Timers模块,我们需要启用时钟源以及日历。

AlarmA和AlarmB都有三个选项。

Disable:禁用
Internal Alarm:内部闹钟功能
Routed to AF1:闹钟事件信号输出到复用引脚RTC_AF1。

WakeUp也有三个选项。

Disable:禁用
Internal WakeUp:内部唤醒功能
Routed to AF1:闹钟事件信号输出到复用引脚RTC_AF1。

这里注意,Routed to AF1这个选项,有且只能有一个支持配置。也就是说AlarmA ,AalarmB,WakeUp三种唤醒方式只能支持一种配置到AF1。一旦AF1被占用了,那么其他的唤醒方式不能配置输出到AF1。


3.3.2 RTC基本参数配置

General
Hour Format: 小时格式,可选12h制或者24小时制。
Asynchronous Predivider value:异步分频器值。设置值为0~127,对应分频系数1-128。当RTCCLK为32.768kHz时,128分频后就是256Hz。
Synchronous Predivider value:同步预分频器。设置值为0~32767,对应分频系数为1-32768。256Hz分频后就是1Hz。
Output Polarity:输出极性。闹钟A,B以及周期唤醒中断事件信号有效时的输出极性,可设置为高电平或低电平。
Output Polarity:输出类型。复用引脚RTC_AF1的输出类型,可选开漏输出或者推挽输出。

Calendar Time
Data Format:数据格式。可选择二进制格式或者BCD格式。
Hours:初始化时间数据的时。
Minutes:初始化时间数据的分。
Seconds:初始化时间数据的秒。
Day Light Saving: value of hour adjustment:夏令时设置。这里设置为不使用夏令时。啥叫夏令时?
Store Operation:存储操作。表示是否已经对夏令时设置做修改。设置为Reset表示未修改夏令时。Set则表示已修改。

Calendar Date

这个分组主要设置的是初始化的日期。
Week Day:周几
Month:几月
Date:几日
Year:几年


唤醒方式设置。

因为AlarmB和AlarmA的设置是一样的,我这里方便截图,就直接用AlarmB做解释了。

AlarmA/B
Hours:时 0-23
Minutes:分 0-59
Seconds:秒 0-59
Sub Seconds:亚秒 0-59
Alarm Mask Date Week day:屏蔽日期。设置为Enable表示屏蔽,即闹钟与日期无关。反之有关
Alarm Mask Hours:屏蔽小时。Enable表示闹钟与小时数据无,反之有关。
Alarm Mask Minutes:屏蔽分钟。Enable表示闹钟与分钟数据无,反之有关。
Alarm Mask Seconds:屏蔽秒。Enable表示闹钟与秒数据无,反之有关。
Alarm Sub Second Mask:屏蔽亚秒。Enable表示闹钟与亚秒数据无,反之有关。
Alarm Date Week Day Sel:日期形式。有Date和Weekday两种选项。选项Date表示用1-31表示日期。选择后者则表示用Monday到Sunday表示星期几
Alarm Date:日期。1-31或Monday-Sunday。

这里屏蔽日期什么含义,具体来说就是,我正常设置一个闹钟是哪一天哪一时哪一分哪一秒,如果屏蔽了日期,那也就是说我每天的固定时分秒都会响闹钟。屏蔽日期与小时,则说明,每小时的第几分钟第几秒都会响闹钟。以此类推。

Wake UP
Wake Up Clock:周期唤醒的时钟源。
Wake Up Counter:唤醒计数器的重载值。设定范围为0-65535。这个就是计数器到达设定值就触发中断,接着重新计数。如果这个值设置为0,则每个时钟周期中断一次。这里WakeUpClock设置为1Hz,WakeUpCounter设置为0,则表示每秒触发一次中断。

这里WakeUpClock的值是通过分频来获得的。

3.3 中断配置

这里中断这样设置,表明周期唤醒的优先级高于闹钟的中断。


4. 代码编写

实现我们想要的电平翻转其实就只需要对3个回调函数做一下处理就行。

每次来一个中断就翻转一下电平

C++ 复制代码
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
	HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
}
void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc)
{
	HAL_GPIO_TogglePin(BEEP_GPIO_Port,BEEP_Pin);
}	
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{
	HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
}

总结

这里WakeUp的输出到RTF_AF1的电平是高电平,可以用示波器抓一下看看。我这通过杜邦线引出来看LED,只能看到微弱的闪烁。

这篇博客主要是RTC的一些基本概念以及简单运用,和TIM定时器相似,不过多了很多东西。要对比学习。

相关推荐
TESmart碲视44 分钟前
HKS201-M24 大师版 8K60Hz USB 3.0 适用于 2 台 PC 1台显示器 无缝切换 KVM 切换器
单片机·嵌入式硬件·物联网·游戏·计算机外设·电脑·智能硬件
花落已飘2 小时前
STM32中实现shell控制台(shell窗口输入实现)
stm32·单片机·嵌入式硬件
花落已飘2 小时前
STM32中实现shell控制台(命令解析实现)
stm32·shell
没有钱的钱仔2 小时前
STM32低功耗模式全面指南
css·stm32·css3
牵牛老人4 小时前
Qt处理USB摄像头开发说明与QtMultimedia与V4L2融合应用
stm32·单片机·qt
宇钶宇夕5 小时前
针对工业触摸屏维修的系统指南和资源获取途径
单片机·嵌入式硬件·自动化
和风化雨6 小时前
stm32的三种开发方式
stm32·单片机·嵌入式硬件
kanhao1006 小时前
三态逻辑详解:单片机GPIO、计算机总线系统举例
单片机·嵌入式硬件
竹照煜_ysn9 小时前
STM32
stm32·单片机·嵌入式硬件
蓬荜生灰10 小时前
永磁无刷电机旋转原理
单片机·嵌入式硬件