STM32HAL库-04-RTC实时时钟

步骤:

1、RTC初始化
2、使能电源时钟,并使能 RTC 及 及 RTC 后备寄存器写访问。
3、开启外部低速振荡器 LSE ,选择 RTC 时钟,并使能。(使用LSE时钟32.768kHz)
4、设置时间和日期
5、获取时间和日期(※)


  • 1、RTC初始化
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


  • 2、使能电源时钟,并使能 RTC 及 及 RTC 后备寄存器写访问。
    __HAL_RCC_PWR_CLK_ENABLE();//使能电源时钟PWR
	HAL_PWR_EnableBkUpAccess();//取消备份区域写保护
	//(实验时忘记添加此项,并没有影响,然后发现写保护已经被取消,不知道时在哪已经取消了写保护)

  • 3、开启外部低速振荡器 LSE ,选择 RTC 时钟,并使能。(使用LSE时钟32.768kHz)
	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();

  • 4、设置时间和日期

//****************设置时间*******


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);
	
}

  • 5、获取时间和日期(HAL库下 RTC 获取时间不连续 或 卡 )
//**************获取日期*****************
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在后。
STM32HAL库-04-RTC实时时钟_第1张图片

你可能感兴趣的:(STM32_HAL库)