解决STM32 CubeMX中配置RTC每次上电就会重置的问题
自从有了Cube MX,配置STM32的外设就变得格外简单。不过这次差点踩坑,下载完程序后RTC自动就恢复到了我设置的初始值,重启之后现象依旧。
下面就以上问题简单分析一下代码。
/* RTC init function */
void MX_RTC_Init(void)
{
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};
/** 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;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN Check_RTC_BKUP */
/* USER CODE END Check_RTC_BKUP */
/** Initialize RTC and set the Time and Date
*/
sTime.Hours = 0x0;
sTime.Minutes = 0x0;
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_MONDAY;
sDate.Month = RTC_MONTH_JANUARY;
sDate.Date = 0x1;
sDate.Year = 0x0;
if (HAL_RTC_SetDate(&hrtc, &sDate, 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();
}
}
从注释和函数执行过就不难看出,每次上电都会将预设值写入RTC中。可问题在于:我虽然可以对这段代码进行修改,但是每当我使用Cube MX重新配置和生成工程后修改的内容就会被覆盖。那么有没有比较好的方法呢?
当然是有的,方法就是宏定义。
//我们可以通过宏定义把 这两个函数给"注释"掉。
HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD)
HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD)
//宏定义如下:
#define HAL_RTC_SetDate(a, b, c) HAL_OK
#define HAL_RTC_SetTime(a, b, c) HAL_OK
/**********原先的代码***********/
if (HAL_RTC_SetDate(&hrtc, &sDate, 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();
}
/********那么在预处理阶段函数被替换掉之后就会变成:********/
if ( HAL_OK != HAL_OK)
{
Error_Handler();
}
if ( HAL_OK != HAL_OK)
{
Error_Handler();
}
为了方便调试,我在宏定义前加了条件:#ifndef __NOT_RESET_RTC_IN_INIT
并在mian.h中也加入宏定义:#define __NOT_RESET_RTC_IN_INIT
为了消除未使用的警告,可以在适当的地方加入:
/* USER CODE BEGIN Check_RTC_BKUP */
#ifdef __NOT_RESET_RTC_IN_INIT
UNUSED(sTime);
UNUSED(sDate);
#endif
/* USER CODE END Check_RTC_BKUP */
更改后的代码。
STM32F407开发板