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

4000行代码的开源GuiLite,并移植到STM32

[复制链接]
STMCU小助手 发布时间:2023-3-4 20:00
1 Gui移植结果
    一些演示效果:
24.gif 33.gif
21.gif 20.gif
19.gif 18.gif

9 o( v! M2 r! ~7 j: _* g9 C 17.gif
16.gif

2 l& F# l. t0 X
2 GuiLite介绍
$ n+ u( v  O1 s6 z2 H" o4 P    GuiLite是一个开源的图形用户界面框架,只依赖于一个单一的头文件库(GuiLite.h),不需要很复杂的文件管理,代码量平易近人。5 F+ ]1 M6 w6 L. b4 u
    GuiLite由4千行C++代码编写,单片机上也能流畅运行,其最低的硬件运行要求如下:
2 J$ C/ H  g* z$ m4 l& a/ t9 A
' K8 y) k8 o/ v' s! r

& ~6 n. ?3 u8 r8 V/ A 15.png : h7 `! q% K$ w" }! u# G( k. \
# f4 X' e( D: v. E
GuiLite具有很强的跨平台特性:
  • 支持的操作系统:iOS/macOS/WatchOS,Android,Linux(ARM/x86-64),Windows(包含VR),RTOS… 甚至无操作系统的单片机
  • 支持的开发语言:C/C++, Swift, Java, Javascript, C#, Golang…
  • 支持的第3方库:Qt, MFC, Winforms, CoCoa…
    2 W' Z: Y' u* E  D! g% x
  • 4 d. s. B7 o9 [
    5 _) D+ ~) Q# ?' w4 d1 Z' t
GuiLite 提供一系列辅助开发工具:
  • 完美的“云” + “物联网”解决方案:让你轻松驾驭全球IoT业务
  • 支持多语言,采用 UTF-8 编码;
  • 资源制作工具为你定制自己的字体/图片资源
  • 所见即所得的GUI布局工具
  • 编译活跃度统计,及实时分析
  • 支持3D & Web
  • 支持Docker,一条命令启动。
    ' `+ ~/ Z( U( o0 W7 m

* i* X2 G3 ~0 `; I: u) h2 X3 GuiLite移植
2.1 所需硬件
5 b; B, O# x! Q: y! Q- Z! y8 C; ]0 e6 P" M. ~2 g

" ^4 n  T' p2 g% H 14.png
2 D' g: j9 t5 h+ {" t
/ d% |& Q% b5 {# Q2 h& Q
* h! P0 e, q* e/ W+ i1 g
STM32F407开发板+ o; d+ P" K. ]% P) k/ }

/ L+ {  N6 D) v+ Q0 U5 @5 |

+ [# w0 }0 X9 D$ c* R6 _  }4 ~3 [ 13.png
4 |$ C% C& ^- ], {! y
3 e+ m+ }& h& T1 t
( s2 j/ I* k- p& E' c$ Y2 Q# l
OLED屏幕/ Z+ _' v5 W" \) [' F: {+ D( X& _( I

! E1 V. I8 [7 i/ f5 `' G; K8 b
$ m8 r% D# k/ f  ]6 @* N
2.2 驱动准备3 z  s' w" j0 G. X; x
    这里我使用STM32CubeMX 对开发板进行外设配置,开启STM32的硬件IIC,这里我用CubeMX开启后如下:6 p, p7 w7 g& u* g) K

( X% b  n$ S. w+ a; a) {& i& K
  B) F1 [6 `; P* \; k
12.png 1 m# M/ d6 M5 b
! Z+ a1 }+ P( Y' z
+ z* |$ T& i, M* Q- W9 G
    配置完成生成代码,同时将分配的堆空间增大:+ g7 F0 Z4 l' e  a+ L
" }/ {2 d, {3 u. }  x4 {
, z% d* ~8 ~) K( J' y$ q
11.png
" a" c. }9 o' b  K7 V3 U" S0 x! w7 S* J+ E8 J
$ ]  c: R; x- r5 o! Z
    代码生成后,我们复制正点原子的OLED驱动工程代码到Hardware硬件目录下,自己创建一个该目录。! U3 k* b) X* \4 \8 [2 U8 z
7 E+ V, c+ P! r0 e5 B# c

5 Q7 R$ [, a. [* h5 C* k 微信图片_20230302201518.png # q2 W/ Y) N- `( ~! ^% E
! r% J/ F3 d7 {
- u' s: R6 E+ r" J% k
    在MDK里面添加文件,然后我们进行修改,注释掉头文件里面关于端口的定义,同时添加三个类型宏定义。
% ~7 ^: `. ~' X/ R: ~1 p4 K
6 I" B8 V# g( o) ?# S; p5 \9 D
( M/ Z* Y2 l1 P- n2 D" k1 d
10.png ; m5 ~9 Y' _1 d
5 n% e6 _; s" \6 a. K3 q8 U( {. G
! d) f/ ]3 h( P- {0 C; q
    然后我们进入oled.c文件,将void OLED_WR_Byte(u8 dat,u8 cmd)和 void OLED_Init(void)函数分别替换为下面的内容:) f" y! {( x' ~  ~5 l1 u% W
OLED_WR_Byte:
7 Q8 ~9 P' C; W' n. q7 o5 x/ M1 n
  1. void OLED_WR_Byte(u8 dat,u8 cmd)
    ; M3 f( C! J  A$ ?: U
  2. {
    $ t2 H- U! C$ O/ \
  3. if(cmd)& i+ N2 E( w5 c5 x  ^1 G
  4.   HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100);
    $ e; `9 F8 ^6 j0 n; Y" m8 m
  5. else
    & {9 j, h( f, e, F' d
  6.   HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100);   h( C' p- N" g7 Q9 Y- j: D; A9 N
  7. }
复制代码
0 Z& A7 Q! i* l, v# \4 |

9 n' C8 Z; D7 W) n1 x5 p0 T4 [

9 b: _* }# R: \7 r3 [OLED_Init:2 j& I# I8 V1 E; ~+ {% b# G
  1. //初始化SSD1306         
    9 c0 M: o6 n& d
  2. void OLED_Init(void)
    9 v, c, {. }5 @6 [# o$ ^
  3. {        / n" \. o$ |6 g& ?5 M' W
  4. OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示  M- T! r3 j, u7 B. \5 a: R
  5. OLED_WR_Byte(0xD5,OLED_CMD); //设置时钟分频因子,震荡频率) e" H! v0 u0 x& K* o$ u
  6. OLED_WR_Byte(80,OLED_CMD);   //[3:0],分频因子;[7:4],震荡频率
      j+ _! M4 `$ I8 m3 j6 [2 h% p
  7. OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数
    & a) J7 R* m4 K9 U$ J1 T
  8. OLED_WR_Byte(0X3F,OLED_CMD); //默认0X3F(1/64)
    ) h' ~2 a" C6 i+ D
  9. OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移6 a6 l/ V' Z" u: ?3 E
  10. OLED_WR_Byte(0X00,OLED_CMD); //默认为0
    0 A5 b! P2 x1 N
  11.   y0 o  h3 s0 @* Y7 N# U
  12. OLED_WR_Byte(0x40,OLED_CMD); //设置显示开始行 [5:0],行数.
      r# f6 [4 g9 [. v( [$ I" l

  13. 8 A/ C9 [' \' ]7 Z; i! l- _
  14. OLED_WR_Byte(0x8D,OLED_CMD); //电荷泵设置
    6 \' K; n! k4 K! y- a& j& `8 M4 W
  15. OLED_WR_Byte(0x14,OLED_CMD); //bit2,开启/关闭" a" L/ u8 i9 Y. M3 o/ w# g
  16. OLED_WR_Byte(0x20,OLED_CMD); //设置内存地址模式
    ) S! F' a( O# ~
  17. OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;
    1 ?/ U5 e6 x1 o2 F' ~$ E
  18. OLED_WR_Byte(0xA1,OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127;5 j: [$ P! p3 b. K/ a
  19. OLED_WR_Byte(0xC0,OLED_CMD); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数) @; ~* E+ ^; c/ C4 A" \# b
  20. OLED_WR_Byte(0xDA,OLED_CMD); //设置COM硬件引脚配置; d  l9 Z1 A3 R' ^* ^  z- v/ P" Z
  21. OLED_WR_Byte(0x12,OLED_CMD); //[5:4]配置
    ( F% F3 v; E# T( _# I( P1 E- Q
  22. . v, j( T" \1 K' a3 r  L) X
  23. OLED_WR_Byte(0x81,OLED_CMD); //对比度设置/ ~$ L! G' Q/ Y; b" X  ?
  24. OLED_WR_Byte(0xEF,OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮)+ o' l$ E2 s2 ]0 Y0 {: _* ?6 F' B
  25. OLED_WR_Byte(0xD9,OLED_CMD); //设置预充电周期
    6 Z" \4 v3 _, @2 F  O
  26. OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;# E: {7 m. o/ {
  27. OLED_WR_Byte(0xDB,OLED_CMD); //设置VCOMH 电压倍率
    , a- x6 w5 e+ v9 S9 i
  28. OLED_WR_Byte(0x30,OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
    2 y' N  Q% K7 v6 l  |1 {
  29. - k9 r3 I6 j! F- r' z
  30. OLED_WR_Byte(0xA4,OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)# d% V. F; x* V3 d  X6 w
  31. OLED_WR_Byte(0xA6,OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示              
    $ }3 i; v$ j1 |2 A
  32. OLED_WR_Byte(0xAF,OLED_CMD); //开启显示  
    8 J+ M- ]" Z4 ~; l+ k  x
  33. OLED_Clear();
    0 p; z" k2 g3 `8 K% T6 H) C
  34. }  
复制代码
3 d% B* U3 Q+ [. a; o/ E+ L# M

% \2 q$ G* L+ K+ M- j# |6 T然后在main.c文件如下位置添加oled测试代码,记得添加头文件和头文件路径。
  s3 b% G7 w8 B/ Q2 e+ A1 f% I( U
0 F, K/ V8 e4 a( }

7 |* @! x" L3 C! c, X 9.png
1 v" ^5 _, i/ K. M* g# o+ t0 X0 \2 v& D) m
% R6 L5 I( o: |& m2 V, l; x
    下载程序,观看现象:
  q: A) x) L5 z$ l" f3 d* \# K4 O  a8 F  B
. v" a9 g5 N, [
8.png
$ _! F  R1 \7 e6 o1 s3 ~  P" o. _) \) ?; L5 f
, J/ ?2 L! V1 k: Q
    此 OLED 驱动的准备已经完成,下一步就是移植 GuiLite。9 c! }/ M7 X: P4 \9 L) a' R( l
9 X& Z! P6 }' ^( o6 q9 B7 i) o( {2 E% ^
% T, s3 t& y$ b" c+ W* ?$ \
2.3 例程移植
9 m0 _* t% m# Z. `9 u3 [    首先,我们上GuiLite的例程展示官网:GuiLiteDemo,选择Hello例程,将其中的 UI_Code文件夹复制到 Hardware 下:/ p( h7 ?8 ?0 m: T. C

. U0 b! H+ }: r4 R: g2 r% E7 V

' o# k; u3 d! U$ S 7.png
9 |+ d( L2 J4 F# `2 M8 [6 ^, T+ C$ O- |6 i7 I7 Z0 ~

% V# v$ n" H4 k    在 MDK 工程里面导入UICode下的GuiLite.h和UIcode.cpp文件。+ M7 ~5 U# U) }# }6 |
$ i' Z( Y6 Q& n' k, J
- G  h9 `" X! I/ ?) M
6.png
4 a5 q5 W3 z; C$ n8 D9 m* P$ j/ {
" \* K1 o0 V2 p, I
0 Q9 w4 d0 F0 R+ ]7 m1 e& t' v
    我们在 main.c 文件开头添加 GuiLite 接口代码,接口代码如下:& `9 z- X; Z* ?$ Y3 D* x
  1. //画点函数接口. H) [9 W5 m/ G7 r! W% f9 U
  2. void gfx_draw_pixel(int x, int y, unsigned int rgb)/ k/ I# y* Z3 G1 V2 N
  3. {
    9 U; A9 i: G) a0 ?+ |! r
  4.     OLED_DrawPoint(x,y,rgb);4 G. v& c5 Y; `! j4 d1 X
  5. }3 ~) s' Y1 Z8 F- W2 J# `. c7 b7 d% d
  6. //画面函数(未使用)
    $ s9 b4 F- Y6 c% G. G0 j. k- N3 g3 p
  7. void gfx_draw_fill(int x, int y,int w, int q, unsigned int rgb)
    + c" h* I/ }3 O
  8. { 0 t/ _$ i( M. ?+ T
  9. }5 t) K8 ~7 @  Q3 O% P; X- v; b- X
  10. //创建一个函数指针结构体3 Y1 |' H3 n4 T, H
  11. struct EXTERNAL_GFX_OP
    , ?" j) x$ N9 V( B+ x0 o
  12. {( ^, X' d4 c0 O( \2 |. ^- t, x
  13. void (*draw_pixel)(int x, int y, unsigned int rgb);
    " ?; ~8 g( W$ e' X
  14. void (*fill_rect)(int x0, int y0, int x1, int y1, unsigned int rgb);
    . O( R9 k0 G2 n6 B7 y
  15. } my_gfx_op;) C& W* R  m2 Z9 V' O5 @& S" w
  16. extern void startHelloCircle(void* phy_fb, int width, int height, int color_bytes, struct EXTERNAL_GFX_OP* gfx_op);# e' s* n6 m- i( }3 r; g' v
  17. 0 e+ ?) X5 T8 S" @$ \4 b3 Y
  18. //设定延时函数接口
    + K% z* W% ]9 K/ w6 A6 X, e
  19. void delay_ms(int milli_seconds)* H, X. M, y% z1 M) E3 J7 u1 L
  20. {
    5 ^5 z+ m& b7 H! A" v5 L
  21. HAL_Delay(milli_seconds);: j# C$ G! _' w  v: N$ |
  22. }
复制代码

9 B  ?$ |' M* I+ q" C4 x+ S& o/ {) O4 A

& y% e+ F$ f$ }8 p3 O1 P+ I之后在main函数中添加如下代码:8 Z& ]2 U" T& e+ @5 x, ~
  1. //传递函数指针
    1 b+ W' K( Y9 M4 i
  2. my_gfx_op.draw_pixel = gfx_draw_pixel;3 i3 [2 v& B- k9 U$ S
  3. my_gfx_op.fill_rect = NULL;//gfx_fill_rect;; O, ~; T/ E5 u
  4. //启动画圆. ]$ H. p. U  q0 D1 t0 Z
  5. startHelloCircle(NULL, 128, 64, 1, &my_gfx_op);
复制代码
; s1 ]) X) ?! I, C+ S) M

3 ^2 e( a. p$ x3 B0 Z2 k' ^! { 然后我们修改UIcode.cpp文件中的代码,添加OLED头文件,以及在UI执行函数界面处添加OLED刷新函数。
) V, v0 O: N; i5 q' c
4 e5 x4 }! v% {# Y

& Q; m) e( [+ `) N- Y" H( C- \ 5.png * t3 n; C& b1 P' Q; ?9 I2 e

; a- v: t7 Z* r$ |) I* y
& |/ i9 T/ }! x, D: Q
    之后在UIcode的第8行修改3D圆的参数,因为OLED大小128x64 ,所以我的配置如下:
, n+ i/ t5 a6 T# ^; n& p& y2 x8 m; U  w; T* Q4 f+ ~
6 ~& u( c2 C" m
4.png
, m% O/ }* }* B2 M- y4 d. U. V7 c% f
$ d5 C2 z# q  L6 K7 k6 u! `3 x( G
    配置完成后,我们关闭Use MicroLIB选项,编译代码:
! U2 c. b' y# N: h( g% `0 U% x" U% ]8 S. _2 \. z7 ?# R7 y: n4 ^

: k1 I( z$ V/ S 3.png ( E+ ^0 R4 N* ]+ J

# A8 V- Y+ ^" Q+ l, Z+ b5 _4 S
/ |0 ]; N4 C1 g7 D8 C
    编译成功,下载代码。4 f2 K8 H9 V0 [' w% F8 y2 L2 G1 b

, h$ T! p% P) x" C6 F0 _' i

$ Y& m$ v8 I( |% v/ a 2.png
4 Y% y8 i  X8 N) F$ m8 x7 L4 ?
8 o9 ^. X) p1 V! I% \3 }0 T% G8 |

, w- p" l! F% x    下载完成后程序复位,可以在OLED上看到Demo的示例动画。. ?) ?8 z. ^' o; q7 K" ?0 c9 t% w
( b' O  u6 e8 S! }

" x. m8 O, u. ?+ X2 h$ P0 m4 p 1.png ) b# n8 [9 W* U! Z; }4 R

2 d9 T0 n0 N. Q; }: f" B/ X# R转载自:[url=]芯片之家[/url]; Y* h- `- T  r8 D) \8 {
4 J8 l7 f  ]9 Q8 |. o7 y
8 s& ^; M! ?/ F9 ^! e
收藏 评论0 发布时间:2023-3-4 20:00

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版