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

解决RTC时钟在TouchGFX中被切换时重置的问题

[复制链接]
电子烂人 发布时间:2024-12-27 14:44
之前用F746板卡做的工程有些问题,在切换页面的时候,时钟模块会被重置,这次加上RTC来解决这个问题。
+ X/ K* R. |; R2 Z& k([基于stm32f746的智能冰箱实物设计 (stmicroelectronics.cn)](https://shequ.stmicroelectronics.cn/thread-643676-1-1.html))
9 U) F# e3 H3 M* @% ~7 q9 }/ k 微信图片_20241227143242.png
3 v, S/ e/ ^% R; m1 N2 {之前项目里的时钟是用一个counter慢慢累加:; C% m2 t7 h, v! n' C% k2 l1 y0 V
  1. void timeView::setupScreen()5 D; U8 ~$ s: m9 r: x+ ?
  2. {7 ]. S4 q+ A- ?7 x- \& k8 [
  3.     timeViewBase::setupScreen();$ W, J7 l6 V" g7 b. X3 S& \% _, Y
  4.     digitalHours = digitalClock1.getCurrentHour();
    ) F" T# @# u! T+ ]7 q
  5.     digitalMinutes = digitalClock1.getCurrentMinute();. S9 T( o( Q8 J) g0 y
  6.     digitalSeconds = digitalClock1.getCurrentSecond();
    : Z/ k) e+ ?* r# U1 ^! Y' A
  7. }
    6 F: l$ Z  v  I. u

  8. + l) J$ A# W: D  }2 p. H
  9. % r/ L# s6 F# E: G
  10. void timeView::handleTickEvent()% W8 y, J4 T. _' l
  11. {
    - a* P3 q& z5 e1 ]
  12.     tickCounter++;+ S) ~. j% H5 [# v

  13. # p6 f6 o; n9 K& K
  14.     if (tickCounter % 60 == 0)9 ?- [: ]7 x% D% D7 w6 o
  15.     {
    , \% \' P! U* M" B; B
  16.         if (++digitalSeconds >= 60)
    0 p( d& m' ^7 E) Y5 {0 t* T
  17.         {
    4 G# L4 {; a% U* u
  18.             digitalSeconds = 0;
    7 t. z( m) y1 [* Y+ g( N4 a
  19.             if (++digitalMinutes >= 60)# |7 ^5 O5 f* K$ \; _; [- t
  20.             {6 R, m; N: \7 f' |' S
  21.                 digitalMinutes = 0;7 f( U/ B+ Y* ?: g+ Y
  22.                 if (++digitalHours >= 24)$ o/ O" F4 o" O, [: e( e
  23.                 {7 l% q  v" Z+ H7 k7 x
  24.                     digitalHours = 0;
    * h! e5 T! c; ^; N
  25.                 }
    0 T% n# m$ H! a' v7 `0 ?, N* \3 M0 r
  26.             }' r2 U) ?6 b; R
  27.         }6 a- y5 r9 v! M+ }5 V
  28. 1 S* _# J$ ?3 i: i  y7 A5 j% D0 A& u
  29.         // Update the clock, L& r+ S) Y9 H  g
  30.         digitalClock1.setTime24Hour(digitalHours, digitalMinutes, digitalSeconds);
    ' n; s" O3 C& }+ u. u7 x, k. R! a
  31.     }
    ; b; o; l2 }% ^; K( c: i# K3 b( t
  32. }
复制代码
虽然可以达到数字时钟的效果,但是当翻页的时候,时钟就会被清除重新计数,1 c, K, z! s) e
项目用FREERTOS开发,在里面设置进程间通信特别复杂,要解决这个问题,更快捷的方法是在这部分中添加RTC时钟。. z7 c4 R: y" t" \. I% a
在RTC中使能并设定好时间:
  C" |$ Y9 I6 y8 w9 R- J+ _ 微信图片_20241227142423.png ( S! I9 D" c# U; Z9 ~0 _  k# V" H7 N
对应的程序也要需要重写一下:7 U2 C4 ?, c  n9 Y+ J; _
首先要在modelListener.hpp里添加RTC相关函数:
, g& R$ e5 H/ C/ h  ~) |: L
  1. virtual void updateTime(uint8_t hour, uint8_t minute, uint8_t second) {}
复制代码
然后,在MODEL.C中,把主函数的RTC TIME和DATE拉过来(注意要两个一起,不然会有BUG),并传参给updateTime函数。2 o, u( y/ f" m" b- B; L
  1. extern RTC_TimeTypeDef RTC_Time;
    8 ^! d& h, P9 n9 Q$ z* ~
  2. extern RTC_DateTypeDef RTC_Date;
    " G5 J( A% n! h& V- T  G
  3. extern RTC_HandleTypeDef hrtc;, r/ ]6 K* I: b: f6 Y! E5 M

  4. - i4 R# K5 L+ p: f
  5. Model::Model() : modelListener(0)
    1 R' n: s" z0 M) }+ k7 E
  6. {: o1 r1 V9 |% r* X  @2 B! Z  i

  7. 6 k) C; ]/ A  m1 V: A% I0 Z
  8. }& T+ I: z2 t# f

  9. # K+ }! s) G) F1 a- P% ?; J0 U
  10. void Model::tick()
    * u2 I: L' X; y! y$ z
  11. {0 B4 _! Q" r8 K1 l
  12.         HAL_RTC_GetTime(&hrtc, &RTC_Time, FORMAT_BIN);
    $ ~1 `+ D0 H+ b4 S$ ]! d
  13.         HAL_RTC_GetDate(&hrtc, &RTC_Date, FORMAT_BIN);1 `  M& P( q; _# J8 z3 H! `$ h
  14. 5 |3 ]' R( q6 X4 `& C
  15.         modelListener -> updateTime(RTC_Time.Hours, RTC_Time.Minutes, RTC_Time.Seconds);! b5 e7 H* Q! W5 w" R2 o8 I& k1 r
  16. }
    0 W! l6 |2 e/ M' @
复制代码
不要忘了在time里也要再定义一次updateTime函数:
2 G8 f) V3 Y$ L6 Y: v
  1. void timePresenter::updateTime(uint8_t hour,uint8_t minute,uint8_t second)0 o; C8 r: C/ T+ M
  2. {) R3 x% ~& `% k$ f' U9 D1 @" f
  3.         view.updateTime(hour,minute,second);8 b% s& @: j- z7 A" r0 d
  4. }6 j5 ?1 C/ L' {& c6 A
复制代码
对应的.hpp文件也要定义一次:( u8 j/ Y8 L5 o% f: \
  1. void updateTime(uint8_t hour,uint8_t minute,uint8_t second);
    ' {, |# i4 _7 b5 c4 ^
复制代码
最后,在screenView.C中修改,把其他几个全部注释掉,只留存累加器,并在开始累计之前就获取一次时间
" m9 f5 o! A$ x0 F
  1. void timeView::setupScreen()9 ~5 N% w( }) ]) J4 t3 p
  2. {
    ! K" v8 T2 W% t# V) C( g
  3.     timeViewBase::setupScreen();) ]* l( m4 S, E/ H# `! e% T
  4.     //digitalHours = digitalClock1.getCurrentHour();
    ) U' r" Y( o! i/ B6 n  ~
  5.     //digitalMinutes = digitalClock1.getCurrentMinute();) g5 x! [+ {, V! g, X
  6.     //digitalSeconds = digitalClock1.getCurrentSecond();
    7 f; T1 i3 J1 b9 R) G
  7. }
    . c4 l  r* t/ g+ ^  `; L
  8. , v2 ?2 L. G& P$ I; X/ U
  9. 2 x0 a) i- v( B$ O
  10. void timeView::updateTime(uint8_t hour,uint8_t minute,uint8_t second)
    # G  U6 P' [5 P# ^+ J0 x& w" E
  11. {5 Z' W( A0 ^0 |. x& ~! k. a: A
  12.          // Update the clock
    1 N3 w1 C+ e: W( t6 n& N
  13.         digitalClock1.setTime24Hour(hour,minute,second);
      `) w# K/ m! h5 b1 c" ?5 }

  14. 5 v) l4 o6 l( n2 a/ r- s9 J9 ^
  15.     tickCounter++;1 p: ^* Q5 G" p, m
  16. % S/ O3 C. A  P, M7 [
  17.     if (tickCounter % 60 == 0)5 D( }6 H+ i; ]) Y1 B3 [3 W, u6 p- r
  18.     {  d/ W  a, b; Z: I, e
  19.         if (++digitalSeconds >= 60)
    ' x) Z6 M* g, k0 K; ]/ J
  20.         {
    1 a7 h, o. o# H" M7 j
  21.             digitalSeconds = 0;2 o6 H9 u+ l+ {' g  f4 I/ ?  ?
  22.             if (++digitalMinutes >= 60)
    ( J; x* W! n# y" p: M4 b% x
  23.             {5 h8 y$ }4 i% l
  24.                 digitalMinutes = 0;
    ; i0 J3 K% f. d8 i
  25.                 if (++digitalHours >= 24)( u. _* r: f) W5 m+ W1 D* Q
  26.                 {
    7 l( L1 c/ ~  E# L# @$ B
  27.                     digitalHours = 0;4 [- g1 G- X3 f: p( i2 L
  28.                 }! i/ Q2 H( p* b( h/ ?+ h3 _8 M
  29.             }
    $ [3 V$ F2 Q0 W
  30.         }
    . ^. v! e. v" K- ~0 D! Y
  31.         }
    2 X' n6 g! @/ O4 @; d* t

  32. 1 B% E; z/ u, J) ]3 m3 ?

  33. # P# ^3 w+ I  V& ]+ Q5 |% W% x
  34. }
复制代码
对应的,hpp里也要修改:( N$ Q0 s9 L% N2 D
  1. #ifndef TIMEVIEW_HPP
    3 F$ x* s( I2 ]. Z4 {# K5 x
  2. #define TIMEVIEW_HPP
    4 x1 y& ]/ Z0 U8 ~
  3. 4 T4 ~0 L) e3 d/ [
  4. #include <gui_generated/time_screen/timeViewBase.hpp>" o2 x) r( ^1 N+ W7 @
  5. #include <gui/time_screen/timePresenter.hpp>% d7 m' x0 _' U  q3 W
  6. 6 }4 B! a3 s4 ]$ y: S
  7. class timeView : public timeViewBase6 ~  \4 l" O) F
  8. {
    ) V7 ~  I6 _/ t
  9. public:
    # G$ a6 q: A/ U" U8 p/ k' j* G
  10.     timeView();
    ! z6 k& {: o* [& a/ K
  11.     virtual ~timeView() {}! |5 g9 J( I/ y! X2 e
  12.     virtual void setupScreen();
    ! Q! g) E/ d5 {, c1 v: }
  13.     virtual void tearDownScreen();
    + @3 w) f3 @5 Z; [% b" b) G
  14.     virtual void updateTime(uint8_t hour,uint8_t minute,uint8_t second);3 r, Y2 D1 {7 d7 V1 Q$ R! I. o
  15. protected:7 g4 T$ O3 I: L
  16.     int tickCounter;- G, h0 K8 v& O
  17.     int digitalHours;
    ; V' @  m3 d: s* d1 h4 c4 e' s3 G
  18.     int digitalMinutes;
    9 d( n3 @- G5 L4 h! c+ n  O
  19.     int digitalSeconds;
    , G7 m# q4 Q( Y' Z4 a# ^
  20. };
    2 `7 l) j. P/ m
  21. 0 k# A; a. m$ B$ r9 ^% [- `
  22. #endif // TIMEVIEW_HPP
    & l) F! H( X8 i
复制代码
1 R; k$ r, n" C3 G* A, {
这样就可以在TOUCHGFX中引入RTC时钟,也不会出现换页面时清零数字时钟的问题了。
6 v  y. ?2 c  x; l2 }1 d' `" T* c0 X% J& K) s3 k, v" o
最终效果:0 b% S2 N8 p# }5 p2 d  u1 I
. C0 K5 E5 [/ `- j8 L, E

, A1 p6 B: e8 q: u: ^' ^, S0 A- H5 w4 O3 ^+ Q
+ j& z" n) T% |' _
% y  x8 I) A; `. ?" j
赞 收藏 评论0 发布时间:2024-12-27 14:44

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版