1、RTC初始化
2、使能电源时钟,并使能 RTC 及 及 RTC 后备寄存器写访问。
3、开启外部低速振荡器 LSE ,选择 RTC 时钟,并使能。(使用LSE时钟32.768kHz)
4、设置时间和日期
5、获取时间和日期(※)
RTC_HandleTypeDef RTC_HandleStruct;
RTC_HandleStruct.Instance = RTC; //RTC外设地址
RTC_HandleStruct.Init.HourFormat = RTC_HOURFORMAT_12; //时间格式12小时或24小时
RTC_HandleStruct.Init.AsynchPrediv = 0x7f; //异步预分频系数
RTC_HandleStruct.Init.SynchPrediv = 0xff; //同步预分频系数
RTC_HandleStruct.Init.OutPut = RTC_OUTPUT_DISABLE; //选择连接到 RTC_ALARM 输出的标志
RTC_HandleStruct.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; //设置 RTC_ALARM 的输出极性
RTC_HandleStruct.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; //设置 RTC_ALARM 的输出类型为开漏输出还是推挽输出
HAL_RTC_Init(&RTC_HandleStruct);
Fck_spre=Frtcclk/[(PREDIV_S+1)*( PREDIV_A+1)]
PREDIV_A 即 :AsynchPrediv = 0x7f
PREDIV_S 即 :SynchPrediv = 0xff
(0x7f+0x1) * (0xff+1) = 0x80 * 0x100 = 0x8000 = 32768
__HAL_RCC_PWR_CLK_ENABLE();//使能电源时钟PWR
HAL_PWR_EnableBkUpAccess();//取消备份区域写保护
//(实验时忘记添加此项,并没有影响,然后发现写保护已经被取消,不知道时在哪已经取消了写保护)
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct;
//**********配置开启 LSE**************
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
//(实验时此处写错成HSI,没有发现什么影响)
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
//*************选择 RTC 时钟源************
RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
RCC_PeriphCLKInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);
//**************RTC使能*************
__HAL_RCC_RTC_ENABLE();
//****************设置时间*******
HAL_StatusTypeDef Set_RTC_Time(u8 hour,u8 min,u8 sec,u8 ampm)
{
RTC_TimeTypeDef RTC_TimeStruct;
RTC_TimeStruct.Hours = hour;
RTC_TimeStruct.Minutes = min;
RTC_TimeStruct.Seconds = sec;
RTC_TimeStruct.TimeFormat = ampm;
RTC_TimeStruct.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
RTC_TimeStruct.StoreOperation = RTC_STOREOPERATION_RESET;
return HAL_RTC_SetTime(&RTC_HandleStruct,&RTC_TimeStruct,RTC_FORMAT_BIN);
}
//***************设置日期****************
HAL_StatusTypeDef Set_RTC_Data(u8 year,u8 month,u8 data,u8 weekday)
{
RTC_DateTypeDef RTC_DateStruct;
RTC_DateStruct.WeekDay = weekday;
RTC_DateStruct.Month = month;
RTC_DateStruct.Date = data;
RTC_DateStruct.Year = year;
return HAL_RTC_SetDate(&RTC_HandleStruct,&RTC_DateStruct,RTC_FORMAT_BIN);
}
//**************获取日期*****************
void Get_Time(RTC_DateTypeDef *RTC_Date,RTC_TimeTypeDef *RTC_Time)
{
//注意必须GetTime在前GetDate在后
HAL_RTC_GetTime(&RTC_HandleStruct,RTC_Time,RTC_FORMAT_BIN);
HAL_RTC_GetDate(&RTC_HandleStruct,RTC_Date,RTC_FORMAT_BIN);
}
//**************获取日期*****************
void Get_Time(RTC_DateTypeDef *RTC_Date,RTC_TimeTypeDef *RTC_Time)
{
//注意必须GetTime在前GetDate在后
HAL_RTC_GetTime(&RTC_HandleStruct,RTC_Time,RTC_FORMAT_BIN);
HAL_RTC_GetDate(&RTC_HandleStruct,RTC_Date,RTC_FORMAT_BIN);
}
开始时函数是HAL_RTC_GetDate在前,但是发现获取的时间不够及时,一直卡在一个时间点不更新(以200ms为周期循环获取),或者过了十几秒获取的数据才更新(以10ms为周期循环获取),百度没找到答案,翻看源码发现问题所在,必须HAL_RTC_GetTime在前HAL_RTC_GetDate在后。