当前位置:首页 > 嵌入式 > 玩转嵌入式
[导读]对于学习过51单片机的同学来说,一般使用RTC功能,一般都会使用51单片机+DS1302的方案,在STM32单片机中,因为STM32单片机自带RTC模块,所以我们只需要使用一个STM32即可,不需要外挂实时时钟芯片了。


对于学习过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寄存器即可。

注意:

每次操作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();

RTC闹钟

在实际应用中,我们有时会用到定时闹钟功能,我们简单的可以在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的闹钟中断来实现。

  1. 使能RTC_IT_ALR中断,并设置闹钟时间:
  1. 闹钟中断响应


在主电源VDD有效的情况下(待机),RTC还可以配置闹钟事件使STM32退出待机模式。

结果展示

RTC_Init(void)函数中,设置初始化时间如下:

程序会在串口助手中,每秒钟输出一条时间信息,40S后执行一次闹钟中断。

STM32串口发送数据和接收数据方式总结!

STM32配置SPI通讯功能

还在敲代码? 来看看如何自动生成"状态机"代码

SPI怎么玩?搞懂时序,运用自如

什么是DMA? STM32如何配置DMA?

STM32基础分析——PWM配置

STM32单片机:独立看门狗、窗口看门狗的配置



免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭