#include "McuBspRtc.h" static BspRtcAlarmCallback gMcuBspRtcExtiCallback = NULL; static RTC_HandleTypeDef gRTCHandle; static unsigned char gCentury = 0; static unsigned char gRtcSyncFlag = 0; // RTC时钟同步标志位 /* 初始化RTC */ int McuBspRtcInit(void) { gRTCHandle.Instance = RTC; gRTCHandle.Init.AsynchPrediv = RTC_AUTO_1_SECOND; // 设定基本时钟为1s,时钟精度为1s gRTCHandle.Init.OutPut = RTC_OUTPUTSOURCE_NONE; // 允许PC13脚作为普通IO口使用 if (HAL_RTC_Init(&gRTCHandle) != HAL_OK) { return -1; } return 0; } /* 设置当前时间 */ int McuBspRtcSetTime(MCU_BSP_CLOCK *time) { RTC_TimeTypeDef sTime = {0}; RTC_DateTypeDef sDate = {0}; if (time == NULL) { return -1; } sTime.Hours = time->Hours; sTime.Minutes = time->Minutes; sTime.Seconds = time->Seconds; sDate.Month = time->Month; sDate.Date = time->Date; sDate.Year = time->Year % 100; gCentury = time->Year / 100; if(HAL_RTC_SetDate(&gRTCHandle, &sDate, RTC_FORMAT_BIN) != HAL_OK) { return -1; } if(HAL_RTC_SetTime(&gRTCHandle, &sTime, RTC_FORMAT_BIN) != HAL_OK) { return -1; } gRtcSyncFlag = 1; return 0; } /* 获取RTC同步标志位 */ int McuBspRtcGetSyncFlag(void) { return gRtcSyncFlag; } /* 读取当前时间 */ int McuBspRtcGetTime(MCU_BSP_CLOCK *time) { RTC_TimeTypeDef sTime = {0}; RTC_DateTypeDef sDate = {0}; if (time == NULL) { return -1; } if (HAL_RTC_GetTime(&gRTCHandle, &sTime, RTC_FORMAT_BIN) != HAL_OK) { return -1; } if (HAL_RTC_GetDate(&gRTCHandle, &sDate, RTC_FORMAT_BIN) != HAL_OK) { return -1; } time->Hours = sTime.Hours; time->Minutes = sTime.Minutes; time->Seconds = sTime.Seconds; time->Month = sDate.Month; time->Date = sDate.Date; time->Year = gCentury * 100 + sDate.Year; return 0; } /* 启动RTC闹钟中断 */ int McuBspRtcStartAlarm(unsigned char RtcPeriod, BspRtcAlarmCallback Callback) { RTC_AlarmTypeDef sAlarm = {0}; /* 获取当前时间 */ RTC_TimeTypeDef sTime = {0}; if (HAL_RTC_GetTime(&gRTCHandle, &sTime, RTC_FORMAT_BIN) != HAL_OK) { return -1; } sAlarm.Alarm = RTC_ALARM_A; switch (RtcPeriod) { case MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_30MIN: if ((sTime.Minutes + 30) > 60) { sAlarm.AlarmTime.Hours = sTime.Hours + 1; } else { sAlarm.AlarmTime.Hours = sTime.Hours; } if (((sTime.Minutes + 30) > 60) && ((sTime.Minutes + 30) < 90)) { sAlarm.AlarmTime.Minutes = 0; } else { sAlarm.AlarmTime.Minutes = 30; } sAlarm.AlarmTime.Seconds = 0; break; case MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_1HOUR: sAlarm.AlarmTime.Hours = (sTime.Hours + (MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_1HOUR - (sTime.Hours % MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_1HOUR))) % 24; sAlarm.AlarmTime.Minutes = 0; sAlarm.AlarmTime.Seconds = 0; break; case MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_2HOUR: sAlarm.AlarmTime.Hours = (sTime.Hours + (MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_2HOUR - (sTime.Hours % MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_2HOUR))) % 24; sAlarm.AlarmTime.Minutes = 0; sAlarm.AlarmTime.Seconds = 0; break; case MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_3HOUR: sAlarm.AlarmTime.Hours = (sTime.Hours + (MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_3HOUR - (sTime.Hours % MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_3HOUR))) % 24; sAlarm.AlarmTime.Minutes = 0; sAlarm.AlarmTime.Seconds = 0; break; case MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_4HOUR: sAlarm.AlarmTime.Hours = (sTime.Hours + (MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_4HOUR - (sTime.Hours % MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_4HOUR))) % 24; sAlarm.AlarmTime.Minutes = 0; sAlarm.AlarmTime.Seconds = 0; break; case MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_6HOUR: sAlarm.AlarmTime.Hours = (sTime.Hours + (MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_6HOUR - (sTime.Hours % MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_6HOUR))) % 24; sAlarm.AlarmTime.Minutes = 0; sAlarm.AlarmTime.Seconds = 0; break; case MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_8HOUR: sAlarm.AlarmTime.Hours = (sTime.Hours + (MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_8HOUR - (sTime.Hours % MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_8HOUR))) % 24; sAlarm.AlarmTime.Minutes = 0; sAlarm.AlarmTime.Seconds = 0; break; case MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_12HOUR: sAlarm.AlarmTime.Hours = (sTime.Hours + (MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_12HOUR - (sTime.Hours % MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_12HOUR))) % 24; sAlarm.AlarmTime.Minutes = 0; sAlarm.AlarmTime.Seconds = 0; break; case MCU_BSP_RTC_CLOCK_WAKEUP_PERIOD_24HOUR: sAlarm.AlarmTime.Hours = 0; sAlarm.AlarmTime.Minutes = 0; sAlarm.AlarmTime.Seconds = 0; break; default : return -1; } HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 0x0F, 0); // 优先级最低与系统滴答优先级一致 HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn); if (HAL_RTC_SetAlarm_IT(&gRTCHandle, &sAlarm, RTC_FORMAT_BIN) != HAL_OK) { return -1; } gMcuBspRtcExtiCallback = Callback; return 0; } void McuBspRtcEndAlarm(void) { HAL_NVIC_DisableIRQ(RTC_Alarm_IRQn); } /* RTC初始化的时候底层硬件使用 */ void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc) { RCC_OscInitTypeDef RCC_OscInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; if (hrtc -> Instance == RTC) { __HAL_RCC_PWR_CLK_ENABLE(); HAL_PWR_EnableBkUpAccess(); /* Configue LSE as RTC clock soucre */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.LSEState = RCC_LSE_ON; PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { } PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; if(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { } __HAL_RCC_RTC_ENABLE(); } } /* 反初始化底层硬件调用 */ void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc) { /*##-1- Reset peripherals ##################################################*/ __HAL_RCC_RTC_DISABLE(); } void RTC_Alarm_IRQHandler(void) { HAL_RTC_AlarmIRQHandler(&gRTCHandle); } void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) { if (gMcuBspRtcExtiCallback == NULL) { gMcuBspRtcExtiCallback(); } }