抹茶妹妹 发表于 2022-9-29 23:29

STM32超低功耗进阶之RTC

一,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。

抹茶妹妹 发表于 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

设置闹钟
/** 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);

抹茶妹妹 发表于 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();
}

抹茶妹妹 发表于 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可设置的最大值为多少
页: [1] 2
查看完整版本: STM32超低功耗进阶之RTC