STM32 RTC应用 程序死在RTC_WaitForSynchro()函数中 晶振已经起振

2019-12-31 19:17发布

已经使用了6pF的电容,且死机后测晶振管脚有32K波形。

出现的现象:
程序第一次上电时会配置RTC(RTC未配置过),此时程序正常运行。
当再次复位后,程序检查到RTC已经被配置过,执行 RTC_WaitForSynchro(); 函数,等待RTC时钟和中线时钟同步。程序就死在这个函数中。

很是疑惑。晶振都起振了,为什么会死在这里呢?
估计是我什么地方没有弄对,请大家指点下!

先谢过各位。

-----------------------------------------------------------------------------------

上电执行的初始化函数如下:
  1. void hal_rtc_init(void)
  2. {
  3.   uint32_t TempCnt = 0;
  4.   if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
  5.   {
  6.     /* Backup data register value is not correct or not yet programmed (when
  7.        the first time the program is executed) */
  8.     hal_debug_printf("RTC not yet configured.... ");

  9.     /* RTC Configuration */
  10.     hal_rtc_configuration();

  11.     TempCnt = ap_time_date2sec(&g_SysTime);

  12.     hal_rtc_timeset(TempCnt);

  13.     BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
  14.   }
  15.   else
  16.   {
  17.     /* Check if the Power On Reset flag is set */
  18.     if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
  19.     {
  20.       hal_debug_printf("Power On Reset occurred.... ");
  21.     }
  22.     /* Check if the Pin Reset flag is set */
  23.     else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
  24.     {
  25.       hal_debug_printf("External Reset occurred.... ");
  26.     }

  27.     hal_debug_printf("No need to configure RTC.... ");
  28.     /* Wait for RTC registers synchronization */
  29.     RTC_WaitForSynchro();

  30.     ap_time_sec2date(RTC_GetCounter(),&g_SysTime);//根据RTC计数器得到目前系统时间

  31.     /* Enable the RTC Second */
  32.     RTC_ITConfig(RTC_IT_SEC, ENABLE);

  33.     /* Wait until last write operation on RTC registers has finished */
  34.     RTC_WaitForLastTask();
  35.   }

  36. #ifdef RTCClockOutput_Enable
  37.   /* Enable PWR and BKP clocks */
  38.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  39.   /* Allow access to BKP Domain */
  40.   PWR_BackupAccessCmd(ENABLE);

  41.   /* Disable the Tamper Pin */
  42.   BKP_TamperPinCmd(DISABLE); /* To output RTCCLK/64 on Tamper pin, the tamper
  43.                                  functionality must be disabled */

  44.   /* Enable RTC Clock Output on Tamper Pin */
  45.   BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);
  46. #endif

  47.   /* Clear reset flags */
  48.   RCC_ClearFlag();

  49. }
复制代码RTC的配置函数如下:
  1. u8 hal_rtc_configuration(void)
  2. {
  3.         u8 Temp=0;
  4.   
  5.   /* Enable PWR and BKP clocks */
  6.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  7.   /* Allow access to BKP Domain */
  8.   PWR_BackupAccessCmd(ENABLE);

  9.   /* Reset Backup Domain */
  10.   BKP_DeInit();
  11.   #warning 将外设BKP的全部寄存器重设为缺省值,该操作需要视应用情况而定

  12.   /* Enable LSE */
  13.   RCC_LSEConfig(RCC_LSE_ON);
  14.   /* Wait till LSE is ready */
  15.   while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  16.   {
  17.     Temp++;
  18.     delay_ms(10);
  19.   }
  20.   if(Temp>=250)return 1;//初始化时钟失败,晶振有问题     

  21.   /* Select LSE as RTC Clock Source */
  22.   RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

  23.   /* Enable RTC Clock */
  24.   RCC_RTCCLKCmd(ENABLE);

  25.   /* Wait for RTC registers synchronization */
  26.   RTC_WaitForSynchro();

  27.   /* Wait until last write operation on RTC registers has finished */
  28.   RTC_WaitForLastTask();

  29.   /* Enable the RTC Second */
  30.   RTC_ITConfig(RTC_IT_SEC, ENABLE);

  31.   /* Wait until last write operation on RTC registers has finished */
  32.   RTC_WaitForLastTask();

  33.   /* Set RTC prescaler: set RTC period to 1sec */
  34.   RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */

  35.   /* Wait until last write operation on RTC registers has finished */
  36.   RTC_WaitForLastTask();
  37.   
  38.   return 0;
  39. }
复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
22条回答
nicholasdlut
1楼-- · 2020-01-01 14:45
问题还是没有解决
156397226
2楼-- · 2020-01-01 18:48
 精彩回答 2  元偷偷看……
skinzhan
3楼-- · 2020-01-01 22:50
gdmgb520 发表于 2012-6-6 08:53
解决了。
请看这里 http://www.elecbench.com/?p=849

LZ,链接打不开呀。可以详解一下怎么解决的吗?
mxh0506
4楼-- · 2020-01-02 02:38
我来转贴:
不论是否需要配置RTC寄存器,每次系统复位都需要执行如下操作:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);
RCC_RTCCLKCmd(ENABLE);

leavic
5楼-- · 2020-01-02 08:12
请乖乖的使用6pF晶振+8pF或10pF电容。
gdmgb520
6楼-- · 2020-01-02 08:49
skinzhan 发表于 2012-8-28 11:56
LZ,链接打不开呀。可以详解一下怎么解决的吗?

链接目前正常,欢迎访问我的博客 www.elecbench.com

该文内容如下:
----------------------------------------------------------------------------------
出现的现象:使用野火的RTC例程,在软件仿真时如果不需要配置,则程序会死在 RTC_WaitForSynchro() 函数中。而下载到硬件上时,有时候可以跑,有时候也会在该函数中死循环。

可能的原因:
首先,一定要确认是否使能了对后备寄存器和RTC的访问。
系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操
作。执行以下操作将使能对后备寄存器和RTC的访问:
● 设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
● 设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问
PWR_BackupAccessCmd(ENABLE);
另外还要使能RTC时钟 RCC_RTCCLKCmd(ENABLE); 虽然该函数的说明中说只在RCC_RTCCLKConfig()函数调用之后才能调用,但是实际上如果不调用该函数,仿真时就会在 RTC_WaitForSynchro() 函数中死循环,等待RTC时钟同步。
也就是说,不论是否需要配置RTC寄存器,每次系统复位都需要执行如下操作:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);
RCC_RTCCLKCmd(ENABLE);

其次,STM32的RTC对外部LSE要求比较高,最好使用负载电容为6pF的晶振。在芯片的DataSheet中有明确的说明,不能使用12.5pF的晶振。“ To avoid exceeding the maximum value of CL1 and CL2 (15 pF) it is strongly recommended to use a resonator with a load capacitance CL≤ 7 pF. Never use a resonator with a load
capacitance of 12.5 pF.”

一周热门 更多>