stm32定时器有什么功能(RTC及定时闹钟功能实现)
对于学习过51单片机的同学来说,一般使用RTC功能,都会使用51单片机 DS1302的方案,在STM32单片机中,因为STM32单片机自带RTC模块,所以我们只需要使用一个STM32即可,不需要外挂实时时钟芯片了。
RTC实时时钟简介"RTC"是Real Time Clock 的简称,意为实时时钟。
STM32提供了一个秒中断源和一个闹钟中断源,修改计数器的值可以重新设置系统当前的时间和日期。
STM32的RTC外设,实质是一个掉电后还能继续运行的定时器,通过配置,可以让它准确地每秒钟中断一次。
所谓掉电,是指电源VDD断开的情况下,为了RTC外设掉电可以继续运行,必须给STM32芯片通过VBAT引脚接上外部3.3V供电。
当主电源VDD有效时,由VDD给RTC外设供电。
当VDD掉电后,由VBAT给RTC外设供电。
无论由什么电源供电,RTC中的数据始终都保存在属于RTC的备份域中,如果主电源和VBAT都掉电,那么备份域中保存的所有数据都将丢失。(备份域除了RTC模块的寄存器,还有42个16位的寄存器可以在VDD掉电的情况下保存用户程序的数据,系统复位或电源复位时,这些数据也不会被复位)。
- 上图来自于《STM32中文参考手册》
备份寄存器是42个16位的寄存器,可用来存储84个字节的用户应用程序数据。他们处在备份域里,当VDD电源被切断,他们仍然由VBAT维持供电,数据不会丢失,所以我们可以使用这些寄存器预存一些运行状态信息。
比如我们可以在RTC初始化之后,对BKP_DR1寄存器写入一个值,比如0x5050,然后在 RTC_Init(void)函数开始处,先读取并判断BKP_DR1寄存器的值是否为0x5050,进而可以知道系统的RTC是否有VBAT外部电源维持供电。
STM32时钟系统
参考《STM32中文参考手册》中对STM32的时钟系统的详细说明。
由上图可知RTC的时钟源可以来源于3个渠道:
- 来自于低速外部时钟LSE,也就是外部的晶振,一般选用32.768KHz
- 来自于高速外部时钟HSE的128分频,即HSE/128
- 来自于低速内部时钟LSI
使用HSE分频时钟或者LSI的时候,在主电源VDD掉电的情况下,这两个时钟来源都会受到影响,因此没法保证RTC正常工作(在有自动校准功能并对时钟的精度要求不是很高的情况下,还是可以使用HSE分频时钟作为RTC时钟的),所以RTC一般都选用低速外部时钟LSE,晶振的频率为实时时钟模块中常用的32.768KHz,因为32768 = 2^15,分频容易实现1秒的时钟频率,所以被广泛应用到RTC模块。
在配置RTC模块的时钟时,把输入的32768Hz的RTCCLK进行32768分频得到实际驱动计数器的时钟TR_CLK = RTCCLK/37768 = 1Hz,计时周期为1秒,计时器在TR_CLK的驱动下计数,即每秒计数器RTC_CNT的值加1。
RTC时间设置RTC时间设置就是对RTC计数器寄存器RTC_CNT进行设置。
该寄存器由两个16位的寄存器RTC_CNTH和RTC_CNTL组成,总共32位,用来记录秒钟值。
理论上可以计算2^32 = 4,294,967,296 s,大约136年。
所以设置RTC时间或者获取RTC时间,就是设置RTC_CNT寄存器或者获取RTC_CNT寄存器的值。
所以封装的设置时钟的函数RTC_Set(),就是求得设定的时间与1970年1月1日 00:00:00之间的秒数,然后通过RTC_SetCounter()函数,写入RTC_CNT寄存器即可。
嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。
点击这里找小助理0元领取:加微信领取资料
注意
每次操作RTC_CNT时应该要使能PWR 和 BKP 时钟,允许访问BKP域,否则会操作失败。
/* Enable PWR and BKP clocks*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
/* Wait until last write operation on RTC registers has finished*/
RTC_WaitForLastTask();
/* 修改当前RTC计数寄存器内容 */
RTC_SetCounter(Cnt);
/* Wait until last write operation on RTC registers has finished*/
RTC_WaitForLastTask();
在实际应用中,我们有时会用到定时闹钟功能,我们简单的可以在main函数的while循环中,通过比对当前时间和设定时间值是否相等进行判断是否定时时间到,比如:
//主循环
while(1)
{
times ;
if(t!=calendar.sec)
{
t=calendar.sec;
NowHour = calendar.hour;
NowMinute = calendar.min;
NowSecond = calendar.sec;
if(NowHour==AlarmHour&&NowMinute==AlarmMinute&&NowSecond==AlarmSecond)
{
//执行预定动作
}
}
}
除了上面的方法外,我们还可以使用RTC的闹钟中断来实现。
- 使能RTC_IT_ALR中断,并设置闹钟时间:
- 闹钟中断响应
在主电源VDD有效的情况下(待机),RTC还可以配置闹钟事件使STM32退出待机模式。
结果展示RTC_Init(void)函数中,设置初始化时间如下:
程序会在串口助手中,每秒钟输出一条时间信息,40S后执行一次闹钟中断。
好了,今天的文章到这里就结束了,希望对你有帮助,我们下期见。
原文链接:https://mp.weixin.qq.com/s/0oLpg9Kjlfo4Z9q0s6lZuQ
转载自:嵌入式从0到1
文章来源于程序员小哈、嵌入式从0到1
原文链接:https://mp.weixin.qq.com/s/hjhOedO9prE2tmLH4zO9vA?scene=25#wechat_redirect
版权声明:本文来源网络,免费传达知识,版权归原作者所有,如涉及作品版权问题,请联系我进行删除。
,免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com