你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

改造RTC_HAL库函数,让STM32F1XX也具有完美的日历功能

[复制链接]
jz21zfr 发布时间:2020-6-2 13:03
改造RTC_HAL库函数,让STM32F1XX也具有完美的日历功能:+ V) `( r( L- s7 L9 W7 v
    STM32F103C8T6是大多数初学者的入门首选,CubeMX使得编程更加简单,但它的RTC只有时间可以正常使用,日历功能不完善。具体表现为掉电或重启后日期归0,恢复到2000年1月1日。RTC的秒计数器是32位的,在有后备电池供电情况下,应该可以连续计时136年。
, e4 l' I; {3 P经过分析CubeMX生成的stm32f1xx_rtc.c文件,涉及到日历的主要有下面4个函数:$ @% y8 P+ q' s9 z
HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format);+ }: l6 M% @' y0 R. m+ O
HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format);( n7 _+ b8 T2 `. v% t
HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format);4 w# I4 j3 J0 [  T# x
HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format);

7 z% S1 l) O" m9 W0 A" ~" r- @    在其中2条(HAL_RTC_GetTime和HAL_RTC_GetDate)中都有条“counter_time -= ( xxxx * 24U * 3600U);”语句,就是在计数值超过24小时(86400)后将RTC的秒计数器清0,日期只单纯的做加一操作,且只保存在内存中。所以掉电后日期就归0了。虽然有介绍用RTC的后备存储器保存日期,在适当的时候取出。但这个方法并不适用于那些不定时开关机的场合,比如周五关机,周一再开机,因为日期没有及时更新,而还是两天的日期。& e$ Q8 K/ z  |5 |, [, ?! w* I
    于是本人对这4个函数进行了改写,在不影响其它(如闹钟)功能的前提下,完善日历功能。经试用基本满意,用法及参数规则和原函数一致:在主程序中用HAL_RTC_SetTime和HAL_RTC_SetDate设置时间及日期,用HAL_RTC_GetTime和HAL_RTC_GetDate获取时间及日期。* C7 t# k- Z( d: x+ {% Y/ h) t' G
    下面有改造好的stm32f1xx_hal_rtc.c文件,只要在编译器中用本文件的内容替代原stm32f1xx_hal_rtc.c的全部内容即可。也不用担心会出现其它问题,如果不想要,只需在CubeMX里重新“GENERATE CODE”就还原了。另外在rtc初始化MX_RTC_Init()函数里也不需要作任何处理。只保留0 D5 K) w  L% D% S
  hrtc.Instance = RTC;7 w) u1 Q' ^3 O% \* Y; ]% f
  hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;6 N0 e- c2 w. H0 e1 h9 J
  hrtc.Init.OutPut = RTC_OUTPUTSOURCE_ALARM;* h4 B# m: U8 A$ k4 m" ]" S
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
- P) c$ E) H5 E: N& j% a% k" p# G  {: @  m, t, T5 T4 q  J2 l' x0 o
    Error_Handler();

! R5 A8 v% B4 {4 N0 L  }  其它可以删除。

* K& K9 P) l, A. l4 e& }" t4 Q  e' X+ S
/ v# E, V# F7 _% F- }' m% v
收藏 3 评论7 发布时间:2020-6-2 13:03

举报

7个回答
jz21zfr 回答时间:2020-6-2 13:18:55
欢迎大家试用,并交流。( H3 O7 L, H" q; [
附件:4 g6 f9 \6 g, W! V

/ w) ~3 H1 a3 G8 o

stm32f1xx_hal_rtc.c.rar

下载

10.66 KB, 下载次数: 181

李康1202 回答时间:2020-6-3 08:57:19
谢谢分享
: A, a# h  ]$ _0 V, w
huyongtao1 回答时间:2020-7-23 15:42:38
保存是保存了,可是为啥日期设置后变为了2032/08/04号了。我的做法是将你的stm32f1xx_rtc.c替换掉。日期却乱了
jz21zfr 回答时间:2020-8-3 17:46:33
huyongtao1 发表于 2020-7-23 15:42; n, N) Z* r( v5 J. s0 E
保存是保存了,可是为啥日期设置后变为了2032/08/04号了。我的做法是将你的stm32f1xx_rtc.c替换掉。日期却 ...
是在编译器中,先删除stm32f1xx_rtc.c的全部内容,然后再将下载的stm32f1xx_rtc.c文件的全部内容复制粘贴过去。注意HAL_RTC_SetDate语句的用法。如果有备份电池,单片机重启后,日期应该不会改变。如果没有,日期会变回2000年1月1日。
Yogo 回答时间:2021-1-5 16:09:26
jz21zfr 发表于 2020-8-3 17:46
. H2 Z) n8 F% L) x' U; n7 A1 Z+ y是在编译器中,先删除stm32f1xx_rtc.c的全部内容,然后再将下载的stm32f1xx_rtc.c文件的全部内容复制粘贴过 ...

4 K* \+ J4 ]. j( |! l( P很感谢楼主的分享,这方法只有楼主作,其他不曾看过。: N2 q9 ~' F, C% f9 X- E) i0 f
年份跟4楼一样,HAL_RTC_SetDate(&hrtc, &RTC_Date, RTC_FORMAT_BCD),写0x20读出来会变成0x32;写0x14读出来会变成0x20。) _# y6 V& d4 t! p! X
7 n, ]2 ^( o6 A9 Q* [
STM32CubeMX 6.1.1 + STM32F1 Serial 1.8.3
kylixyao 回答时间:2021-1-5 18:07:42
谢谢分享
zhuser 回答时间:2022-4-1 15:52:22

HAL_RTC_SetDate()里,要改为以下代码才可以避免日期设定的错误


for(loop = 0; loop DateToUpdate.Year; loop ++) //累计所有年份的天数 { if(RTC_IsLeapYear(loop + 2000))days += 366; //润年366天 else days += 365; //平年365天 } for(loop = 1; loop DateToUpdate.Month; loop ++) //累计今年已过月份的天数 { if((loop == 1)||(loop == 3)||(loop == 5)||(loop == 7) ||(loop == 8)||(loop == 10)) days += 31; //大月31天 else if((loop == 4)||(loop == 6)||(loop == 9)||(loop == 11))days += 30;//小月30天 else if(loop == 2) { if(RTC_IsLeapYear( hrtc->DateToUpdate.Year+2000))days += 29; //闰年二月29天 else days += 28; //平年二月28天 } } days += hrtc->DateToUpdate.Date - 1; //总天数

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版