单片机型号:stm32L431
库函数:HAL库
项目需求: 单片机进行数据上报后,如果数据上报成功进入低功耗,当天不在上报数据,如果不成功进入低功耗,10分钟后进行RTC唤醒,再次联网上报数据
RTC10分种后唤醒解决方案:
方案1:使用RTC闹钟功能:再进低功耗前先获取当前RTC的时间,在当前时间上加10分钟,算出唤醒时间,然后设置RTC闹钟唤醒时间,
设置函数:HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD)
中断函数:void RTC_Alarm_IRQHandler(void)
方案2:使用RTC的WakeUp功能,最大计数值可以设置0x1FFFF,根据时钟频率可以任意调整延时唤醒时间,如果时1HZ的RTC计数频率,最大延时唤醒时间(0x1FFFF+1)*1/60/60=36小时
设置函数: HAL_RTCEx_SetWakeUpTimer_IT(&hrtc,600,RTC_WAKEUPCLOCK_CK_SPRE_16BITS);//RTC600秒后唤醒
中断函数 : void RTC_WKUP_IRQHandler(void)
关闭周期唤醒函数: HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);//关闭RTC周期唤醒
注意事项:
- 在进行RTC闹钟设置时,不能只调用(HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)函数,这样会导致闹钟设置失败,要重新配置RTC才会设置成功
void RTC_WakeUp(void)
{
if(gNetInfo.uploadTimeUpdate!=1)//
return;
RTC_AlarmTypeDef sAlarm = {0};
// #if TEST
// gImportInfo.alarm.hour=0;
// gImportInfo.alarm.minute=0;
// gImportInfo.alarm.second=40;
// #endif
sAlarm.AlarmTime.Hours = gImportInfo.alarm.hour;
sAlarm.AlarmTime.Minutes = gImportInfo.alarm.minute;
sAlarm.AlarmTime.Seconds = gImportInfo.alarm.second;
sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_WEEKDAY;
// sAlarm.AlarmDateWeekDay = 0x1;
sAlarm.Alarm = RTC_ALARM_A;
if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
gNetInfo.uploadTimeUpdate=0;
}
2.再获取RTC时间或者日期时,必须先获取时间,再获取日期,顺序不能颠倒(会获取失败),而且时间和日期调用的时候不能单独调用,必须两个同时调用,不然下次获取的时间和日期会出错
HAL_RTC_GetTime(&hrtc, &pTime, RTC_FORMAT_BCD);//获取时间
HAL_RTC_GetDate(&hrtc, &pDate, RTC_FORMAT_BCD);//获取日期
3.RTC周期唤醒函数,进低功耗前打开,出低功耗后关闭,不然程序正常运行时,也会进 RTC周期唤醒中断函数,干扰软件正常运行