一、rtc的时钟有lse提供。
二、选择rtc唤醒与闹钟功能
内部参数介绍
闹钟配置
在配置时间时,注意将时间信息存储起来,防止复位后时间重新配置。
if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0)!= 0x55AA)//判断标志位是否配置过,没有则进入if进行配置
{
sTime.Hours = 0x23;
sTime.Minutes = 0x59;
sTime.Seconds = 0x55;
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_FRIDAY;
sDate.Month = RTC_MONTH_OCTOBER;
sDate.Date = 0x25;
sDate.Year = 0x24;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR0, 0x55AA);//写入标志位
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, sDate.Year );//写入标志位
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, sDate.Date);//写入标志位
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR3, sDate.Month);//写入标志位
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR4, sDate.WeekDay);//写入标志位
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR5, sTime.Hours);//写入标志位
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR6, sTime.Minutes);//写入标志位
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR7, sTime.Seconds);//写入标志位
}
/** Enable the Alarm A
*/
sAlarm.AlarmTime.Hours = 0x0;
sAlarm.AlarmTime.Minutes = 0x0;
sAlarm.AlarmTime.Seconds = 0x5;
sAlarm.AlarmTime.SubSeconds = 0x0;
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_DATE;//星期或日期
sAlarm.AlarmDateWeekDay = 0x1;//日期
sAlarm.Alarm = RTC_ALARM_A;
if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
/** Enable the WakeUp
*/
if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)
{
Error_Handler();
}
开启电源时钟
void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(rtcHandle->Instance==RTC)
{
/* USER CODE BEGIN RTC_MspInit 0 */
RCC_OscInitTypeDef RCC_OscInitStruct;
__HAL_RCC_PWR_CLK_ENABLE();//使能电源时钟PWR
HAL_PWR_EnableBkUpAccess();//取消备份区域写保护
RCC_OscInitStruct.OscillatorType=RCC_OSCILLATORTYPE_LSE;//LSE配置
RCC_OscInitStruct.PLL.PLLState=RCC_PLL_NONE;
RCC_OscInitStruct.LSEState=RCC_LSE_ON; //RTC使用LSE
HAL_RCC_OscConfig(&RCC_OscInitStruct);
/* USER CODE END RTC_MspInit 0 */
...
}
在复位函数中添加关闭时钟配置
void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle)
{
if(rtcHandle->Instance==RTC)
{
/* USER CODE BEGIN RTC_MspDeInit 0 */
/* USER CODE END RTC_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_RTC_DISABLE();
/* RTC interrupt Deinit */
HAL_NVIC_DisableIRQ(RTC_WKUP_IRQn);
HAL_NVIC_DisableIRQ(RTC_Alarm_IRQn);
/* USER CODE BEGIN RTC_MspDeInit 1 */
HAL_PWR_DisableBkUpAccess();
__HAL_RCC_PWR_CLK_DISABLE();
/* USER CODE END RTC_MspDeInit 1 */
}
}
在闹钟回调和唤醒回调中添加
//RTC闹钟A中断处理回调函数
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
printf("ALARM A!\r\n");
}
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{
RTC_TimeTypeDef RTC_TimeStruct;
RTC_DateTypeDef RTC_DateStruct;
uint8_t buf[40];
HAL_RTC_GetTime(hrtc,&RTC_TimeStruct,RTC_FORMAT_BIN);
sprintf((char*)buf,"Time: %02d:%02d:%02d",RTC_TimeStruct.Hours,RTC_TimeStruct.Minutes,RTC_TimeStruct.Seconds);
printf("%s\r\n",buf);
HAL_RTC_GetDate(hrtc,&RTC_DateStruct,RTC_FORMAT_BIN);
sprintf((char*)buf,"Date: 20%02d-%02d-%02d Day %d",RTC_DateStruct.Year,RTC_DateStruct.Month,RTC_DateStruct.Date,RTC_DateStruct.WeekDay);
printf("%s\r\n",buf);
}
闹钟正常提示
复位和掉电后时间依旧正常,没有进行重置