STM32处理器 RTC分析
来源:互联网 发布:冯提莫用什么软件唱歌 编辑:程序博客网 时间:2024/06/08 16:25
前言:
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);
//有写入函数必然会有读函数,关于这个应用的解释可以在上面的备份寄存器中找到解释;
补充:以上程序步骤中如果还要添加闹钟中断,秒中断,溢出中断,均可以添加;
下面为原子例程:
u8 RTC_Init(void){ u8 temp = 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) return 1; 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(); return 0; }
- STM32处理器 RTC分析
- STM32处理器定时器分析
- STM32处理器输入捕获分析
- stm32 -- RTC
- STM32 RTC
- STM32 RTC
- STM32->RTC
- stm32 RTC
- STM32 RTC小结
- STM32 RTC设置 (转)
- stm32 rtc万年历
- STM32 RTC时钟
- STM32的RTC
- STM32 RTC小结
- ARM-STM32-RTC/ADC
- stm32 RTC时间
- stm32的RTC
- STM32 RTC 读写不正确
- MySQL 加锁处理分析
- jQuery系列之事件(二)
- 【Some】【Other】程序员的忧虑
- 第一章 Shiro简介——跟我学习springmvc shiro mybatis
- linux基础学习笔记
- STM32处理器 RTC分析
- jQuery事件补充enter和over的区别
- 一位资深程序员大牛给予Java初学者的学习路线建议
- shuoj 1086 字符串+进制改变
- 遇到跑批时快时慢、或一直变慢,作为运维DBA或开发的你,如何下手?
- Qt5集成到VS2015
- 《Python核心编程》学习笔记
- Java 代码性能优化总结
- 天朝墙google facebook instagram的一些感慨