网贴写的比较清楚的有一篇可以参考:
https://blog.csdn.net/lirrrr3377/article/details/19161487
代码可以用,但是数据结构设计的不好,容易出错,可读性不强。
所以重写数据结构和配置函数。
整理后的步骤如下:
1. RTC初始化可以利用CubeMX设置后自动生成可用的代码,防止出错
2. 定义date和time的数据结构
typedef struct{
uint8_t Year;
uint8_t Month;
uint8_t Day;
}Date_t;
typedef struct{
uint8_t Hour;
uint8_t Minute;
uint8_t Second;
}Time_t;
3. 查看RTC配置参数,注意要打开时钟哦
RTC_HandleTypeDef hrtc;
/* 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 = 17;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
}
void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
{
if(rtcHandle->Instance==RTC)
{
/* USER CODE BEGIN RTC_MspInit 0 */
/* USER CODE END RTC_MspInit 0 */
/* RTC clock enable */
__HAL_RCC_RTC_ENABLE();
/* USER CODE BEGIN RTC_MspInit 1 */
/* USER CODE END RTC_MspInit 1 */
}
}
4. 编写设置和调取RTC数据的函数
//setup the RTC parameter
void SetRTC(Date_t current_date,Time_t current_time)
{
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};
sTime.Hours =current_time.Hour;
sTime.Minutes = current_time.Minute;
sTime.Seconds = current_time.Second;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
sDate.WeekDay = RTC_WEEKDAY_MONDAY;
sDate.Month = current_date.Month;
sDate.Date = current_date.Day;
sDate.Year = current_date.Year;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
}
//get the RTC data
void GetRTC(Date_t *date_result,Time_t *time_result)
{
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BCD);
HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BCD);
date_result->Year=sDate.Year;
date_result->Month=sDate.Month;
date_result->Day=sDate.Date;
time_result->Hour=sTime.Hours;
time_result->Minute=sTime.Minutes;
time_result->Second=sTime.Seconds;
}
5. 主函数调用并检查结果
int main(void)
{
/* USER CODE BEGIN 1 */
// format: date-- ddmmyy, time--hhmmss
Date_t date;
Time_t time;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_RTC_Init();
/* USER CODE BEGIN 2 */
SetRTC(INIT_DATE,INIT_TIME);
printf("DATE set to:Y--20%02d, M--%02d ,D--%02d \n",(INIT_DATE.Year),(INIT_DATE.Month),(INIT_DATE.Day));
printf("TIME set to:H-- %02d , M-- %02d , S-- %02d \n",(INIT_TIME.Hour),(INIT_TIME.Minute),(INIT_TIME.Second));
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
LED_Toggle;
HAL_Delay(3000);
GetRTC(&date,&time);
printf("current time: %02d: %02d : %02d \n",time.Hour,time.Minute,time.Second);
printf("current date :Y--20%02d, M--%02d ,D--%02d",date.Year,date.Month,date.Day);
}
/* USER CODE END 3 */
}
6. 确认运行结果