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

采用 STM32H750 实现电机控制节点维护设备设计

[复制链接]
STMCU小助手 发布时间:2023-1-16 15:00

0 E$ H5 |' Z  t& Y: W, J% g8 m8 g
0 u8 X1 s) s; S4 T( z+ L8 b: M
微信图片_20230115153427.jpg
1 ]6 l' @5 N3 w  k

3 d  o1 f& ~( U4 w& U8 H" ^/ T8 n1 T
4 B$ V# ~0 F7 K, S8 \  H5 S
在详述实现过程之前,我们先看一下 ST 专家点评。
4 j; O6 X, Y. f/ F: F) n

$ Z* M' M+ r1 Q; JST专家点评5 y5 f' S0 {& O- @1 R6 ^  N
从这个评测贴中我们可以看到这位同学给我们展示了如何使用STM32H750+TouchGFX开发平台快速开发一个使用STM32H7对电机进行控制的应用.( n. m5 c; A7 Y* }( S) X( B
- o4 t$ z2 {4 D7 f1 t/ K/ f
从UI设计的角度来看:UI的设计非常好,这位工程师对UI设计方面也是非常有心得的,由于UI设计的非常好,再加上TouchGFX Designer的布局和交互,设计出来的界面非常美观。在UI设计方面,使用很多TouchGFX Designer自带的控件进行UI设计,基础控件:如图片/文本/进度条控件进行基础布局,使用滑动容器控件和静态图表控件用与实现子页面滑动/图表等功能;并通过TouchGFX 模拟器进行仿真测试,很方便的开发出一款界面美观交互友好的嵌入式GUI产品。+ G7 `2 L3 _+ ]& y+ M; h1 S
# ^1 a1 t2 H  f1 S* {  Y3 K' t  n
从数据处理的角度看:UI设计好后,通过MVP机制对UI和后端数据处理进行分离对电机进行控制,前后端分离,方便未来增加和扩展更多功能。
3 }7 Z/ ?9 Y; O. Q* E
从整体设计来看:设计的UI非常美观,接近智能手机/手表的用户体验,功能实现比较完整. 是一个很好的的UI设计作品。
9 P4 y+ h+ E8 E4 }% c2 t! T4 Q- @: ]/ B3 u; v4 T# |9 I
一、项目介绍
参加STM32论坛的STM32H750B-DK评测活动,利用提供的开发板做一个前期验证项目。验证项目是做一个手持的电机运动节点维护设备,方便携带到现场对电机进行维护,这里暂且称为PAD。(实物演示视频见本文上方作品展示)
2 W6 z& f4 g' F4 C3 Q9 S
. ]8 H! \" a* m1 |

* W# d) I" G7 v- i. Q: i. k- r8 {& TPAD通过UART与电机控制节点连接通讯(如下图所示),当检测到设备接入,PAD获取其设备信息状态,包括固件版本、PCB版本、运行日志等。通过PAD还可以控制电机做一些简单的运动测试,配置电机的运动参数,如加速度、速度、电流等。由于时间有限,目前仅实现上述功能。
  k% o4 _! c9 ?8 C; v( X# [6 I) m5 ~% J# A+ j& d; D
微信图片_20230115153423.png

/ M& |3 i/ E. R, K
二、开发板STM32H750B-DK
开发板资源丰富,本项目比较关注的资源情况:
  • Arm® Cortex®-M7 内核(带双精度浮点单元),400MHz主频
  • 4.3英寸RGB LCD,电容屏
  • 外扩2 x 512Mbit Flash
  • 扩128 Mbit SDRAM
  • UART接口
  • 持Chrom-ART图形加速
    6 t3 t8 ?  d% C, E& P- A1 |
& c- t: y' v: X5 R/ ~' O: h
三、设计工具
  • STM32CubeMX
  • STM32CubeIDE 1.9.0
  • TouchGFX Designer V4.201 Z) y6 E' ?" s* e7 _' p9 Q. d1 y
       微信图片_20230115153420.png
    4 A8 P  f1 Z5 l% \7 y& ^- Q
项目中用到的TouchGFX资源
(1)控件(Widget)
  • Box
  • Button
  • Image
  • Slider
  • Static Graph
  • Swipe Container
  • Text Area
  • Texture Mapper
    $ L* `' a! R+ W7 T# A3 J0 {
(2)实现UI动效使用到的TouchGFX内置的交互动作(Interactions Action)
  • Call new virtual function
  • Change screen
  • Move Widget
  • Fade Widget
  • Wait for
    , c* V6 I) j1 [1 U
9 l0 I1 T3 f9 t, \# ~/ h- z
四、界面设计
不会UI设计的电子工程师不是好厨师,所以这一次亲自操刀设计,整体设计风格采用我喜欢的“毛玻璃效果”。TouchGFX Designer的模拟器非常实用,大大提高了调试效率,以下图片均来自模拟器的截图。实际上,模拟器的显示效果与直接目视比较接近,视频拍出来的效果比实际差了不少,屏幕颜色不对,还有条纹。。。截图只能看静态效果,动态效果请大家观看文章上方视频演示。3 F; x' d  G  f% x; ]6 m

: [& X+ p1 }7 {$ h7 y7 n

) b0 x8 h  u$ j: A/ }目前实现了5个界面:开机、连接、功能选择、信息显示、电机控制。
' Y+ J6 w5 G0 [0 D& W& C( l- _  L
4.1  开机动画
微信图片_20230115153416.png
4.2  连接界面
微信图片_20230115153413.png

5 t: \7 |4 F7 Y9 ~) l0 @
4.3  功能选择界面

" c7 T0 X' Q. ~( `8 I, L+ B
微信图片_20230115153407.png

8 y# K! R) n; [- u& x3 a0 N
4.4  信息显示界面

7 O6 G6 ]5 @! V0 @& [2 C* t( y
W7XNCDP1K4L2){U7}{E@YCK.png 3 s8 Z: n( c! r4 L$ `9 C

; e: Y3 W2 E5 H" g4 U0 Y/ r
4.5  电机控制界面

9 J; u9 n6 c9 ?+ ~' V) F: F
CX}FMD%%O1FWAD(P$%Z@W_K.png , l$ [# u* N/ r  i+ G# F

& w" ~# @8 T6 J. `) F
五、硬件交互
使用TouchGFX的MVP框架实现GUI与硬件的双向交互。MVP的全称为Model-View-Presenter,Model提供数据,View负责显示,Controller/Presenter负责逻辑的处理。在本项目中主要是检测用户在触摸屏上的操作,转换成相应的UART命令发送至外部电机控制板;当外部电机控制板的状态发生变化时,也会主动发送数据到开发板,此时GUI负责刷新界面显示的相关内容。MVP框架应该是TouchGFX中不易掌握的部分,UI怎么和硬件交互?这个是根本,每个项目都会涉及到。这里以本项目中的UART为例说明一下,如何通过操作屏幕上的按钮来控制UART发送数据。  N& z+ I) O+ U0 H. {9 x8 V

) J( g! s7 S* I# [+ Z& ]

& `% }: A6 e# x
微信图片_20230115153159.png
" X8 U. o% r: _% q
$ `% S, n6 h  M. y( W0 b7 u
以上述界面截图中的STOP按钮为例。在TouchGFX Designer中,我们给Screen1添加STOP按钮,命名为con_stop(很多资料中介绍了这些基本操作,这里不再累述),我们要实现通过电击此按钮向UART发送数据。. Y2 D- o# m' R. b; t

: {8 `2 E* i% l

* C2 b# Q) e2 U, F. w- y8 g在界面右侧的Interactions中添加con_stop按钮的点击事件。如图上所示,触发条件为按钮点击(序号1);触发源选择为con_stop按钮(序号2);触发执行的动作为调用一个虚函数,虚函数的名称我们设定为con_stop_clicked(序号3)。然后按下F4执行Generate Code生成代码。TouchGFX Designer会自动生成这个函数的定义,在STM32cubeIDE中查看Screen1VeiwBase.hpp文件,可以看到此虚函数的声明:
6 h8 i$ l* G1 T% P
$ W9 d3 w9 Y- ]/ y2 }4 R4 b( K

5 G. N/ o7 W. o- r1 _/ a2 ?; Ivirtual void con_stop_clicked()   { }- e5 G) u8 B" \7 @1 {+ G. g

! D' X& P# a3 z. f
. ~) E( _. X1 c" f+ S6 f
(1)手动在Screen1View.hpp文件中给Screen1View类添加此虚函数: ( U- Q  y  _  o& q
0 o- u5 v  `# c8 `9 O

6 N$ s/ W: g; z0 q% g virtual void con_stop_clicked();' E% H" q. l' n4 `2 w: `/ ?2 l4 L

0 L3 ?% V: }/ H1 a

! E3 e! e% X4 ?手动在Screen1View.cpp中添加此虚函数的实现部分:7 {# y* X" O" ]/ F1 v
  1. voidScreen1lView::con_stop_clicked()
    / z) g- m0 J4 C! `
  2.   {2 S% g" E$ {* S; m
  3.         presenter->con_stop_clicked();' O" l: H% h9 q/ H, {/ C- R
  4.   }
复制代码

2 I% m, [' }" F* h  z1 n, x* q( i1 j2 Y8 H8 J

  V$ J) K. W7 \; `上面这个函数调用了presenter中的con_stop_clicked()函数(函数名可以自己定),实际上这个函数我们还没有实现,接下来给presenter添加这个函数。
8 A# o2 J# N9 v* e) B5 P' \0 e+ _
5 K$ }' c& _* w# b- v1 e( N
(2)手动在Screen1Persenter.hpp中,给Screen1Persenter类中添加函数con_stop_clicked:" u, @. O, d# f, W2 P; Q) k
* i) c+ g) U+ b& R0 G7 y
- l3 X6 _! y5 H
virtual void con_stop_clicked();
0 s: Y+ x# A0 ]* l; d# S3 R
+ S' Q2 T! l+ }  O* X

  k0 n* P9 X% v/ g9 L手动在Screen1Persenter.cpp中添加这个函的实现:
7 j2 H. j( t, e5 B* `9 K
  1. void Screen1Presenter::con_stop_clicked()
    ! k  w* ^! Y" w4 j8 S* ]' f
  2.    {
    ' a) c9 x  ^0 G
  3.     model->con_stop_clicked();! D5 E8 T6 M+ V
  4.    }
复制代码

* L5 y& c6 z- W; Z, x' `
) {4 P9 U- i$ j2 E" z. i% Z0 B
: p& n5 ], G' k# I' {# i3 c# G
(3)上面这个函数调用了model中的函数con_stop_clicked(这个函数名也可以自己定),好吧实际上这个函数我们也还没实现,接下来继续。
( S  b% j& h: t4 r1 K9 T% m$ ?4 L# A$ p
; X: h7 F( C5 |4 O) b( A: z
手动在model.hpp文件中给Model类添加这个函数:/ N% l: ]6 j# S1 u; q  B, b1 d7 m

( @+ f5 \" `4 O8 A3 w

) n$ ^% w9 J3 w: V3 J/ ]void con_stop_clicked();% h5 E* B5 `# O/ N: L: P

. [' T% a# {! G/ S
8 M; p6 `( n% R$ L9 A1 U
手动在model.cpp中添加上面函数的实现部分。
- v( z9 x+ f6 b0 w
  1. void Model::con_stop_clicked()
    3 R* z3 t/ C1 b  X/ N
  2.    {
    ' @. A+ t5 H% u' |& m5 K* T
  3.     uart_send_cmd_stop();1 Q, C, u- |6 ^
  4.    }
复制代码

: T8 E( h' E8 e
; B- Z; ?) \1 U' s, E2 j2 e

9 \  t' E* F$ [$ B1 H5 q) yuart_send_cmd_stop()函数上就是发送UART数据的部分了,通常情况下是在uart.c中实现的,内容类似下面这个。* ^3 q5 _% Q5 y, [0 M) d
0 S: f' g& k. a: J, n% o

: B4 l$ \/ b* R3 n! P6 GHAL_UART_Transmit(&huart1, (const uint8_t*) str, len, 1000);+ M7 P; G2 v) r' W
# U- a/ L% y0 q( e8 a
% V6 Q0 e8 ]5 `8 ^/ b( e$ g/ n
在model.cpp中我们把uart_send_cmd_stop()这个函数作为外部函数引入:
8 c5 I& Z2 y, ~: h0 U9 k0 l
  1. extern "C"
    & r% g7 y- @" N* V
  2.    {
    5 W: X  b1 Q% p
  3.       extern void uart_send_cmd_stop();
    : j6 a! d  C5 r7 _; n. _
  4.    }6 x. q0 t3 J: V2 i$ G0 B, @' `# B
  5.    #endif
复制代码
, O8 d$ L, l; k3 v. u; ^7 C
- }# w- h5 E7 D- i. ~3 R

# y! G/ G& q8 F实际上这里偷懒了。项目中使用了FreeRTOS,有一个Uart_Task任务,负责UART的数据收发处理。在多任务的情况下,多个任务涉及同一个硬件应该确保互斥访问。所以这里应该使用信号量,改变信号量的状态来通知Uart_Task任务实际发送数据到UART。
+ I. k0 d" V! j. R3 D) Z3 V4 X; \- Z$ k3 O% `. u
一波操作下来, View  --->  Presenter  --->  Model  --->  UART,千山万水有点麻烦,不过MVP的优点还是很多的,想要了解更多大家可以问问百度。1 o4 ~/ R6 A$ J- A* i4 Z& E" f
- c7 U1 x7 g! D) {% |! I
六、总结
之前一直用LVGL,做过一些项目,也算是比较熟悉了。最近半年才开始使用 TouchGFX。一番体验下来不得不说,在 STM32上做 GUI 应用 TouchGFX 确实很有优势,毕竟是 ST 亲儿子,先天优势,生态全、控件多,实现各种炫酷效果不在话下。最方便的是几乎不需要怎么优化,不用操心什么 DMA2D、LDTC……,底层ST都帮你搞好了,跑起来效果就已经非常流畅。ST 新出的 NeoChrom GPU 看介绍更牛X,有机会到要试试到底有多牛。
. I2 r2 W7 H9 f) @0 B6 W$ Q, `) H7 F. c/ b* B& i( O" S

3 a- y6 ?' y/ b7 c9 Z

3 c0 i5 o0 t$ H8 b
; v( m) k7 r, T/ i) \  u
! y5 Z8 u% ~4 h1 m1 G
赞 收藏 评论0 发布时间:2023-1-16 15:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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