当前位置:首页 > 单片机 > 单片机
[导读]前言:1.博客基于ARM Cortex-M3内核的STM32F103ZET6和标准3.5.0库;2.如有不足之处,还请多多指教一 RTC是什么?1. 从结构上讲就是一个独立的定时器;2. 从功能上来说就是为系统提供系统掉电不复位的日历时间;RTC分

前言:
1.博客基于ARM Cortex-M3内核的STM32F103ZET6和标准3.5.0库;
2.如有不足之处,还请多多指教

一 RTC是什么?
1. 从结构上讲就是一个独立的定时器;
2. 从功能上来说就是为系统提供系统掉电不复位的日历时间;


RTC分为两个完全能独立的部分:1. APB1接口;2. RTC核心;
功能:
(1)APB1总线连接APB1接口并负责驱动APB1接口,接口内部包含一组16位寄存器,可以通过APB1总线对其进行读写操作。
(2)RTC核心由RTC20位预分频模块和32位可编程计数器模块组成;
Ⅰ RTC预分频模块包含一个20位的可编程分频器RTC_DIV。预分频模块为32位计数器模块提供时基单元,这个很重要;预分频器内的是一递变(递减)的值,当递减结束时如果开启相应的中断,将会触发中断,并且RTC_PRL重装载寄存器将会将之前写入的分频值再次装载到预分频器;
Ⅱ 计数器(RTC_CNT)概念很好理解,当时基单元是1S时,计数器可以记录136年左右的时间,够用了;若配置并使能了RTC_ALR(闹钟寄存器),当RTC_CNT的值与其相等时,将会触发闹钟中断;

二 RTC的时钟源的选择

(1)从图片中可以看出有三个时钟源:
1. HSE的128分频
2. LSE (用的最多)
3. LSI

三 相关寄存器
(1)备份域控制寄存器RCC_BDCR

LSEON,LSEBYP,RTCSEL和RTCEN位都处于备份域,这些位在复位后处于写保护的状态,只有在电源控制寄存器PWR_CR中的DBP位置1后才能对这些位进行改动;
RTCEN:RTC时钟使能位;0:RTC关闭;1:RTC开启
RTCSEL[1:0]:RTC时钟源选择 00:无时钟,01:LSE振荡器(用的最多),10:LSI振荡器,11:HSE振荡器/128
LSEBYP:外部低速时钟振荡器旁路(旁路可以理解为开关,被旁路既是被关闭);0:LSE时钟未被旁路(关闭);1:LSE时钟被旁路(关闭);
LSEON:外部低速振荡器使能;0:外部32KHz振荡器关闭;1:外部32KHz振荡器开启;

(2)控制寄存器(高位)RTC_CRH

RTC_CRH是用来控制RTC的相关中断的
OWIE:允许溢出中断位; 0:屏蔽RTC_CNT溢出中断;1:使能RTC_CNT溢出中断;
ALRIE:允许闹钟中断; 0:屏蔽闹钟中断;1:使能闹钟中断;
SECIE:允许秒中断; 0:屏蔽秒中断;1:使能秒中断;

(3)控制寄存器(低位)RTC_CRL(重要)

RTOFF(只读):RTC操作; 0:上次对RTC寄存器的写操作仍在进行;1:上次对RTC寄存器的写操作已经完成;对RTC寄存器操作时,必须要完成一次写操作之后(RTOFF=1)才能进行下次写操作
CNF:配置标志(重要);在对ALR,DIV,CNT寄存器配置之前,必须先配置该位软件写1:进入如配置模式,对CNT,ALR,PRL进行赋值;0:退出配置模式(开始更新RTC寄存器);
RSF:寄存器同步标志;0:寄存器尚未同步;1:寄存器已经同步;
每当RTC_CNT和RTC_DIV由软件更新或清0时,此位由硬件置1;应用程序必须等待这位被硬件置1,以确保CNT,ALR,PRL已经被同步;
在APB1复位或APB1时钟停止后,此位必须由软件清0;
重要:由于APB1接口和RTC核心完全独立,处理器在复位,睡眠,停机环境下是继续工作的,但APB1接口停止了工作所以这里就出现了一个问题是:当处理器从复位睡眠停机情况下恢复过来的前一段时间,APB1接口和RTC核心还没有完成同步工作;此时不能读取RTC的值,不能对CRH/CRL进行配置,要等RSF=1后,才可以对RTC的值进行读取;

OWF:溢出标志; 0:CNT无溢出; 1:CNT溢出;
ALRF:闹钟标志: 0:CNT≠ALR,没有产生闹钟; 1:CNT≥ALR,闹钟产生;
SECF:秒标志; 0:RTC_DIV没有溢出;1:RTC_DIV溢出;

(4)RTC预分频装载寄存器RTC_PRLH(高)和RTC_PRLL(低)


这是两个寄存器(唉!搞不懂为什么要整两个,可能为后期分频系数增大做准备把)
分频公式为: Ftr_clk = Frtcclk/[19:0]+1
比如我们最常用的Frtc_clk = 32.768KHz ,([19:0]+1)=32768 ,代入得Ftr_clk = 1Hz = 1S;

(5)RTC预分频器余数寄存器RTC_DIVH(高)和RTC_DIVL(低)

(6)备份寄存器BKP
和其他寄存器不同,备份寄存器包含42个16位的寄存器(共84字节,中小容量STM芯片存储空间为20字节 );
功能:
1. 侵入检测;2. RTC校准;3. (常用)用BKP来存储RTC的校验值或者记录些重要的数据,但是这里不要误理解为是EEPROM,功能类似,但是这个所在备份区域一旦完全掉电,就GG了;
特性:(重要)
1. BKP处于备份域,当Vdd掉电时,仍然有Vbat来供电。
2. 在系统待机唤醒,系统复位,掉电复位时,备份域内的数据将不会被复位,但一旦这些情况出现,备份域和RTC都不能被访问了,这是为了保护这些情况发生时备份域和RTC的值不会被改变;这时需要下面操作才能继续访问:
Ⅰ 配置寄存器RCC_APB1ENR的PWREN位和BKPEN位来打开电源和后备接口电源;
Ⅱ 电源控制寄存器PWR_CR的DBP位来使能对后备寄存器和RTC的访问;

四 编程步骤
(1)使能电源时钟和备份区域时钟;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR " RCC_APB1Periph_BKP,ENABLE);
在上面解释备份寄存器中讲到的特性“Ⅰ”可以找到解释;

(2)取消备份区写保护;
PWR_BackupAccessCmd(ENABLE);
对备份区域写入保护是在每次复位后被使能,即复位后不能向备份区域写入数据或修改寄存器,RTC核心的属于备份区域,在进行时钟初始化的时候,不能对其写入数据是不合理的,所以必须要取消备份区写保护;在上面解释备份寄存器中讲到的特性“Ⅱ”可以找到解释;

(3)复位备份区;
BKP_DeInit();
在取消对备份区域的写保护完成后,备份区域可能还存在以前设置过的一些数据和配置;因为要重新配置,所以这里要初始化一下;

(4)开启外部低速振荡器
RCC_LSEConfig(RCC_LSE_ON); //配置RCC_BDCR的LSEON位,开启RTC常用的时钟源:LSE ;
特别注意:这个函数执行完毕后不能急着执行其他操作,因为是要启动外部晶振,所以需要一些时间;如果启动完成,备份域控制寄存器RCC_BDCR的LSERDY位将会被硬件置1;

(5)配置并使能RTC时钟源
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //配置RCC_BDCR的RTCSEL[1:0]位,三个时钟源,LSE最常用;
RCC_RTCCLKCmd(ENABLE); //配置RCC_BDCR的RTCEN位,启动RTC时钟
**特别注意:**RTC时钟源开启之后,需要等到时钟源RTC_CNT,ALR,PRL三个寄存器同步了,才能对RTC进行操作;
所以这里要等待一下:
RTC_WaitForSynchro(); //检测RTC_CRL的RSF位,知道同步完成,结束函数;

(6)配置RTC核心:分频和时钟;
Ⅰ RTC_EnterConfigMode(); //配置RTC_CRL的CNF位,允许配置
Ⅱ RTC_SetPrescaler( u32 ); //设置分频数 通常为32767
RTC_WaitForLastTask(); //等待分频数配置完成
Ⅲ RTC_Set(2009,12,2,10,0,55); //这个函数是自己写的;
Ⅳ RTC_ExitConfigMode(); //配置RTC_CRL的CNF位,禁止配置

(7)向备份区域写入完成时钟配置的信息;
BKP_WriteBackupRegister(BKP_DR1,0x5050);
//有写入函数必然会有读函数,关于这个应用的解释可以在上面的备份寄存器中找到解释;

补充:以上程序步骤中如果还要添加闹钟中断,秒中断,溢出中断,均可以添加;

下面为原子例程:

u8RTC_Init(void){u8temp=0;if(BKP_ReadBackupRegister(BKP_DR1)!=0x5050){RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);PWR_BackupAccessCmd(ENABLE);BKP_DeInit();RCC_LSEConfig(RCC_LSE_ON);while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET&&temp<250){temp++;delay_ms(10);}if(temp>=250)return1;RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);RCC_RTCCLKCmd(ENABLE);RTC_WaitForLastTask();RTC_WaitForSynchro();RTC_ITConfig(RTC_IT_SEC,ENABLE);RTC_WaitForLastTask();RTC_EnterConfigMode();RTC_SetPrescaler(32767);RTC_WaitForLastTask();RTC_Set(2009,12,2,10,0,55);RTC_ExitConfigMode();BKP_WriteBackupRegister(BKP_DR1,0x5050);}else{RTC_WaitForLastTask();RTC_ITConfig(RTC_IT_SEC,ENABLE);RTC_WaitForLastTask();}RTC_NVIC_Config();RTC_Get();return0;}

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

为增进大家对工业以太网的认识,本文将对工业以太网的原理、工业以太网的关键技术以及工业以太网要解决的问题予以介绍。

关键字: 以太网 工业以太网 指数

为增进大家对工业以太网的认识,本文将对工业以太网网络优势、工业以太网和IOLINK的区别予以介绍。

关键字: 以太网 工业以太网 指数

为增进大家对工业以太网的认识,本文将对工业以太网的优势、工业以太网缺点、工业以太网的维护予以介绍。

关键字:

Apr. 23, 2024 ---- 随着节能成为AI推理服务器(AI Inference Server)优先考量,北美客户扩大存储产品订单,带动QLC Enterprise SSD需求开始攀升。然而,目前仅Solidi...

关键字: SSD AI 服务器

为增进大家对二极管的认识,本文将对续流二极管、续流二极管的工作原理以及二极管在工业产品中的应用予以介绍。

关键字: 二极管 指数 续流二极管

通过本文,您将了解到二极管反接是否有电压以及二极管在电子电路中的应用。

关键字: 二极管 指数 稳压电路

为增进大家对二极管的了解,本文将对ESD二极管和TVS二极管之间的区别予以介绍。

关键字: ESD TVS 二极管 指数

为增进大家对嵌入式主板的认识,本文将对嵌入式主板以及嵌入式主板常见问题及其解决方法予以介绍。

关键字: 嵌入式 指数 主板

为增进大家对嵌入式系统的认识,本文将对嵌入式系统、嵌入式系统的特点予以介绍。

关键字: 嵌入式 指数 嵌入式系统

为增进大家对嵌入式的认识,本文将对嵌入式、嵌入式工作相关的内容予以介绍。

关键字: 嵌入式 指数 嵌入式技术
关闭
关闭