历史上的今天
返回首页

历史上的今天

今天是:2025年02月26日(星期三)

正在发生

2020年02月26日 | stm32实时时钟——RTC

2020-02-26 来源:eefocus

对于单片机转ARM的同学来说,RTC可能比较少接触。提到实时时钟,更经常想到的是DS1302。当然,在STM32里,自己一个CPU已经足够,不需要DS1302。


实际上,RTC就只一个定时器而已,掉电之后所有信息都会丢失,因此我们需要找一个地方来存储这些信息,于是就找到了备份寄存器。因为它掉电后仍然可以通过纽扣电池供电,所以能时刻保存这些数据。我们在本期教程中将详细讲述RTC原理及例程,以引导大家顺利进入RTC的世界。


1.STM32的RTC模块


RTC模块之所以具有实时时钟功能,是因为它内部维持了一个独立的定时器,通过配置,可以让它准确地每秒钟中断一次。下面就来看以下它的组成结构。


1.1RTC的组成


RTC由两个部分组成:APB1接口部分以及RTC核心部分(感觉说了等于没说,因为任何模块都会有接口部分和它自己的核心部分。请注意,权威的STM32系列手册是这么说的?)。笔者猜想原因可能是STM32所有的外设默认时钟无效,使用某个外设时,再开启时钟,用这样的方式来降低功耗。这里的RTC,APB1接口由APB1总线时钟来驱动。为了突出时钟吧?不过据说APB1接口部分还包括一组16位寄存器。


RTC核心部分又分为预分频模块和一个32位的可编程计数器。前者可使每个TR_CLK周期中RTC产生一个秒中断,后者可被初始化为当前系统时间。此后系统时间会按照TR_CLK周期进行累加,实现时钟功能。


1.2对RTC的操作


我们对RTC的访问,是通过APB1接口来进行的。注意,APB1刚被开启的时候(比如刚上电,或刚复位后),从APB1上读出来的RTC寄存器的第一个值有可能是被破坏了的(通常读到0)。这个不幸,STM32是如何预防的呢?我们在程序中,会先等待RTC_CRL寄存器中的RSF位(寄存器同步标志)被硬件置1,然后才开始读操作,这时候读出来的值就是OK的。


那么对RTC寄存器的写操作会不会有类似的情况呢?对于写操作,我们只要注意,每一次写操作,必须确保在前一次写操作完成后进行。这个“确保”,


是通过查询RTC_CR寄存器中的RTOFF状态位,判断RTC寄存器是否处于更新中。只有当RTOFF状态位是1,才可以写RTC寄存器。


2.RTC的编程


RTC的例程,主要是设置RTC时钟,使得其在超级终端上显示出当前的时钟。这个时钟的显示是“不停地走”。而且掉电后,重新上电,时钟仍然在走,仍然显示当前的时间。当然,如果感兴趣,您可以让它在LCD上显示——那就是一个名副其实的电子钟了。


编程的时候,首先要注意备份寄存器BKP_DR1,它做了一件关键的事情:判断RTC是否已经被设置过。因为RTC跟其他计时器不同,它是使用纽扣电池单独供电工作,所以它不会每次上电或者复位都被重置。判断RTC是否已经被设置过,可以决定当前是否需要去设置RTC。如果刚安装电池,第一次上电,自然需要去设置。否则的话,我们只要让它显示当前时钟即可。


当第一次使用RTC的时候,可以参考手册。这里对第一次配置需要做的工作进行了总结:


1、打开电源管理和备份寄存器时钟。注意,一定要打开备份寄存器的时钟。我们正是通过在备份寄存器写固定的数据来判断芯片是否第一次实用RTC,从而在系统运行RTC时提示配置时钟的。


2、使能RTC和备份寄存器的访问(复位默认是关闭的,以防止可能存在的意外的写操作。)。


3、选择外部低速晶体为RTC时钟,并使能时钟。笔者当初调试RTC的时候,犯了一个低级错误:由于没有定义如下:#defineRTCClockSource_LSE


导致程序一直停留在这里:/WaittillLSEisready/


while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET)


{


}


希望大家看完本教程后,能避免这个错误。


4、使能秒中断,程序里在秒中断里置位标志位来通知主程序显示时间数据,同时在32位计数器到23:59:59时清零;


5、设置RTC预分频器值产生1秒信号计算公式fTR_CLK=fRTCCLK/(PRL+1),我们设置32767来产生秒信号。


我们再次强调:所有在对RTC寄存器操作之前都要判断读写操作是否完成,即内部是否有读写操作。


下面来看代码:/SystemClocksConfiguration/RCC_Configuration();


/NVICconfiguration/


NVIC_Configuration();/ConfiguretheGPIOs/GPIO_Configuration();


/ConfiguretheUSART1/


USART_Configuration();


以上四个函数调用,虽然最平常不过,但是还是要引起大家的关注。特别是中断NVIC_Configuration();以及USART_Configuration();,希望大家仔细查阅具体的函数实现。


与本期教程有关系第一个要点,就是时钟,为避免遗漏,笔者将其代码放在第一位:RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_PWR,ENABLE);


接着我们读取备份寄存器BKP_DR1中的值来判断是否是第一次上电,如果不是则直接显示时钟,否则进行时间设置。当BKP_DR1的值不为0xAAAA,说明是第一次上电,此时需要对RTC进行初始化。注意初始化的实现函数RTC_Configuration();,为什么那么写,请参考我们之前给出的“第一次使用RTC的配置工作总结”,然后进行时钟设置。注意,因为我们需要进行写操作,所以根据固件库手册,要先调用RTC_WaitForLastTask(),等待标志位RTOFF被设置,保证在前一次写操作结束后才能进行。调用RTC_SetCounter(Time_Regulate());,将计数值写入RTC计数器。


由于后面要通过BKP_WriteBackupRegister()函数对BKP_DR1写操作,因此之前还需要进行一次RTC_WaitForLastTask(),这样,对时间的设置就完成了。剩下的代码,比较简单,主要是注意如下:


RTCCount=RTC_GetCounter();//获得计数值并计算当前时钟/Computehours/


THH=RTCCount/3600;/Computeminutes/


TMM=(RTCCount%3600)/60;/Computeseconds/


TSS=(RTCCount%3600)%60;


这是通过RTC_GetCounter();函数获取计数值,然后把这个计数值分别用小时、分钟、秒来表示的过程。最后还需要调用printf函数把它显示出来。

推荐阅读

史海拾趣

GuangDong Province MengCo Semiconductor Co., Ltd公司的发展小趣事
选择合适的制动电阻型号和容量,确保在制动过程中能够有效散热,避免过热。
汇顶科技(GOODiX)公司的发展小趣事
选用质量可靠、性能稳定的元器件是确保电路可靠性的基础。
BTCPower公司的发展小趣事

BTCPower公司自成立以来,一直致力于研发高效能、低能耗的电源管理芯片。经过数年的努力,公司成功开发出了一款具有革命性的芯片,能够在保证性能的同时,显著降低电子设备的能耗。这一技术突破迅速吸引了市场的关注,BTCPower的产品开始被广泛应用于智能手机、平板电脑等消费电子产品中,公司因此获得了巨大的商业成功。

协顺电子(Finecables)公司的发展小趣事

经过多年的发展,协顺电子已经成为中国电子连接器行业的领军企业之一。展望未来,公司将继续坚持“以顾客为中心”的经营理念,不断提升产品质量和技术水平;同时,公司也将积极探索新的业务领域和市场机会,推动公司的持续发展。此外,协顺电子还将加强与国际知名企业的合作与交流,共同推动电子行业的发展和进步。

请注意,以上故事框架仅供参考,具体的故事内容需要根据协顺电子(Finecables)公司的实际情况和发展历程进行创作和补充。

Analog Microwave Design公司的发展小趣事

Analog Microwave Design公司一直注重企业文化的建设和传承。公司倡导创新、务实、合作的企业精神,鼓励员工敢于挑战、勇于创新。同时,公司还注重员工的培训和发展,为员工提供了良好的职业晋升通道和学习机会。这种积极向上的企业文化不仅激发了员工的工作热情和创新精神,还为公司的长期发展提供了有力保障。

以上五个故事分别从初创时期的挑战与机遇、技术创新的突破、国际化战略的实施、产品线的丰富与完善以及企业文化的建设与传承等方面,展现了Analog Microwave Design公司在电子行业发展的历程和成就。这些故事不仅反映了公司的成长轨迹,也体现了公司在面对市场变化和技术挑战时所采取的积极态度和应对策略。

Emerson Embedded Power公司的发展小趣事

作为一家具有社会责任感的企业,Emerson Embedded Power积极参与公益事业和社会活动。该公司通过捐赠资金、物资和技术支持等方式,帮助贫困地区的学校和社区改善基础设施和教育条件。同时,公司还积极倡导员工参与志愿服务活动,为社会贡献爱心和力量。

请注意,以上故事是基于Emerson Embedded Power在电子行业中的一般发展情况和特点而编写的概述性故事框架,并非具体的、详细的发展故事。如果需要更详细的信息或故事,建议直接查阅该公司的官方资料或相关新闻报道。

问答坊 | AI 解惑

安规相关资料下载

  顶一下谢谢   还有 安规的基本准则是:   产品在设计和生产中应该避免以下危险的产生: 1触电和能量的危险 2火灾 3热的危险 4机械危险 5辐射和化学危险        …

查看全部问答>

请问如何在EVC应用程序中获得平台信息

我的问题是这样的: 在不同平台中共用一段代码,在代码中通过宏定义,选择编译不同的程序。如: #ifdefine PLATFORM1     #include \"platform1.h\" #elif PLATRORM2    #include \"platform2.h\" #endif 然后我在程序 ...…

查看全部问答>

usb传输速率

wince 设备支持全速模式,但不支持高速模式,能和USB2.0兼容,但是,当设备连接上pc,进入存储(即设备当作u盘)时 设备的usb驱动设置为全速模式,但是实际COPY 文件的时候速度只有0.5Byte左右,按道理理论有12/8=1.5Byte,请问怎 样能提高呢。 ...…

查看全部问答>

求教wince5.0的USB Function驱动问题!

    请问wince5.0的usb function controller驱动是怎么被加载的?在Ufnmdd.cpp中的UFN_Init等接口函数怎么被调用执行?在source文件中利用Ufnmdd.cpp只生成了个usbmddbase.lib库而没有生成DLL,在最终的image中也没有打包进去,那怎么样才 ...…

查看全部问答>

TL431做基准源的问题

请问图中两个电路,对输出而言有什么区别呢?我现在需要的是10V的基准源。 图中的做法是用:3K电阻和1K电阻的比值+1=4,然后4×2.5V=10V 但是5V输入和15V输入难道就没区别了?不太明白...恳请赐教~~…

查看全部问答>

编程添加标准33600bps调制解调器的问题

我的机器是winXP,用USB口虚拟了一个串口,连接了一个modem 正常情况下要在控制面板->电话和调制解调器 中添加一个标准33600bps调制解调器才能正常通信 现在我想自己写程序完成这个安装过程(不调用电话和调制解调器窗口) inf文件用的是C:\\WINDO ...…

查看全部问答>

团购工业模拟器件套装已收到,发帖感谢!

本帖最后由 dontium 于 2015-1-23 13:17 编辑 不错,可惜REF5025是标准版,封装都比较小 …

查看全部问答>

第八届中国国际国防电子展览会报道

      阿牛哥5月10日去北京展览馆参加第八届中国国际国防电子展览会。这次参加国防电子展的固态硬盘供应商 连接器制造商 射频芯片供应商很多 智能视频监控方案提供商也很多 还有几家高校的雷达研究所产品也很有特色。 &n ...…

查看全部问答>

很好的模拟电路资料大全--值得收藏

放大器是一种三端电路,其中必有一个端是输入和输出的共同“地”端,如果这个共“地”端接于发射极的,称为共射电路,接于集电极的,称为共集电路,接于基极的,称为共基电路,这三种有不同的性能. …

查看全部问答>