STM32F103 RTC使用

作者

QQ群:852283276
微信:arm80x86
微信公众号:青儿创客基地
B站:主页 https://space.bilibili.com/208826118

LSE Ready卡死

使用st-link下载器对板子供电,供电能力不够,导致外部LSE始终不能ready,但LSI可以。换外部电源供电之后,LSE也可以锁定。第二天测试,又卡死,不是电源供电问题,怀疑是LSE不起振,板子上晶振离单片机距离有点远,目前没有安装电池,测试不是没有按照电池的问题。Time_init函数加上如下初始化。

#if 1
  /* Enable LSE */
  RCC_LSEConfig(RCC_LSE_ON);
  /* Wait till LSE is ready */
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  {}

  /* Select LSE as RTC Clock Source */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
#else
	RCC_LSICmd(ENABLE);
	
  while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
  {}		
		
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
#endif

RTC_WaitForSynchro卡死

首先将标准库例子中RTC_Configuration中的下面三行代码放到上面Time_init中,如果使用LSI则LSI初始化也应放出来,可能是由于没有安装电池的原因。这里和Time_init初始化重复了一部分,是由于BKP_DeInit了(猜测),否则会有异常。

/**
  * @brief  Configures the RTC.
  * @param  None
  * @retval None
  */
void RTC_Configuration(void)
{
#if 0 /*move to top for RTC_WaitForSynchro dead*/
   /* Enable PWR and BKP clocks */
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

   /* Allow access to BKP Domain */
   PWR_BackupAccessCmd(ENABLE);
#endif
  /* Reset Backup Domain */
  BKP_DeInit();
  
#if 1
#if EN_RTC_LSE
  /* Enable LSE */
  RCC_LSEConfig(RCC_LSE_ON);
  /* Wait till LSE is ready */
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  {}

  /* Select LSE as RTC Clock Source */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
#else
  RCC_LSICmd(ENABLE);
	
  while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
  {}		
		
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
#endif
#endif
  /* Enable RTC Clock */
  RCC_RTCCLKCmd(ENABLE);

  /* Wait for RTC registers synchronization */
  RTC_WaitForSynchro();

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

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

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

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

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

}

void Time_init(void)
{
	/*Enables the clock to Backup and power interface peripherals    */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR,ENABLE);
	/*Allow access to Backup Registers*/
  PWR_BackupAccessCmd(ENABLE);
  
#if EN_RTC_LSE
  /* Enable LSE */
  RCC_LSEConfig(RCC_LSE_ON);
  /* Wait till LSE is ready */
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  {}

  /* Select LSE as RTC Clock Source */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
#else
  RCC_LSICmd(ENABLE);
	
  while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
  {}		
		
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
#endif
    
	/*delay_us(100);*//*delay because uart print error chars*/
	/*uart_printf("%s line%d\r\n", __FUNCTION__, __LINE__);*/
	if (BKP_ReadBackupRegister(BKP_DR1) != CONFIGURATION_DONE)
  {
    /* Backup data register value is not correct or not yet programmed (when
       the first time the program is executed) */
    /* RTC Configuration */
    uart_printf("RTC configured....\r\n");
    RTC_Configuration();
    uart_printf("Please Set time and date from shell\r\n");		
    BKP_WriteBackupRegister(BKP_DR1, CONFIGURATION_DONE);
  }
  else
  {
		delay_us(2000);
    /* Check if the Power On Reset flag is set */
    if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
    {
      uart_printf("Power On Reset occurred....");
    }
    /* Check if the Pin Reset flag is set */
    else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
    {
      uart_printf("External Reset occurred....");
    }
    uart_printf("No need to configure RTC....\r\n");
    /* Wait for RTC registers synchronization */
    RTC_WaitForSynchro();
    /* Enable the RTC Second */
    RTC_ITConfig(RTC_IT_SEC, ENABLE);
    /* Wait until last write operation on RTC registers has finished */
    RTC_WaitForLastTask();
  }
  /* Clear reset flags */
  RCC_ClearFlag();
	/* Check if how many days are elapsed in power down/Low Power Mode-
   Updates Date that many Times*/
  CheckForDaysElapsed();
  s_time_date.Month = BKP_ReadBackupRegister(BKP_DR2);
  s_time_date.Day = BKP_ReadBackupRegister(BKP_DR3);
  s_time_date.Year = BKP_ReadBackupRegister(BKP_DR4);
}

但并没有解决我的问题,怀疑是电路进入某种异常状态,虽然没有放后备电池,但总是检测到RTC已经配置,我更改CONFIGURATION_DONE的值,让RTC重新配置后,bug解除!!!

唤醒

使用LSE 32.768KHz时,CubeIDE配置默认即可,分频 = (127+1)*(255+1) = 32768,正好为1s,前一个7bit分频器,后一个是14bit分频器,LSI时钟 37K=(73+1)*(499+1)
RTC支持Standby模式唤醒,由于需要10min唤醒一次,使用RTC Alarm,使用RTC wakeup,唤醒的时间比较短,只有16bit的定时器。

负载电容

晶振 负载电容 匹配电容
电子电路学习笔记(16)——晶振电路的电容
STM32L0外接32768HZ晶振应该接多大的负载电容才合适

电容大了会跑慢,小了跑快,必须正好才行。
32768kHz_3215
一般12.pF负载电容的晶振,匹配电容选择22pF。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值