基于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定时器相似,不过多了很多东西。要对比学习。

相关推荐
萧技电创EIIA27 分钟前
基于stc12单片机的PID恒温烙铁设计
单片机·嵌入式硬件·pid过程控制
光子物联单片机2 小时前
STM32G474单片机开发入门(八)内部FLASH详解及读写实战
stm32·单片机·嵌入式硬件·mcu
BreezeJuvenile2 小时前
通用定时器_输入捕获介绍及案例实操
stm32·单片机·嵌入式硬件·输入捕获·通用定时器
时空自由民.3 小时前
无人机系统耗电,低功耗管理问题解决方法(chatgpt)
单片机·嵌入式硬件·无人机
时空自由民.3 小时前
无人机系统耗电,低功耗管理问题解决方法(腾讯元宝)
单片机·嵌入式硬件·无人机
清风6666664 小时前
基于单片机的双档输出数字直流电压源设计
单片机·mongodb·毕业设计·nosql·课程设计
牛马大师兄4 小时前
STM32独立看门狗IWDG与窗口看门狗WWDG知识梳理笔记
笔记·stm32·单片机·嵌入式硬件·嵌入式·看门狗
夜月yeyue4 小时前
STM32 Flash 访问加速器详解(ART Accelerator)
linux·单片机·嵌入式硬件·uboot·bootloard
A9better5 小时前
嵌入式开发学习日志37——stm32之USART
stm32·嵌入式硬件·学习
国科安芯9 小时前
ASP4644芯片低功耗设计思路解析
网络·单片机·嵌入式硬件·安全