声明:有文章仅用于记录自己的学习进度。
1.介绍
RTC(实时时钟)本质是一个独立的定时器,通过相关的配置可以提供时钟日历的功能。RTC模块和配置都在后备区域,所以器件的工作状态对于RTC没有影响。
为了RTC在即使开发板没有上电的时候也可以正常的工作,通常在开发板的后背区域会加上一块纽扣电池,只有主电源和纽扣电池都没有电,RTC才会停止工作。RTC的数据保存在属于RTC的备份域中,如果主电源VDD和VBAT都掉电,备份域中的数据将会丢失。而在备份域中还有一个42个16位的寄存器可以在VDD掉点的情况下保存用户程序的数据,系统复位或者电源复位的时候这些数据也不会被复位。所以会用这个BKP区域来保存RTC的校验值或者记录一些重要的数据。
RTC的本质是一个32位的一个计数器(向上计数),时钟来源分为三种,分别为高速外部时钟的128分频(HSE/128)、低速内部时钟LSI以及低速外部时钟LSE。因为前两个时钟会受到主电源掉电的影响,RTC通常都是用LSE即低速外部时钟时钟。频率为32768HZ。
PS:主电源有效时,RTC还可通过相关配置闹钟时间使STM32退出待机模式。
2.学习所感
RTC的学习过程中重点需要学习的就是它的程序框图的设计和运作流程,知道了程序框图才可以使用的得心应手,整体的框图还是比较的简单,多梳理几次即可。
首先外部时钟进入备份域的预分频器后,预分频器将外部时钟的频率分频,然后将其作为RTC的频率,这个实验中使用的俄式外部低速时钟,分频系数位32768,也就是1HZ每次1s,也就是说RTC_CNT的数值每秒加1。
3.配置过程
RTC和备份区域挂接在APB1总线上,通过头文件查找即可找到PWR和BKP文件。RTC后备寄存器有写保护的功能,想要对RTC后备寄存器进行写访问的话必须要先使能写访问(在STM32中的PWR源文件中);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟
PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问
开启写功能过后要进行备份区域的复位,但是并不是每次都需要对备份区域进行复位的,而是要先判断后备区域是否已经被复位了,如果已经复位自然没有必要再进行复位了。已经复位过了再复位的话,之前的数据会丢失。
if (BKP_ReadBackupRegister(BKP_DR1) != 0xA0A0) //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎
{
BKP_DeInit(); //复位操作
}
之后选择并开启RTC的时钟LSE(RCC源文件中)。
RCC_LSEConfig(RCC_LSE_ON);
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //设置RTC时钟(RTCCLK),选择LSE作为RTC时钟
RCC_RTCCLKCmd(ENABLE); //使能RTC时钟
设置分频系数,等待RTC的寄存器的操作完成。同步之后再设置秒中断,再开启RTC的允许配置位,设置时间,进入配置模式。
RTC_EnterConfigMode();// 允许配置
RTC_SetPrescaler(32767); //设置RTC预分频的值
操作完成过后再退出RTC的配置模式。
RTC_ExitConfigMode(); //退出配置模式
PS:时间的配置需要将时间转换成秒送入到计数器当中去。
转换的公式为 数值 = 时*3600+分*60+秒再转换成十六进制送入。
此时就完成了对于RTC的初始化。
再使用库函数相应函数对其进行标识位的写入,下次就不需要再进行初始化了。
BKP_WriteBackupRegister(BKP_DR1, 0XA0A0); //向指定的后备寄存器中写入用户程序数据
RTC初始化代码
u8 RTC_Init(void)
{
//检查是不是第一次配置时钟
u8 temp=0;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟
PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问
if (BKP_ReadBackupRegister(BKP_DR1) != 0xA0A0) //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎
{
BKP_DeInit(); //复位备份区域
RCC_LSEConfig(RCC_LSE_ON); //设置外部低速晶振(LSE),使用外设低速晶振
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET&&temp<250) //检查指定的RCC标志位设置与否,等待低速晶振就绪
{
temp++;
delay_ms(10);
}
if(temp>=250)return 1;//初始化时钟失败,晶振有问题
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //设置RTC时钟(RTCCLK),选择LSE作为RTC时钟
RCC_RTCCLKCmd(ENABLE); //使能RTC时钟
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_WaitForSynchro(); //等待RTC寄存器同步
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_EnterConfigMode();// 允许配置
RTC_SetPrescaler(32767); //设置RTC预分频的值
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_Set(2017,3,22,17,34,55); //设置时间
RTC_ExitConfigMode(); //退出配置模式
BKP_WriteBackupRegister(BKP_DR1, 0XA0A0); //向指定的后备寄存器中写入用户程序数据
}
else//系统继续计时
{
RTC_WaitForSynchro(); //等待最近一次对RTC寄存器的写操作完成
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
}
RTC_NVIC_Config();//RCT中断分组设置
RTC_Get();//更新时间
return 0; //ok
}