/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file rtc.c
* @brief This file provides code for the configuration
* of the RTC instances.
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "rtc.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
RTC_HandleTypeDef hrtc;
/* RTC init function */
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};
uint32_t Backup_register;
/* USER CODE BEGIN RTC_Init 1 */
/* USER CODE END RTC_Init 1 */
/** Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN Check_RTC_BKUP */
// Backup_register = power_bkp_read(0);
// if (Backup_register == 0x5050) {
// /* USER CODE END Check_RTC_BKUP */
// /** Initialize RTC and set the Time and Date
// */
// sTime.Hours = 0;
// sTime.Minutes = 0;
// sTime.Seconds = 0;
// sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
// sTime.StoreOperation = RTC_STOREOPERATION_RESET;
// if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
// {
// Error_Handler();
// }
// sDate.WeekDay = RTC_WEEKDAY_FRIDAY;
// sDate.Month = RTC_MONTH_JULY;
// sDate.Date = 18;
// sDate.Year = 23;
// if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
// {
// Error_Handler();
// }
// /** Enable the Alarm A
// */
// sAlarm.AlarmTime.Hours = 0;
// sAlarm.AlarmTime.Minutes = 0;
// sAlarm.AlarmTime.Seconds = 15;
// sAlarm.AlarmTime.SubSeconds = 0;
// sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
// sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
// sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS
// |RTC_ALARMMASK_MINUTES;
// sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
// sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
// sAlarm.AlarmDateWeekDay = 1;
// sAlarm.Alarm = RTC_ALARM_A;
// if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
// {
// Error_Handler();
// }
// /** Enable the Alarm B
// */
// sAlarm.AlarmTime.Seconds = 30;
// sAlarm.Alarm = RTC_ALARM_B;
// if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
// {
// Error_Handler();
// }
// /* USER CODE BEGIN RTC_Init 2 */
// power_bkp_write(0, 0x5051);
// }
/* USER CODE END RTC_Init 2 */
}
void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(rtcHandle->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_LSI;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* RTC clock enable */
__HAL_RCC_RTC_ENABLE();
/* RTC interrupt Init */
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);
HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
/* USER CODE BEGIN RTC_MspInit 1 */
/* USER CODE END RTC_MspInit 1 */
}
}
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_Alarm_IRQn);
/* USER CODE BEGIN RTC_MspDeInit 1 */
/* USER CODE END RTC_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
uint8_t set_system_time(uint8_t hours, uint8_t minutes, uint8_t seconds) {
RTC_TimeTypeDef sTime = {0};
sTime.Hours = hours;
sTime.Minutes = minutes;
sTime.Seconds = seconds;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
{
return 1;
Error_Handler();
} else {
return 0;
}
}
uint8_t set_system_date(uint8_t year, uint8_t month, uint8_t date, uint8_t weekDay) {
RTC_DateTypeDef sDate = {0};
sDate.WeekDay = weekDay;
sDate.Month = month;
sDate.Date = date;
sDate.Year = year;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
{
return 1;
Error_Handler();
} else {
return 0;
}
}
uint8_t set_alarm_A(uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t weekDay) {
RTC_AlarmTypeDef sAlarm = {0};
uint32_t Backup_register;
sAlarm.AlarmTime.Hours = hours;
sAlarm.AlarmTime.Minutes = minutes;
sAlarm.AlarmTime.Seconds = seconds;
sAlarm.AlarmTime.SubSeconds = 0;
/***********************************************/
// Backup_register = hours;
// Backup_register <<= 8;
// Backup_register |= minutes;
// Backup_register <<= 8;
// Backup_register |= seconds;
// power_bkp_write(0, Backup_register); /* 0 address write */
/***********************************************/
sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS
|RTC_ALARMMASK_MINUTES;
// sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
sAlarm.AlarmDateWeekDay = weekDay;
sAlarm.Alarm = RTC_ALARM_A;
if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
{
return 1;
Error_Handler();
} else {
return 0;
}
}
uint8_t set_alarm_B(uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t weekDay) {
RTC_AlarmTypeDef sAlarm = {0};
sAlarm.AlarmTime.Hours = hours;
sAlarm.AlarmTime.Minutes = minutes;
sAlarm.AlarmTime.Seconds = seconds;
sAlarm.AlarmTime.SubSeconds = 0;
sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS
|RTC_ALARMMASK_MINUTES;
// sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
sAlarm.AlarmDateWeekDay = weekDay;
sAlarm.Alarm = RTC_ALARM_B;
if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
{
return 1;
Error_Handler();
} else {
return 0;
}
}
uint8_t get_alarm_time(uint8_t *hours, uint8_t *minutes, uint8_t *seconds) {
RTC_TimeTypeDef rtc_t = {0};
if (HAL_RTC_GetTime(&hrtc, &rtc_t, RTC_FORMAT_BIN) == HAL_OK) {
*hours = rtc_t.Hours;
*minutes = rtc_t.Minutes;
*seconds = rtc_t.Seconds;
return 1;
} else {
return 0;
}
}
uint8_t get_alarm_date(uint8_t *year, uint8_t *month, uint8_t *date, uint8_t *weekDay) {
RTC_DateTypeDef rtc_d = {0};
if (HAL_RTC_GetDate(&hrtc, &rtc_d, RTC_FORMAT_BIN) == HAL_OK) {
*year = rtc_d.Year;
*month = rtc_d.Month;
*date = rtc_d.Date;
*weekDay = rtc_d.WeekDay;
return 1;
} else {
return 0;
}
}
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *rtc_handle_A) {
char infoA[]="Alarm A(xx:xx:%02d) trigger: \r\n";
RTC_TimeTypeDef rtc_t = {0};
char sendBuff[128] = {0};
get_alarm_time(&rtc_t.Hours, &rtc_t.Minutes, &rtc_t.Seconds);
sprintf(sendBuff, infoA, rtc_t.Seconds);
printf("\r\n ---------- A alarm ----------\r\n");
printf("%s", sendBuff);
printf(" ---------- A alarm ----------\r\n\r\n");
led_switch = ALARM_A;
}
void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *rtc_handle_B) {
char infoB[]="Alarm B(xx:xx:%02d) trigger: \r\n";
RTC_TimeTypeDef rtc_t = {0};
char sendBuff[128] = {0};
get_alarm_time(&rtc_t.Hours, &rtc_t.Minutes, &rtc_t.Seconds);
sprintf(sendBuff, infoB, rtc_t.Seconds);
printf("\r\n ---------- B alarm ----------\r\n");
printf("%s", sendBuff);
printf(" ---------- B alarm ----------\r\n\r\n");
led_switch = ALARM_B;
}
/* USER CODE END 1 */
对RTC寄存器和backup 寄存器写操作时都需要取消写保护,完成相应操作之后再开启写保护。
你操作这两部分时注意这个问题,不要弄混乱了。
建议对这两块分开配置或编程,不要穿插在一起。