环境:

Stm32CubeMX V5.6.0

stm32F412RETx芯片,芯片的VBAT引脚接电池

RTC使用的外部晶振,内部的振荡器配置后断电后不跑,原因未知,下面直接上使用外部晶振的方案


配置RTC使用外部晶振,外部晶振是32.768KHz的

配置RTC,启用日历和时钟

stm32CubeMX默认填入的分频是使用32.768KHz的,但是内部振荡器是32KHz的,所以估计都是推荐使用外部晶振,使用内部振荡器的自己按公式重新计算分频值

公式如下:

RTC时钟频率 = RTC时钟源 / ((Asynchronous Predivider value + 1) * (Synchronous Predivider value + 1))

套用一下公式

32.768KHz / ((127+1)*(255+1)) = 1Hz,也就是1秒

年是从1970年算起的,其他月日时分秒以及24或者12小时制没什么好说的

数据格式Data Format,我使用Binary data format

stm32定义了RTC_FORMAT_BIN和RTC_FORMAT_BCD两种格式

RTC_FORMAT_BIN:为10进制,RTC_FORMAT_BCD为16进制,开始我也是这样认为的,然后并不是

看一下stm32f4xx_hal_rtc.h头文件中对月份的定义:

/** @defgroup RTC_Month_Date_Definitions RTC Month Date Definitions* @{*/
/* Coded in BCD format */
#define RTC_MONTH_JANUARY              ((uint8_t)0x01)
#define RTC_MONTH_FEBRUARY             ((uint8_t)0x02)
#define RTC_MONTH_MARCH                ((uint8_t)0x03)
#define RTC_MONTH_APRIL                ((uint8_t)0x04)
#define RTC_MONTH_MAY                  ((uint8_t)0x05)
#define RTC_MONTH_JUNE                 ((uint8_t)0x06)
#define RTC_MONTH_JULY                 ((uint8_t)0x07)
#define RTC_MONTH_AUGUST               ((uint8_t)0x08)
#define RTC_MONTH_SEPTEMBER            ((uint8_t)0x09)
#define RTC_MONTH_OCTOBER              ((uint8_t)0x10)
#define RTC_MONTH_NOVEMBER             ((uint8_t)0x11)
#define RTC_MONTH_DECEMBER             ((uint8_t)0x12)/** @defgroup RTC_WeekDay_Definitions RTC WeekDay Definitions* @{*/
#define RTC_WEEKDAY_MONDAY             ((uint8_t)0x01)
#define RTC_WEEKDAY_TUESDAY            ((uint8_t)0x02)
#define RTC_WEEKDAY_WEDNESDAY          ((uint8_t)0x03)
#define RTC_WEEKDAY_THURSDAY           ((uint8_t)0x04)
#define RTC_WEEKDAY_FRIDAY             ((uint8_t)0x05)
#define RTC_WEEKDAY_SATURDAY           ((uint8_t)0x06)
#define RTC_WEEKDAY_SUNDAY             ((uint8_t)0x07)

比如12月份RTC_MONTH_DECEMBER的值是等于0x12的,转成10进制等于18,也就是RTC_FORMAT_BCD也不是16进制,只是用了16进制的样式,0x12不看0x直接看数字部分,就是12月份

再来看看stm32内部的两种格式的转换函数

/*** @brief  Converts a 2 digit decimal to BCD format.* @param  Value Byte to be converted* @retval Converted byte*/
uint8_t RTC_ByteToBcd2(uint8_t Value)
{uint32_t bcdhigh = 0U;while(Value >= 10U){bcdhigh++;Value -= 10U;}return  ((uint8_t)(bcdhigh << 4U) | Value);
}/*** @brief  Converts from 2 digit BCD to Binary.* @param  Value BCD value to be converted* @retval Converted word*/
uint8_t RTC_Bcd2ToByte(uint8_t Value)
{uint32_t tmp = 0U;tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10;return (tmp + (Value & (uint8_t)0x0F));
}

转换函数代码自己看不说明,总之觉得很奇怪的用法

配置完成,生成工程

找到static void MX_RTC_Init(void)函数,在 HAL_RTC_Init后,使用RTC的后备寄存器保存是否初始化过时间的标志,RTC的后备寄存器也是后备电源供电的,所以主电源断电后数据还在,也可以用这些寄存器保存数据,读写函数如下:

void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data);
uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister);

MX_RTC_Init函数修改如下:

static void MX_RTC_Init(void)
{/* USER CODE BEGIN RTC_Init 0 *//* USER CODE END RTC_Init 0 */RTC_TimeTypeDef sTime = {0};RTC_DateTypeDef sDate = {0};/* USER CODE BEGIN RTC_Init 1 *//* USER CODE END RTC_Init 1 *//** 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 */// 检查后备寄存器uint32_t iSetFlag = 0x5053;// 这个0x5053值自己随意if(iSetFlag != HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0)){   ///* USER CODE END Check_RTC_BKUP *//** Initialize RTC and set the Time and Date*/sTime.Hours = 9;sTime.Minutes = 45;sTime.Seconds = 0;sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;sTime.StoreOperation = RTC_STOREOPERATION_RESET;if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}sDate.WeekDay = RTC_WEEKDAY_WEDNESDAY;sDate.Month = RTC_MONTH_MAY;sDate.Date = 13;sDate.Year = 50;if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}/* USER CODE BEGIN RTC_Init 2 */// 设置完时钟,设置标志HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR0, iSetFlag);}else{        }{// 获取一次时间显示RTC_TimeTypeDef sTime;HAL_StatusTypeDef status = HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);RTC_DateTypeDef sDate;status = HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);printf("MX_RTC_Init:Date time: %d-%02d-%02d weekData:%d %02d:%02d:%02d\r\n"                   , 1970 + sDate.Year, sDate.Month, sDate.Date, sDate.WeekDay, sTime.Hours, sTime.Minutes, sTime.Seconds);}/* USER CODE END RTC_Init 2 */}

获取时间日期HAL_RTC_GetTime和HAL_RTC_GetDate有要求先后顺序的,看函数定义处的说明:

You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values in the higher-order calendar shadow registers to ensure consistency between the time and date values. Reading RTC current time locks the values in calendar shadow registers until Current date is read.

上google翻译的结果:

必须在HAL_RTC_GetTime()之后调用HAL_RTC_GetDate()才能解锁高阶日历影子寄存器中的值,以确保时间和日期值之间的一致性。 读取RTC当前时间将锁定日历影子寄存器中的值,直到读取当前日期为止。

基本配置完成,断主电源后,在次上电,查看输出的时间是正常的

我用F103芯片配置过,发现F103的芯片日期断电后就没有了

参考:

https://blog.csdn.net/qq_24381977/article/details/94460855

Stm32CubeMX配置RTC时钟相关推荐

  1. STM32CubeMx配置H7时钟: Frequency searched for is out of range for this vos range

    问题提出 配置时钟树的时候主频想设置到400Mhz,点击快速设置,按下回车,出现了Frequency searched for is out of range for this VOS range 但 ...

  2. STM32 RTC时钟掉电日期不更新

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

  3. stm32 RTC时钟配置

    stm32--RTC实时时钟 一.关于时间 2038年问题 在计算机应用上,2038年问题可能会导致某些软件在2038年无法正常工作.所有使用UNIX时间表示时间的程序都将将受其影响,因为它们以自19 ...

  4. STM32如何计算RTC时钟异步预分频和同步预分频

    实时时钟 (RTC) 是一个独立的 BCD 定时器/计数器,提供具有可编程闹钟中断功能的日历时钟/日历,可用于管理所有低功耗模式的自动唤醒单元.在配置RTC时钟时预分频器是关键指标,通过配置预分频器可 ...

  5. RTC时钟学习总结附带其他小总结

    RTC时钟 一.RTC时钟的简介 二.RTC的具体配置 1.对应的时钟图 2.RTC配置一般步骤 3.RTC特征 ①闹钟中断 ②秒中断(常用) ③溢出中断(应该不常用) 3.主函数中的使用 未解决的问 ...

  6. RTC时钟实现实时日历

    文章目录 1.RTC时钟简介 1.2.初识RTC 1.2.相关寄存器 2.创建项目2 3.完善代码 4.总结 1.RTC时钟简介 1.2.初识RTC 1.简介: RTC-real time clock ...

  7. STM32CubeMX | STM32 F1系列HAL库低功耗STOP和STANDBY模式唤醒(RTC时钟唤醒+外部中断唤醒示例)

    STM32CubeMX | STM32 F1系列HAL库低功耗STOP和STANDBY模式唤醒(RTC时钟唤醒+外部中断唤醒示例) 目录 STM32CubeMX | STM32 F1系列HAL库低功耗 ...

  8. STM32 RTC时钟掉电日期不更新 STM32 HAL库RTC时钟配置

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 STM32 RTC时钟掉电日期不更新 & STM32 HAL库RTC时钟配置 一.STM32CubeMX RTC配置 二.RT ...

  9. 火牛单片机rtc时钟配置_怎么用STM32F103RTC进行时钟的配置

    #include "sys.h" #include "delay.h" #include "usart.h" #include " ...

最新文章

  1. ​每日一皮:​你的Frozen Throne...
  2. winform 日期控件放在工具条(先放一个label 占好位置)上。工具条和其他控件都要求有鼠标的精准。...
  3. tomcat不能多次startup.sh,异常时直接,分析logs目录下的日志。
  4. numpy将bool值转换成数值
  5. sentinel 端口_Spring Cloud Alibba教程:Sentinel的使用
  6. (OS 64)指定的网络名不再可用,winnt_accept: Asynchronous AcceptEx failed.
  7. Codeforces 120F Spiders
  8. 漫话:如何给女朋友解释什么是 3PC?
  9. 加密芯片在汽车无钥匙启动行业的应用
  10. OPENSSH升级为7.4
  11. 网站项目建设流程概述
  12. 2013第44周日小结
  13. 算法笔记--卢卡斯定理
  14. 熊猫烧香病毒作者再被捕 开网络赌场敛财
  15. 追赶法源程序c语言,追赶法求三对角线方程组程序设计.doc
  16. PHP字符串解析函数
  17. 邮件合并保存为一个个单独的文档_用【邮件合并】提升10倍高效生产力
  18. 谷歌浏览器清除dns缓存
  19. Neo4j【有与无】【N4】构建图形数据库应用程序
  20. php php_sapi cli,php_sapi_name() cli

热门文章

  1. SSH_maven_me
  2. flash cs5 as3.0 基础
  3. 【Linux进程、线程、任务调度】三 CPU/IO消耗型进程 吞吐率/响应 SCHED_FIFO算法与SCHED_RR算法 SCHED_NORMAL算法和CFS算法 nice与renic chrt
  4. 世界上最流行的脚本-JavaScript,看过不会来找我
  5. 为什么游戏叫第九艺术?
  6. 物体监测:Sliding Window
  7. 人工智能是从什么起源的
  8. workbench应力应变曲线_利用ansys Workbench仿真塑性材料拉伸力学试验 | 坐倚北风
  9. 【软件设计师】程序设计语言与语言处理程序
  10. 基于SSM开发个人财务管理系统