本次实验工程是在第二次实验串口通信的基础上修改的。参考博客
实时时钟是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒后,RTC的设置和时间维持不变。系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操作。执行以下操作将使能对后备寄存器和RTC的访问:
设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟
设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问。
其供电部分如图所示,当VDD断点之后,需要VBAT管脚为其供电,才能保证RTC的正常工作。
RTC_DateTypeDef GetData; //获取日期结构体
RTC_TimeTypeDef GetTime; //获取时间结构体
/* 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);
由于单片机每一次复位或上电都会调用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)
{
__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时钟秒中断
}