[应用相关] STM32 RTC的初始化(搬运)

[复制链接]
1048|1
 楼主| Luis德华 发表于 2015-9-29 22:05 | 显示全部楼层 |阅读模式
RTC只是个能靠电池维持运行的32位定时器over!
所以,使用时要注意以下问题:
1. 上电后要检查备份电池有没有断过电。如何检查? 恩,RTC的示例代码中已经明示:
  往备份域寄存器中写一个特殊的字符,备份域寄存器是和RTC一起在断电下能保存数据的。
  上电后检查下这个特殊字符是否还存在,如果存在,ok,RTC的数据应该也没丢,不需要重新配置它
  如果那个特殊字符丢了,那RTC的定时器数据一定也丢了,那我们要重新来配置RTC了
  这个过程包括时钟使能、RTC时钟源切换、设置分频系数等等,这个可以参考FWLib\example\RTC\Calendar的代码
  在我的这个实例里,检查备份域掉电在Init.c的RTC_Conig()中,函数内若检测到BKP掉电,则会调用RTC_Configuration()

2. 因为RTC的一些设置是保存在后备域中的,so,操作RTC的设置寄存器前,要打开后备域模块中的写保护功能。
3. RTC设定值写入前后都要检查命令有没有完成,调用RTC_WaitForLastTask();
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // RTC时钟初始化!
  3. ////////////////////////////////////////////////////////////////////////////////

  4. void RTC_Configuration(void)
  5. {
  6.     //启用PWR和BKP的时钟(from APB1)
  7.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  8.     //后备域解锁
  9.     PWR_BackupAccessCmd(ENABLE);

  10.     //备份寄存器模块复位
  11.     BKP_DeInit();

  12.     //外部32.768K其哟偶那个
  13.     RCC_LSEConfig(RCC_LSE_ON);
  14.     //等待稳定
  15.     while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);

  16.     //RTC时钟源配置成LSE(外部32.768K)
  17.     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

  18.     //RTC开启
  19.     RCC_RTCCLKCmd(ENABLE);

  20.     //开启后需要等待APB1时钟与RTC时钟同步,才能读写寄存器
  21.     RTC_WaitForSynchro();

  22.     //读写寄存器前,要确定上一个操作已经结束
  23.     RTC_WaitForLastTask();

  24.     //设置RTC分频器,使RTC时钟为1Hz
  25.     //RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1)
  26.     RTC_SetPrescaler(32767);


  27.     //等待寄存器写入完成
  28.     RTC_WaitForLastTask();

  29.     //使能秒中断
  30.     RTC_ITConfig(RTC_IT_SEC, ENABLE);   

  31.     //等待写入完成
  32.     RTC_WaitForLastTask();

  33.     return;
  34. }


  35. void RTC_Config(void)
  36. {
  37.     //我们在BKP的后备寄存器1中,存了一个特殊字符0xA5A5
  38.     //第一次上电或后备电源掉电后,该寄存器数据丢失,
  39.     //表明RTC数据丢失,需要重新配置
  40.     if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
  41.     {
  42.         //重新配置RTC
  43.         RTC_Configuration();
  44.         //配置完成后,向后备寄存器中写特殊字符0xA5A5
  45.         BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
  46.     }
  47.     else
  48.     {
  49.         //若后备寄存器没有掉电,则无需重新配置RTC
  50.         //这里我们可以利用RCC_GetFlagStatus()函数查看本次复位类型
  51.         if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
  52.         {
  53.             //这是上电复位
  54.         }
  55.         else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
  56.         {
  57.             //这是外部RST管脚复位
  58.         }
  59.         //清除RCC中复位标志
  60.         RCC_ClearFlag();

  61.         //虽然RTC模块不需要重新配置,且掉电后依靠后备电池依然运行
  62.         //但是每次上电后,还是要使能RTCCLK???????
  63.         //RCC_RTCCLKCmd(ENABLE);
  64.         //等待RTC时钟与APB1时钟同步
  65.         //RTC_WaitForSynchro();

  66.         //使能秒中断
  67.         RTC_ITConfig(RTC_IT_SEC, ENABLE);
  68.         //等待操作完成
  69.         RTC_WaitForLastTask();
  70.     }

  71. #ifdef RTCClockOutput_Enable
  72.    
  73.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  74.    
  75.     PWR_BackupAccessCmd(ENABLE);

  76.    
  77.     BKP_TamperPinCmd(DISABLE);

  78.    
  79.     BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);
  80. #endif

  81.     return;
  82. }


yiyigirl2014 发表于 2015-9-30 08:16 来自手机 | 显示全部楼层
受益匪浅,楼主分析很透彻
您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

370

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部