STM32HAL学习笔记七-RTC时钟

STM32HAL学习笔记七-RTC时钟

​ 本次实验工程是在第二次实验串口通信的基础上修改的。参考博客

1.RTC简介

​ 实时时钟是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒后,RTC的设置和时间维持不变。系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操作。执行以下操作将使能对后备寄存器和RTC的访问:

  • 设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟

  • 设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问。

    其供电部分如图所示,当VDD断点之后,需要VBAT管脚为其供电,才能保证RTC的正常工作。

STM32HAL学习笔记七-RTC时钟_第1张图片

2.Cubemx配置

2.1配置低速时钟

STM32HAL学习笔记七-RTC时钟_第2张图片

2.2使能时钟源和日期

STM32HAL学习笔记七-RTC时钟_第3张图片

2.3设置初始时间

STM32HAL学习笔记七-RTC时钟_第4张图片

2.4更改时钟源

STM32HAL学习笔记七-RTC时钟_第5张图片

3.程序编写

3.1定义获取日期和时间的结构体

请添加图片描述

RTC_DateTypeDef GetData;  //获取日期结构体
RTC_TimeTypeDef GetTime;   //获取时间结构体

3.2主程序

STM32HAL学习笔记七-RTC时钟_第6张图片

	  /* Get the RTC current Time */
	  HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
      /* Get the RTC current Date */
      HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);

      /* Display date Format : yy/mm/dd */
      printf("%02d/%02d/%02d\r\n",2000 + GetData.Year, GetData.Month, GetData.Date);
      /* Display time Format : hh:mm:ss */
      printf("%02d:%02d:%02d\r\n",GetTime.Hours, GetTime.Minutes, GetTime.Seconds);

      printf("\r\n");

      HAL_Delay(1000);

3.3调试结果

STM32HAL学习笔记七-RTC时钟_第7张图片

4.优化

​ 由于单片机每一次复位或上电都会调用RTC初始化的函数,而因为HAL库设置了一个BKP寄存器保存一个标志,每次单片机启动时都读取这个标志并判断是不是预先设定的值:如度果不是就初始化RTC并设置时间,再设置标志为预期值;如果是预期值就跳过初始化和时间设置,继续执行后面的程序,所以每次上电或者复位都会重置时间,于是需要优化。

请添加图片描述

可以在MX_RTC_Init()函数增加如下函数

请添加图片描述

RTC_DateTypeDef datebuff;   //日期结构体参数

请添加图片描述

	__HAL_RCC_BKP_CLK_ENABLE();       //开启后备区域时钟
	__HAL_RCC_PWR_CLK_ENABLE();		  //开启电源时钟

请添加图片描述

if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1)!= 0x5051)
  {

STM32HAL学习笔记七-RTC时钟_第8张图片

	__HAL_RTC_SECOND_ENABLE_IT(&hrtc,RTC_IT_SEC);	 //开启RTC时钟秒中断
	datebuff = DateToUpdate;  //把日期数据拷贝到自己定义的data中
	HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 0x5051);//向指定的后备区域寄存器写入数据
	HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, (uint16_t)datebuff.Year);
	HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR3, (uint16_t)datebuff.Month);
	HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR4, (uint16_t)datebuff.Date);
	HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR5, (uint16_t)datebuff.WeekDay);
	
  }
	else
	{
		datebuff.Year    = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);
		datebuff.Month   = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3);
		datebuff.Date    = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4);
		datebuff.WeekDay = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR5);
		DateToUpdate = datebuff;
		if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BIN) != HAL_OK)
		{
			Error_Handler();
		}
		__HAL_RTC_SECOND_ENABLE_IT(&hrtc,RTC_IT_SEC);	 //开启RTC时钟秒中断		
	}

你可能感兴趣的:(STM32Hal库学习笔记,stm32,单片机,arm)