[STM32F1] STM32超低功耗进阶之RTC

[复制链接]
1335|24
 楼主| 抹茶妹妹 发表于 2022-9-29 23:29 | 显示全部楼层 |阅读模式
ST, tc
一,RTC 在低功耗中的作用

RTC 在低功耗场景的作用非常重要,先回顾一下前面讲到的唤醒的方式,以及他的局限性:
- 按键中断唤醒,如果设备在很难手动去触摸到按键的场景
- 异常中断唤醒, 如果外设的电压等降低发生的异常,将会导致系统无法继续工作下去
- 外设接收中断唤醒,如果本身是通讯的发起者,该如何唤醒
 楼主| 抹茶妹妹 发表于 2022-9-29 23:33 | 显示全部楼层
RTC 的优势:
- RTC 可以使用 LSE 来提供时钟源,而且这个时钟源也可以给到 MCU
- RTC 只需要电池供电就可以,功耗非常小
- RTC 可以设置闹钟周期性的唤醒 MCU,即使在关机模式下
RTC 具备其他唤醒无法替代的优点,几乎所有的低功耗设备,都会使用到 RTC 的功能。
 楼主| 抹茶妹妹 发表于 2022-9-29 23:44 | 显示全部楼层
二,RTC 的功能

    RTC 实现定时唤醒唤醒功能
  1.   hrtc.Instance = RTC;
  2.   hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  3.   hrtc.Init.AsynchPrediv = 127;
  4.   hrtc.Init.SynchPrediv = 255;
  5.   hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  6.   hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
  7.   hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  8.   hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  9.   if (HAL_RTC_Init(&hrtc) != HAL_OK)
  10.   {
  11.     Error_Handler();
  12.   }
  13.   if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x0FFF, RTC_WAKEUPCLOCK_RTCCLK_DIV16) != HAL_OK)
  14.   {
  15.     Error_Handler();
  16.   }
 楼主| 抹茶妹妹 发表于 2022-9-29 23:55 | 显示全部楼层
这里要注意 AsynchPrediv 和 AsynchPrediv 这两个数,RTC 的时间基准就是由这两个分频得来。一般来说 RTC 都是由 32.768k 的外部晶振来提供时钟源,这里计算可得:32.768k/(127+1)/(255+1) = 1 hz。
 楼主| 抹茶妹妹 发表于 2022-9-29 23:56 | 显示全部楼层
设置带有中断的定时器:

    唤醒时间基准:16 / 32.768k = ~0.5 ms
    唤醒的时间 :0.5 ms * 0x0FFF = ~2 s

上面的代码的功能就是实现,每间隔 2s 唤醒一次 MCU
 楼主| 抹茶妹妹 发表于 2022-9-29 23:57 | 显示全部楼层
RTC 实现闹钟
设置当前的时间
  sTime.Hours = 0x0;
  sTime.Minutes = 0x0;
  sTime.Seconds = 0x0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 0x1;
  sDate.Year = 0x0;

  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
 楼主| 抹茶妹妹 发表于 2022-9-29 23:58 | 显示全部楼层
设置闹钟
  1.   /** Enable the Alarm A
  2.   */
  3.   sAlarm.AlarmTime.Hours = 0x0;
  4.   sAlarm.AlarmTime.Minutes = 0x0;
  5.   sAlarm.AlarmTime.Seconds = 0x0;
  6.   sAlarm.AlarmTime.SubSeconds = 0x0;
  7.   sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  8.   sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
  9.   sAlarm.AlarmMask = RTC_ALARMMASK_NONE;
  10.   sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
  11.   sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
  12.   sAlarm.AlarmDateWeekDay = 0x1;
  13.   sAlarm.Alarm = RTC_ALARM_A;
  14.   if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
  15.   {
  16.     Error_Handler();
  17.   }
  18.   /* RTC interrupt Init */
  19.   HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 0, 0);
  20.   HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
 楼主| 抹茶妹妹 发表于 2022-9-29 23:58 | 显示全部楼层
RTC 的侵入检测
RTC 可以保证 MCU 在电池优电的情况下,备份域可以一直保存数据,如果检测到非法侵入可以销毁备份域的数据,以下代码由 cubemx 生成,未做验证
  1.   sTamper.Tamper = RTC_TAMPER_1;
  2.   sTamper.Trigger = RTC_TAMPERTRIGGER_LOWLEVEL;
  3.   sTamper.NoErase = RTC_TAMPER_ERASE_BACKUP_ENABLE;
  4.   sTamper.MaskFlag = RTC_TAMPERMASK_FLAG_DISABLE;
  5.   sTamper.Filter = RTC_TAMPERFILTER_2SAMPLE;
  6.   sTamper.SamplingFrequency = RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV32768;
  7.   sTamper.PrechargeDuration = RTC_TAMPERPRECHARGEDURATION_1RTCCLK;
  8.   sTamper.TamperPullUp = RTC_TAMPER_PULLUP_ENABLE;
  9.   sTamper.TimeStampOnTamperDetection = RTC_TIMESTAMPONTAMPERDETECTION_ENABLE;
  10.   if (HAL_RTCEx_SetTamper(&hrtc, &sTamper) != HAL_OK)
  11.   {
  12.     Error_Handler();
  13.   }
 楼主| 抹茶妹妹 发表于 2022-9-29 23:59 | 显示全部楼层
RTC 唤醒时间输出一个电平信号
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**RTC GPIO Configuration
    PB2     ------> RTC_OUT_ALARM
    */
    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF0_RTC_50Hz;

  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  hrtc.Init.AsynchPrediv = 127;
  hrtc.Init.SynchPrediv = 255;
  hrtc.Init.OutPut = RTC_OUTPUT_WAKEUP;
  hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_POS1;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }
 楼主| 抹茶妹妹 发表于 2022-9-30 22:14 | 显示全部楼层
输出的这个电平信号的模式和电平高低都可以设置。

  
 楼主| 抹茶妹妹 发表于 2022-9-30 22:15 | 显示全部楼层
  RTC 可以输出一个固定频率信号,如:1HZ
 楼主| 抹茶妹妹 发表于 2022-9-30 22:35 | 显示全部楼层
总结RTC 的功能非常强大,在低功耗场景中可以在使用最低的功耗来进行睡眠,也可以防止非法入侵。
RTC 在低功耗场景中是不可或缺的组成部分,更多的 RTC 功能的发掘,可以在实际项目去体验一下,理解的也更加透彻。
redone 发表于 2022-10-1 09:42 | 显示全部楼层
棒棒,学习了~
febgxu 发表于 2022-11-2 18:02 | 显示全部楼层
STM32的RTC能产生毫秒级的中断吗
sdCAD 发表于 2022-11-2 18:17 | 显示全部楼层
stm32 rtc时钟可以用内部时钟吗  
janewood 发表于 2022-11-2 18:36 | 显示全部楼层
stm32的rtc与外界时间怎么校准的
jonas222 发表于 2022-11-2 19:13 | 显示全部楼层
STM32 RTC时钟 必须要用中断吗?
xiaoyaodz 发表于 2022-11-2 19:50 | 显示全部楼层
stm32自带的rtc怎么使用              
backlugin 发表于 2022-11-2 20:32 | 显示全部楼层
stm32的rtc外接纽扣电池电压多少
kkzz 发表于 2022-11-2 21:28 | 显示全部楼层
STM32 RTC_SetAlarm可设置的最大值为多少
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

309

帖子

0

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