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

STM32 TouchGFX 部分控件测试备忘

[复制链接]
STMCU小助手 发布时间:2022-8-21 21:46
微信图片_20220821214635.png
' _; M% o  ]/ W+ x4 G. L
ST公司推出的用于图形界面开发的 TouchGFX Designer已经升级到4.20了。这两天我利用手头的STM32F429Discovery板对Touchgfx提供的部分控件功能做了些测试,把这个过程中遇到的一些问题做些整理,以备忘并顺便分享。

: x6 X* u/ K; W/ p6 f
我这次主要测试了TextArea,界面按键响应、动态图形【dynamic graph】、模拟时钟【Analog Clock】、进度条显示以及软件上添加虚拟函数的实现。涉及的界面有下面几个:【仅为测试,界面美丑略过】

2 q4 \6 b( r1 ^
微信图片_20220821214629.png
微信图片_20220821214625.png
微信图片_20220821214622.png
微信图片_20220821214617.png
4 L7 S* b$ a% k( |" p
第一个要注意的地方。
我使用的IDE是STM32CubeIDE。当我在相应hpp头文件里添加虚拟函数声明时,需要在IDE环境里专门对该头文件做个save操作,不然在cpp函数里写好相应函数后编译时总提示没有做函数声明。 举个例子说下,比方我要在Screen1View.cpp写一个IncDuty()函数。
# }: |/ _3 x1 v" l- A
微信图片_20220821214614.png
, @  s9 H  r% x0 ?! ^0 |
我们需在其对应的头文件里加上虚拟函数的声明。在头文件里添加了该虚拟函数声明后,需要手动对该文件做个SAVE操作【File菜单下选择Save】,否则老是编译出错,提示函数无声明,即像下面提示:
微信图片_20220821214604.png
7 B/ o# G% A" k) T9 M% U
但别的cpp文件修改后倒不用单独做save操作,直接编译即可。这个地方因为要操作的文件较多,我多次忘记,直到编译提醒才知道。【不知该问题是否跟IDE有关?我没测试别的IDE。反正提醒下吧。】

; N& B4 b& O3 {' R& S
第2个要注意的地方,我这里通过TouchGFX designer的文本区域控件【textarea】显示STM32的某通道ADC转换值,用到了浮点。

: A% v6 R( N$ R6 f
微信图片_20220821214600.png

" s; u! Q# X! n+ ]
刚开始我用的是这个函数:
Unicode::snprintf(textArea1Buffer, TEXTAREA1_SIZE, "%f",AdcResult);

, q8 P  w* H3 d+ J  M
结果总是出不来,但当我将AdcResult改为整型变量,通过%d可以显示正确结果。先怀疑过IDE方面浮点功能相关配置,经检查没问题。后来到TouchGFX在线服务站点搜索snprintf才有新的发现,如下图所示:
# U: K. L+ L" f6 m
微信图片_20220821214557.png
. [( y; R; ~8 _7 L% O8 ~( y
看来我的函数用错了,使用浮点有另外一个输出函数,即:
Unicode::snprintfFloat(textArea1Buffer, TEXTAREA1_SIZE, "%2.4f", AdcResult);

1 r5 b4 R+ L3 f2 U# I" c3 J. J
第3个要注意的地方,也是跟上面textarea输出显示有关的问题。

3 p* l) }" a; G& q9 Z8 u8 L
微信图片_20220821214552.png
5 G7 C: E0 f$ D& y6 s, p, o
在它的属性那里有个Auto-size的选项,勾选与不勾选的实现代码是不一样的。一般为了简单点,可以不做勾选,自己手动拉个合适大小的框来显示字符及数据。比方还是以上面显示ADC输出电压值为例,其实现代码如下:
  1. void Screen2View:: DispAdcValue()
    + S. Z$ y' |) E
  2.   C1 e0 U! e  ?) B
  3. {
    % ]- a& `  G6 R$ U

  4. + |/ H1 D  u( Q
  5. Unicode::snprintfFloat(textArea1Buffer,TEXTAREA1_SIZE,"%2.4f", AdcResult);
    + V9 j/ X9 d4 \0 r
  6. 6 I% |& P- D( [5 J/ U
  7. //textArea1.resizeToCurrentText();
    * i* e  M) W8 {, O
  8. ! n& v% r% j8 ~" L2 ~
  9. //memset(textArea1Buffer,'\0',strlen(....) );- {& d# W& K/ U+ C6 f
  10. , G5 ^* J# a' q8 y! U- D
  11. textArea1.invalidate();; C  W* [$ }1 f' g. }

  12. 4 k3 `4 e! `) Z& n7 m. l
  13. }
复制代码

5 m% {8 `9 e; N6 T# g& q7 X* N1 y
如果说你希望勾选,你的代码就将上面的屏蔽语句加上即可,有兴趣可以自行试试。
8 A2 W0 f" _; J& w3 V" ?. O8 U, l& ~, n# A
再就是那个动态图形显示那个地方,显示的点数及修改样点值的频率都是可以调整的。我这里是让它动态显示一路PWM输出的方波,为了实现它,我在这个地方做了些来回调试才实现比较好的效果。

8 ]6 ~7 R( @) L5 a/ @+ A6 ]
另外,我在组织模拟时钟代码时遇到的一个小问题。我用到Model::Tick里的modelListener功能。

: m8 @  v) h" W1 [7 `
有个地方本来应该是view.UpdateClock(hours,minutes,seconds);我看库里面绝大部分单词的首字母都是大写的,我就惯性地将view的首字母写成大写V了,编译没有直接提示出错,但就是结果出不来。这里各种API函数很多,初次使用者对他们都较陌生,这种比较隐蔽的问题难免会碰上。
% Q7 j- V% E4 @- L
( C3 ^6 `6 ?- P/ D! {% E" _
我顺便把测试中用到的几个跟GUI这边有关的函数实现代码也贴过来,供有需要的人参考。
  1. modelListener->UpdateClock(sTime.Hours,sTime.Minutes,sTime.Seconds);# n* ?2 K4 s2 |* R& s5 D6 w
  2. 9 G1 r* A& l( M
  3. ( Q+ Z" g/ D3 g# t' r

  4. ; `. B; }5 z; |9 m( q4 }3 }! H
  5. analogClock1.setTime24Hour(sTime1.Hours,sTime1.Minutes, sTime1.Seconds);
    7 j- ]" x6 p: U1 p& A: `

  6. . s5 L" v" `7 x0 H" n' V" D# v9 m

  7. * r! J. R8 G9 j9 m5 d1 `0 Y

  8. * ^( ]5 M3 y- v8 w: Z8 F$ s
  9. void Screen2View:: DispAdcValue()//基于textarea控件固定宽度显示数据
    $ U& p9 U8 t; n7 p

  10. ( |6 b3 O1 t# }
  11. {
    ) g3 v2 q6 N/ z- R" H0 A

  12. - X" H) r. K$ }/ A, }& V
  13. //Unicode::snprintf(textArea1Buffer, TEXTAREA1_SIZE, "%d?u?s?", AdcResult);
    - p" [9 t" {4 s+ j! E
  14. ( s3 g! U: U, a4 P
  15. 4 r+ @8 C2 g$ p3 v( u4 h' z

  16. ( S2 s; d* ]: W% f% i: j, r. n  G0 |! A
  17. Unicode::snprintfFloat(textArea1Buffer, TEXTAREA1_SIZE, "%2.4f", AdcResult);
    " Y1 J- j9 h6 b5 h. P

  18. ; x) ~3 t) w* ?
  19. //textArea1.resizeToCurrentText();5 K: A4 X4 B) c( @3 b" e7 Z

  20. . u8 Z& `7 ]  m$ g* J& d
  21. //memset(textArea1Buffer,'\0',….. );( q" w' r5 T; T* ~  T
  22. 0 p0 s! I; W! d
  23. ) o/ A  Y: R! L

  24. & C% O0 V2 |/ m) J, u, ^
  25. textArea1.invalidate();3 w, q: B4 j7 O' h
  26. - A' S* U+ t3 U1 P
  27. }7 R" S7 C0 Y) j8 F3 _! Y
  28. & L. L3 Q+ e! S% m1 v8 h
  29. 4 n& O4 F0 A9 \) ^' m/ F+ P1 {% [
  30. ( X  |0 w; \1 `/ n" n. z
  31. void Screen3View::UpdateCnt() //For progress Bar6 W+ b( _. t. R( b; A

  32. , ?6 d! }+ S, k3 N* ^6 e. Y. N8 ]
  33. {
    4 k7 g! e/ H$ i! }- }2 B. n  _
  34. 4 i4 i8 I$ f! M* C
  35. if (UpdateCNT > 2000) {UpdateCNT = 0;}
    5 O8 F# `# S( o3 U) S! X+ a
  36. * e; i, n/ S6 N1 w& {2 q! H4 A
  37. //UpdateCNT comes from Timer Interrupt. H% @0 r0 b3 e+ i
  38. 7 X7 \$ Q5 d, E, p0 p, w
  39. textProgress1.setValue(UpdateCNT);
    4 Y- \9 O' \! v5 {- G3 [! F: T, \

  40. 4 m( H' `( O# K! \# @
  41. circleProgress1.setValue(UpdateCNT);
    , `  {  I5 T7 ^1 K
  42. 6 Z; I( _( K* V0 e' r
  43. imageProgress1.setValue(UpdateCNT);7 K7 b$ o* }: X

  44. 8 H  n4 X1 V# L. W( A
  45. }
    ! }7 F# @3 f3 T0 d
  46. 1 p2 V9 ]% o) ^9 @( t
  47. 7 D  S+ ?% s1 }  u
  48. 1 X! i% \& @$ N5 J) m
  49. void Screen1View::IncDuty() //For TIM3-CH18 t3 S! x7 G% ~

  50. ' C1 o! P/ ~- g, d0 R
  51. {3 M: t* {% f# D
  52. , S  I" v2 j6 P/ w) t
  53. CCRValue+=100;4 M2 ?# I. m0 J2 n# U) S% \

  54. 0 W% _! h0 j- I9 k' u
  55. if (CCRValue > 50000)
    $ O' |; v+ ?9 ]; Y1 N( a

  56. 7 I, A' q5 }+ b) {6 p
  57. {. a) V' P# G% f

  58. ) Y$ H) X4 w# v# K; M  r0 T
  59. TIM3->CCR1 = 50000;
    4 C: c5 F7 f2 C3 Y$ _' \
  60. - [; ]5 m+ |: ?% }# c
  61. }0 d- K% r0 x" M2 z" e
  62. & o. |1 \; V' ~, x2 X" Z
  63. else) |$ e6 D% U( i+ a7 U' M* g
  64. & Y% e: ~2 S$ a5 @- _
  65. {% |' P, F1 [2 Y5 X* |( g

  66. 9 S1 }& T# \: [. a
  67. TIM3->CCR1 = CCRValue;
    ! _  i1 Y8 q! ?, B' x, a
  68. + Y7 N5 \0 Q5 ~$ Q0 Y6 Z/ V) q0 h+ U
  69. }
    - W6 v* {. ?6 e4 x8 L

  70. & M  m% [; y5 F4 ^
  71. }- A5 _3 W: J& t

  72. * o7 N" O3 H! c
  73. & p2 `8 b% G( @3 t7 k# a
  74. , ^4 w% o/ |! L4 S
  75. void Screen1View::DecDuty()//For TIM3-CH1( j" r' U  `& L# Q

  76. 0 @( i9 I# [9 O- `' F; u
  77. {
    $ y, ^" g$ r/ M+ R0 s
  78. * N% v3 k, l+ Y
  79. CCRValue-=100;% @& s2 G0 t8 w4 ?5 J' V! a

  80.   x& P$ W5 Y. X( C1 ^& A, @
  81. if (CCRValue <0000)0 U* v9 u" L8 X( a- j. h

  82. # j1 V' _* W' Q% l# ]" F1 y
  83.   {
    5 ?  C$ B# x; o) ^% C

  84. . ~) `  `4 |* C& C2 f! s
  85. CCRValue = 0 ;- n; r+ \( P& q& I
  86. 4 K) c2 G5 {- E8 f/ y, r  Z
  87. TIM3->CCR1 = 000;' b* m1 D" ^  w* {4 F2 [2 Z
  88. $ n/ V: K  ?0 `) }8 q  T5 `" F4 o
  89.   }3 ^* I! O+ y0 q3 u2 u/ l

  90. 0 D  g4 T4 J3 H, q% K) e
  91. else. j. w! b8 d9 f, K( c
  92. : G# D. M, q- x# D7 i
  93.   {
    ' [% h3 F( G- S
  94. & G  K4 Z7 ?1 A0 O
  95. TIM3->CCR1 = CCRValue;
    8 t7 D+ u9 d* U8 `& Q

  96. 3 t& `4 s1 W/ Z) q/ m1 c
  97.   }
    ! L3 H2 e2 e0 g  @  |- ?; T
  98. # \  V( C( L" ?
  99. }: A7 t) v! P9 D, P

  100. $ x4 q) Q! w7 R2 |

  101. 7 W% X! ~; K: R4 ?0 k: `
  102. + {0 ?. _( U: K+ }' [, Y
  103. void Screen1View:: ModifyGraph() //for Dynamic grahph
    ) L; x; a. S8 t; w, F

  104. & p8 t, v% g  I$ q+ d
  105. {6 E/ _0 K) p( |% |0 H, Y+ l
  106. $ B) N  h' p/ w
  107. uint16_t temp;
    0 r" |8 e$ K' e
  108. " C9 _) C  r  b8 E: a# D# L# ]5 o  d
  109. temp = GPIOB->IDR & 0x0010;" b8 w, h, R' M- T/ U6 h
  110. - ?, D2 I( O, Z$ f5 m5 l
  111. if (temp==0)
    , r3 I* B" y! R$ M
  112. / R! X6 I) R; k! [3 f7 V
  113. {1 ^( Q/ F. Q( v7 I3 K5 m' s

  114. # |4 {# ?5 E9 F& O
  115. dynamicGraph1.addDataPoint(0);, t4 k' J2 J5 b' [
  116. 6 K+ {4 O7 d3 A& i% i' G
  117. // dynamicGraph1.invalidate();
    # \( b  P; ?) c

  118. 0 I, Z+ x- w  C( q5 ^7 A' K& Q
  119. }
    2 J6 C% ]1 C/ I* g7 u; O

  120. 8 y" l6 f, C# }/ n
  121. else# b! K8 `  J9 L$ K

  122. 6 d  @% ?# e5 @3 {% Q
  123. {! ]9 F- f% F2 F; \8 F6 Q
  124. 5 b- ~9 P: ]$ P' ]3 @
  125. dynamicGraph1.addDataPoint(99);2 e- R# v2 B) {
  126. ; g% y4 i; Z6 M. F3 L; z' D- D% E' }
  127. // dynamicGraph1.invalidate();& ]3 x7 n0 ^1 \( |0 R

  128. 2 p- ^$ ]* x. ?, w- t  S5 ]! U
  129. }
    % h. X% I$ b- J7 t: J
  130. % Q/ l$ |6 \5 X" X. W. V9 [$ Y5 F
  131. }: n) m: K% U* q
  132. ! L4 a$ B5 c! B: H
复制代码

) N' ?% E. a7 `/ T& {$ k9 L, D
3 _( C8 ?# C; [4 g0 m0 c9 w9 s. b$ G  T
最后补充下,当我加入第4个页面屏的内容时,电脑上模拟下还行,基于STM32F429开发板已经没法正常稳定运行了,毕竟资源有限。当然,不同的人设计4个页面所涉及的内容及任务数可能大相径庭,可能的结果这里不好说绝对。不过,我的测试过程中运行上文中提到的前3个页面内容及功能是没有问题的,下方放了个效果视频供查看。

* ~, y8 P- j% i' j
; B* v" p& u& o- M9 F  i9 Z6 s
赞 收藏 评论0 发布时间:2022-8-21 21:46

举报

0个回答

所属标签

相似技术帖

官网相关资源

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