20230731_XiaoFuZi_emb/ZheDaXiaoFuZi/Src/Usr/Bsp/McuBspRtc.c

207 lines
7.0 KiB
C
Raw Normal View History

#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();
}
}