×
单片机 > 单片机程序设计 > 详情

STM32笔记(五)RTC的初始化

发布时间:2020-06-22 发布时间:
|
这次是RTC的笔记:)
RTC这东西晕晕的,因为一个模块涉及到了RTC,BKP,RCC多个模块,之间的关系让人有点模糊
入门的知识请大家看手册,我来总结:
总之,RTC只是个能靠电池维持运行的32位定时器over!
所以,使用时要注意以下问题:
1. 上电后要检查备份电池有没有断过电。如何检查? 恩,RTC的示例代码中已经明示:
   往备份域寄存器中写一个特殊的字符,备份域寄存器是和RTC一起在断电下能保存数据的。
   上电后检查下这个特殊字符是否还存在,如果存在,ok,RTC的数据应该也没丢,不需要重新配置它
   如果那个特殊字符丢了,那RTC的定时器数据一定也丢了,那我们要重新来配置RTC了
   这个过程包括时钟使能、RTC时钟源切换、设置分频系数等等,这个可以参考FWLibexampleRTCCalendar的代码
   在我的这个实例里,检查备份域掉电在Init.c的RTC_Conig()中,函数内若检测到BKP掉电,则会调用RTC_Configuration()
 
2. 因为RTC的一些设置是保存在后备域中的,so,操作RTC的设置寄存器前,要打开后备域模块中的写保护功能。
3. RTC设定值写入前后都要检查命令有没有完成,调用RTC_WaitForLastTask();
 
具体的RTC初始化代码如下:
////////////////////////////////////////////////////////////////////////////////
// RTC时钟初始化!
////////////////////////////////////////////////////////////////////////////////
 
void RTC_Configuration(void)
{
    //启用PWR和BKP的时钟(from APB1)
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
 
    //后备域解锁
    PWR_BackupAccessCmd(ENABLE);
 
    //备份寄存器模块复位
    BKP_DeInit();
 
    //外部32.768K其哟偶那个
    RCC_LSEConfig(RCC_LSE_ON);
    //等待稳定
    while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
    //RTC时钟源配置成LSE(外部32.768K)
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
    //RTC开启
    RCC_RTCCLKCmd(ENABLE);
    //开启后需要等待APB1时钟与RTC时钟同步,才能读写寄存器
    RTC_WaitForSynchro();
    //读写寄存器前,要确定上一个操作已经结束
    RTC_WaitForLastTask();
    //设置RTC分频器,使RTC时钟为1Hz
    //RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1)
    RTC_SetPrescaler(32767);
    //等待寄存器写入完成
    RTC_WaitForLastTask();
 
//使能秒中断
    RTC_ITConfig(RTC_IT_SEC, ENABLE);   
 
    //等待写入完成
    RTC_WaitForLastTask();
 
    return;
}
 
 
void RTC_Config(void)
{
    //我们在BKP的后备寄存器1中,存了一个特殊字符0xA5A5
    //第一次上电或后备电源掉电后,该寄存器数据丢失,
    //表明RTC数据丢失,需要重新配置
    if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
    {
        //重新配置RTC
        RTC_Configuration();
        //配置完成后,向后备寄存器中写特殊字符0xA5A5
        BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
    }
    else
    {
 
//若后备寄存器没有掉电,则无需重新配置RTC
        //这里我们可以利用RCC_GetFlagStatus()函数查看本次复位类型
        if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
        {
            //这是上电复位
        }
        else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
        {
            //这是外部RST管脚复位
        }
        //清除RCC中复位标志
        RCC_ClearFlag();
 
        //虽然RTC模块不需要重新配置,且掉电后依靠后备电池依然运行
        //但是每次上电后,还是要使能RTCCLK???????
        //RCC_RTCCLKCmd(ENABLE);
        //等待RTC时钟与APB1时钟同步
        //RTC_WaitForSynchro();
 
        //使能秒中断
        RTC_ITConfig(RTC_IT_SEC, ENABLE);
        //等待操作完成
        RTC_WaitForLastTask();
    }
 
#ifdef RTCClockOutput_Enable
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
 
    
    PWR_BackupAccessCmd(ENABLE);
 
    
    BKP_TamperPinCmd(DISABLE);
 
    
    BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);
#endif
 
    return;
}
 
关键字:STM32  RTC  初始化 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
采用AT89C2051的数字可调稳压电源单片机源程序