HAL库如何配置RTC实时时钟

一、RTC实时时钟讲解

        STM32F407 的实时时钟(RTC)是一个独立的定时器。STM32 的 RTC 模块拥有一组连续
计数的计数器,在相对应的软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设
置系统的当前时间和日期。

        RTC是个独立的定时器。RTC模块拥有一个连续计数的计数器,在相应的软件配置下,可以提供时钟日历的功能。修改计数器的值可以重新设置当前时间和日期 RTC还包含用于管理低功耗模式的自动唤醒单元。在断电情况下 RTC仍可以独立运行 只要芯片的备用电源一直供电,RTC上的时间会一直走。RTC实质是一个掉电后还继续运行的定时器,从定时器的角度来看,相对于通用定时器TIM外设,它的功能十分简单,只有计时功能(也可以触发中断)。但其高级指出也就在于掉电之后还可以正常运行。

        无论器件状态如何(运行模式、低功耗模式或处于复位状态),只要电源电压保持在工作范围内,RTC使不会停止工作。

① 时钟源
        STM32F407 的 RTC 时钟源(RTCCLK)通过时钟控制器,可以从 LSE 时钟、LSI 时钟以及 HSE 时钟三者中选择其一。一般我们选择 LSE(外部 32.768KHz 晶振)作为时钟源(RTCCLK)。外部晶振具有精度高,但价格高,RC振荡器精度低,但成本也低。

 ③ 时间和日期相关寄存器
        该部分包括三个影子寄存器,RTC_SSR(亚秒)、RTC_TR(时间)、RTC_DR(日期)。实时时钟一般表示为:时/分/秒/亚秒。RTC_TR 寄存器用于存储时/分/秒时间数据,可读可写(即
可设置或者获取时间)。RTC_DR 寄存器用于存储日期数据,包括年/月/日/星期,可读可写(即
可设置或者获取日期)。RTC_SSR 寄存器用于存储亚秒级的时间,这样我们可以获取更加精确
的时间数据。

④ 可编程闹钟
        STM32F407 提供两个可编程闹钟:闹钟 A(ALARM_A)和闹钟 B(ALARM_B)。通过
RTC_CR 寄存器的 ALRAE 和 ALRBE 位置 1 来使能闹钟。当亚秒、秒、分、小时、日期分别与
闹钟寄存器RTC_ALRMASSR/RTC_ALRMAR和RTC_ALRMBSSR/RTC_ALRMBR中的值匹配
时,则可以产生闹钟(需要适当配置)。本章我们将利用闹钟 A 产生闹铃,即设置
RTC_ALRMASSR 和 RTC_ALRMAR 即可。

二、HAL库初始化RTC时钟

三、RTC时钟函数讲解

(1)读取系统时间函数

/*读取系统时间*/
HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)

*hrtc RTC结构体参数 例:&hi2c2
RTC_TimeTypeDef *sTime: 获取RTC时间的结构体,
Format: 获取时间的格式
RTC_FORMAT_BIN 使用16进制
RTC_FORMAT_BCD 使用BCD进制

(2)读取系统日期函数

/*读取系统日期*/
HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)

*hrtc RTC结构体参数 例:&hi2c2
RTC_DateTypeDef *sTime: 获取RTC日期的结构体,
Format: 获取日期的格式
RTC_FORMAT_BIN 使用16进制
RTC_FORMAT_BCD 使用BCD进制

(3)结构体介绍

typedef struct
{
  uint8_t Hours;            /*!< Specifies the RTC Time Hour.*/
  uint8_t Minutes;          /*!< Specifies the RTC Time Minutes*/
  uint8_t Seconds;          /*!< Specifies the RTC Time Seconds*/
} RTC_TimeTypeDef;
typedef struct
{
  uint8_t WeekDay;  /*!< Specifies the RTC Date WeekDay  */
  uint8_t Month;    /*!< Specifies the RTC Date Month (in BCD format)*/
  uint8_t Date;     /*!< Specifies the RTC Date*/
  uint8_t Year;     /*!< Specifies the RTC Date Year*/
} RTC_DateTypeDef;

四、初始化串口

#include "stdio.h"


int fputc(int ch,FILE *f){
 uint8_t temp[1]={ch};
 HAL_UART_Transmit(&huart1,temp,1,2);
 return ch;
}

五、验证代码

	  /* 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库中生成的代码,每次断电就RTC时间会重置,每次上电都会重新初始化时间。因为HAL库设置了一个BKP寄存器保存一个标志。每次单片机启动时都读取这个标志并判断是不是预先设定的值:如度果不是就初始化RTC并设置时间,再设置标志为预期值;如果是预期值就跳过初始化和时间设置,继续执行后面的程序所以这里我们只需要每次上电执行RTC初始化之前,将标志设置为预期值即可

在rtc.c中的RTC_Init修改为以下内容即可,但请注意,需要修改时间

/**
 * @brief       RTC时间设置
 * @param       hour,min,sec: 小时,分钟,秒钟
 * @param       ampm        : AM/PM, 0=AM/24H; 1=PM/12H
 * @retval      0,成功
 *              其他,异常状态
 */
HAL_StatusTypeDef rtc_set_time(uint8_t hour, uint8_t min, uint8_t sec, uint8_t ampm)
{
    RTC_TimeTypeDef rtc_time_handle;

    rtc_time_handle.Hours = hour;
    rtc_time_handle.Minutes = min;
    rtc_time_handle.Seconds = sec;
    rtc_time_handle.TimeFormat = ampm;
    rtc_time_handle.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
    rtc_time_handle.StoreOperation = RTC_STOREOPERATION_RESET;
    return HAL_RTC_SetTime(&hrtc, &rtc_time_handle, RTC_FORMAT_BIN);
}

/**
 * @brief       RTC日期设置
 * @param       year,month,date : 年(0~99),月(1~12),日(0~31)
 * @param       week            : 星期(1~7,0,非法!)
 * @retval      0,成功
 *              其他,异常状态
 */
HAL_StatusTypeDef rtc_set_date(uint8_t year, uint8_t month, uint8_t date, uint8_t week)
{
    RTC_DateTypeDef rtc_date_handle;

    rtc_date_handle.Date = date;
    rtc_date_handle.Month = month;
    rtc_date_handle.WeekDay = week;
    rtc_date_handle.Year = year;
    return HAL_RTC_SetDate(&hrtc, &rtc_date_handle, RTC_FORMAT_BIN);
}

void MX_RTC_Init(void)
{
	uint16_t bkpflag = 0;
	hrtc.Instance = RTC;
	hrtc.Init.HourFormat = RTC_HOURFORMAT_24; /* RTC 设置为 24 小时格式 */
	hrtc.Init.AsynchPrediv = 0x7F; /* RTC 异步分频系数(1~0x7F) */
	hrtc.Init.SynchPrediv = 0xFF;  /* RTC 同步分频系数(0~0x7FFF) */
	hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
	hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
	hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
	/* 检查是不是第一次配置时钟 */
	bkpflag = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0); /* 读取 BKP0 的值 */
	HAL_RTC_Init(&hrtc);
	if ((bkpflag != 0x5050) && (bkpflag != 0x5051)) /* 之前未初始化过, 重新配置 */
	{
	rtc_set_time(15, 46, 0, RTC_HOURFORMAT12_AM);/* 设置时间, 根据实际时间修改 */
	rtc_set_date(24, 2, 2, 5); /* 设置日期 */
	}
}

  • 26
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值