打印
[STM32F1]

STM32超低功耗进阶之RTC

[复制链接]
768|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 实现定时唤醒唤醒功能
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  hrtc.Init.AsynchPrediv = 127;
  hrtc.Init.SynchPrediv = 255;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x0FFF, RTC_WAKEUPCLOCK_RTCCLK_DIV16) != HAL_OK)
  {
    Error_Handler();
  }

使用特权

评论回复
地板
抹茶妹妹|  楼主 | 2022-9-29 23:55 | 只看该作者
这里要注意 AsynchPrediv 和 AsynchPrediv 这两个数,RTC 的时间基准就是由这两个分频得来。一般来说 RTC 都是由 32.768k 的外部晶振来提供时钟源,这里计算可得:32.768k/(127+1)/(255+1) = 1 hz。

使用特权

评论回复
5
抹茶妹妹|  楼主 | 2022-9-29 23:56 | 只看该作者
设置带有中断的定时器:

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

上面的代码的功能就是实现,每间隔 2s 唤醒一次 MCU

使用特权

评论回复
6
抹茶妹妹|  楼主 | 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();
  }

使用特权

评论回复
7
抹茶妹妹|  楼主 | 2022-9-29 23:58 | 只看该作者
设置闹钟
  /** Enable the Alarm A
  */
  sAlarm.AlarmTime.Hours = 0x0;
  sAlarm.AlarmTime.Minutes = 0x0;
  sAlarm.AlarmTime.Seconds = 0x0;
  sAlarm.AlarmTime.SubSeconds = 0x0;
  sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
  sAlarm.AlarmMask = RTC_ALARMMASK_NONE;
  sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
  sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
  sAlarm.AlarmDateWeekDay = 0x1;
  sAlarm.Alarm = RTC_ALARM_A;
  if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  /* RTC interrupt Init */
  HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);

使用特权

评论回复
8
抹茶妹妹|  楼主 | 2022-9-29 23:58 | 只看该作者
RTC 的侵入检测
RTC 可以保证 MCU 在电池优电的情况下,备份域可以一直保存数据,如果检测到非法侵入可以销毁备份域的数据,以下代码由 cubemx 生成,未做验证
  sTamper.Tamper = RTC_TAMPER_1;
  sTamper.Trigger = RTC_TAMPERTRIGGER_LOWLEVEL;
  sTamper.NoErase = RTC_TAMPER_ERASE_BACKUP_ENABLE;
  sTamper.MaskFlag = RTC_TAMPERMASK_FLAG_DISABLE;
  sTamper.Filter = RTC_TAMPERFILTER_2SAMPLE;
  sTamper.SamplingFrequency = RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV32768;
  sTamper.PrechargeDuration = RTC_TAMPERPRECHARGEDURATION_1RTCCLK;
  sTamper.TamperPullUp = RTC_TAMPER_PULLUP_ENABLE;
  sTamper.TimeStampOnTamperDetection = RTC_TIMESTAMPONTAMPERDETECTION_ENABLE;
  if (HAL_RTCEx_SetTamper(&hrtc, &sTamper) != HAL_OK)
  {
    Error_Handler();
  }

使用特权

评论回复
9
抹茶妹妹|  楼主 | 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();
  }

使用特权

评论回复
10
抹茶妹妹|  楼主 | 2022-9-30 22:14 | 只看该作者
输出的这个电平信号的模式和电平高低都可以设置。

  

使用特权

评论回复
11
抹茶妹妹|  楼主 | 2022-9-30 22:15 | 只看该作者
  RTC 可以输出一个固定频率信号,如:1HZ

使用特权

评论回复
12
抹茶妹妹|  楼主 | 2022-9-30 22:35 | 只看该作者
总结RTC 的功能非常强大,在低功耗场景中可以在使用最低的功耗来进行睡眠,也可以防止非法入侵。
RTC 在低功耗场景中是不可或缺的组成部分,更多的 RTC 功能的发掘,可以在实际项目去体验一下,理解的也更加透彻。

使用特权

评论回复
13
redone| | 2022-10-1 09:42 | 只看该作者
棒棒,学习了~

使用特权

评论回复
14
febgxu| | 2022-11-2 18:02 | 只看该作者
STM32的RTC能产生毫秒级的中断吗

使用特权

评论回复
15
sdCAD| | 2022-11-2 18:17 | 只看该作者
stm32 rtc时钟可以用内部时钟吗  

使用特权

评论回复
16
janewood| | 2022-11-2 18:36 | 只看该作者
stm32的rtc与外界时间怎么校准的

使用特权

评论回复
17
jonas222| | 2022-11-2 19:13 | 只看该作者
STM32 RTC时钟 必须要用中断吗?

使用特权

评论回复
18
xiaoyaodz| | 2022-11-2 19:50 | 只看该作者
stm32自带的rtc怎么使用              

使用特权

评论回复
19
backlugin| | 2022-11-2 20:32 | 只看该作者
stm32的rtc外接纽扣电池电压多少

使用特权

评论回复
20
kkzz| | 2022-11-2 21:28 | 只看该作者
STM32 RTC_SetAlarm可设置的最大值为多少

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

302

帖子

0

粉丝