本文编写的相关内容有读取RTC时间,闹钟A和B,定时器自动唤醒功能
1.cubemx配置
2.程序相关
由于HAL库每次复位或重启都会读一下备份区的标记位,没有置位则每次都会重新写入初始化参数
static void MX_RTC_Init(void)
{
/* USER CODE BEGIN RTC_Init 0 */
/* USER CODE END RTC_Init 0 */
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};
RTC_AlarmTypeDef sAlarm = {0};
/* USER CODE BEGIN RTC_Init 1 */
uint16_t bkpflag = 0;
/* USER CODE END RTC_Init 1 */
/** Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127; // 32768hz = (128-1) * (256-1)
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN Check_RTC_BKUP */
bkpflag = HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR0); // 读取备份区寄存器标记位
if((bkpflag != 0x5050) && (bkpflag != 0x5051)) // 每次判断一下是否已写入,已写入则继续运行之前的时间,否则重新初始化参数
{
sTime.Hours = 0x17;
sTime.Minutes = 0x11;
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_FRIDAY;
sDate.Month = RTC_MONTH_MAY;
sDate.Date = 0x10;
sDate.Year = 0x24;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK) // 初始化选BCD码
{
Error_Handler();
}
}
/* USER CODE END Check_RTC_BKUP */
/** Initialize RTC and set the Time and Date
*/
/** Enable the Alarm A
*/
sAlarm.AlarmTime.Hours = 0x10;
sAlarm.AlarmTime.Minutes = 0x10;
sAlarm.AlarmTime.Seconds = 0x10;
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 = 0x10;
sAlarm.Alarm = RTC_ALARM_A;
if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);
/** Enable the WakeUp
*/
if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 1, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK) // 1hz 时间范围1s-36h,时间分辨率1s
{
Error_Handler();
}
/* USER CODE BEGIN RTC_Init 2 */
/* USER CODE END RTC_Init 2 */
}
void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(hrtc->Instance==RTC)
{
/* USER CODE BEGIN RTC_MspInit 0 */
/* USER CODE END RTC_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV30;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
__HAL_RCC_RTC_ENABLE();
/* RTC interrupt Init */
HAL_NVIC_SetPriority(RTC_WKUP_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn);
HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
/* USER CODE BEGIN RTC_MspInit 1 */
HAL_PWR_EnableBkUpAccess(); /* 取消备份区域写保护 */
__HAL_RCC_PWR_CLK_ENABLE(); /* 使能电源时钟 PWR */
HAL_RTCEx_BKUPWrite(hrtc,RTC_BKP_DR0,0x5051); // 第一次初始化在备份区写入标记,防止每次上电都重新写入初始化参数 LSI:0x5051 LSE:0x5050
/* USER CODE END RTC_MspInit 1 */
}
}
/* USER CODE BEGIN 1 */
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) // Alarm A 闹钟回调函数,设置时间到调用
{
printf("alarm is ring\r\n");
}
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) // Wake up 回调函数,周期性调用
{
printf("wakeup is ring\r\n");
}
/* USER CODE END 1 */