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

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

[复制链接]
STMCU小助手 发布时间:2023-3-4 20:00
1 Gui移植结果
    一些演示效果:
24.gif 33.gif
21.gif 20.gif
19.gif 18.gif
# [- ^7 Z- |% N1 `+ A. p
17.gif
16.gif
) e( g* `6 L. m# ]' c' q, a- B5 |
2 GuiLite介绍
1 c% D( U- d; z2 F  h% g3 A* e    GuiLite是一个开源的图形用户界面框架,只依赖于一个单一的头文件库(GuiLite.h),不需要很复杂的文件管理,代码量平易近人。+ n( ~. {+ u. b
    GuiLite由4千行C++代码编写,单片机上也能流畅运行,其最低的硬件运行要求如下:: w: K) t( E! s+ O5 m$ i& n

5 X  C3 q2 j- Q- a* K

$ q4 M. j' C" L+ d 15.png
  B. }3 a5 s+ D; H( \
0 f1 |5 `% W" F6 |GuiLite具有很强的跨平台特性:
  • 支持的操作系统:iOS/macOS/WatchOS,Android,Linux(ARM/x86-64),Windows(包含VR),RTOS… 甚至无操作系统的单片机
  • 支持的开发语言:C/C++, Swift, Java, Javascript, C#, Golang…
  • 支持的第3方库:Qt, MFC, Winforms, CoCoa…
    $ O' u6 I8 m! E
  • & ]% t. d# u' e9 i/ q( ?, A

    , J/ Z2 f1 f3 c" O
GuiLite 提供一系列辅助开发工具:
  • 完美的“云” + “物联网”解决方案:让你轻松驾驭全球IoT业务
  • 支持多语言,采用 UTF-8 编码;
  • 资源制作工具为你定制自己的字体/图片资源
  • 所见即所得的GUI布局工具
  • 编译活跃度统计,及实时分析
  • 支持3D & Web
  • 支持Docker,一条命令启动。
    9 q# Q; v+ C7 z# X6 ~9 g
+ H, v+ J: Z, y* D- r
3 GuiLite移植
2.1 所需硬件$ U! v' H1 V$ w

% v# [0 z; ]' ]5 O( y

2 g. J; Z' r- h1 V 14.png
$ _+ B" s5 ], C; W2 C! v+ X. e7 p4 y. d. ^/ M6 G

( M+ k7 S8 w( }- N8 ?: A$ {( J1 ASTM32F407开发板
3 K% G4 p; S2 S3 W8 `. t! J1 B7 ~  |1 ~
0 l/ _% v$ ]( e8 Q; N7 n
13.png - X: \! B3 v0 A/ S2 ^) s: {& W
6 Z" l9 j0 X; A( r% m7 s
/ R+ K' ]/ |3 `' }  b, N5 O( X
OLED屏幕! j6 |, G5 J' X) I( x

  q- _& C- N$ i2 C9 d4 @# J- b
* E/ q- |+ f' t5 T  ~1 ^( _( w  p. d( ]
2.2 驱动准备9 K: R& B( O7 b, a. k/ W
    这里我使用STM32CubeMX 对开发板进行外设配置,开启STM32的硬件IIC,这里我用CubeMX开启后如下:
7 V& F' a! b5 V. c/ D! u
7 _" `4 m9 O0 G; k, R: {7 B$ P: _
0 c7 O/ `$ y+ k0 q& Z/ y
12.png * S- f2 m5 w4 p4 s- }" _
' a' @9 ^& ~* ], a

5 p% {* f+ V( f6 d    配置完成生成代码,同时将分配的堆空间增大:
( [2 l6 \% }/ T% K! Q8 [1 x. }
5 Q$ y; D/ _: Z. G; U7 i
- W( n5 y0 n) b& j( a" P0 W
11.png
* J2 `. ]1 f& G& S" A3 I, ~" j1 [# P
: b' u6 R3 d- T* v- K% r
    代码生成后,我们复制正点原子的OLED驱动工程代码到Hardware硬件目录下,自己创建一个该目录。4 {. r! g& T+ o8 N' ^4 ?$ X

- A  u4 Q/ n3 J2 T1 x

8 w7 b7 b1 U1 q% s) ?  ?2 V 微信图片_20230302201518.png
" t' T. j2 N$ Z" a# Y( O
' s. `$ T, @% A: y3 @( c1 I/ D5 F4 L8 q

$ w6 Q2 O8 \- v+ [7 I( f    在MDK里面添加文件,然后我们进行修改,注释掉头文件里面关于端口的定义,同时添加三个类型宏定义。8 n1 L" R8 ~, T! l

+ H% @3 a- ?! k
: W$ r- z2 s5 |
10.png
& ~) V, _. ^1 T8 h$ z5 E9 d
* w. l' X  H) `" V
3 B$ c+ Q6 W) t* X* o! {6 q( q( x+ u
    然后我们进入oled.c文件,将void OLED_WR_Byte(u8 dat,u8 cmd)和 void OLED_Init(void)函数分别替换为下面的内容:
" ]3 f% I; V: d5 W4 `# ^& nOLED_WR_Byte:
' H( ^& b. O  n# S7 Z
  1. void OLED_WR_Byte(u8 dat,u8 cmd)0 U4 A  Q6 D7 A" m; R6 r
  2. {
    * z- g, Q9 Z9 r9 \9 D
  3. if(cmd)  t3 D8 u$ z. J7 z
  4.   HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100);
    6 ~" z0 m  q: I9 Y# u' a
  5. else( ~- O  e2 N7 Z" y. s; b7 F
  6.   HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100);
    2 C2 J0 z3 S5 m# F! X
  7. }
复制代码

/ [. ^2 F# z+ V. d# V* I# X5 T. Q; ^( Q2 @
( j3 W5 w  s& Z7 `" _
* _# G* q0 e. @9 [9 ^( j: W8 Q
OLED_Init:" a7 ?+ V* V6 |. w, A; X
  1. //初始化SSD1306         ( m8 s( w( ]% ^) A5 Z+ i
  2. void OLED_Init(void)
    ) T# z1 h; M8 \' W4 H4 P
  3. {        
    ' w" T; ~; Q  `. R' w
  4. OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示
    7 U4 ?" `& {9 l( w
  5. OLED_WR_Byte(0xD5,OLED_CMD); //设置时钟分频因子,震荡频率
    - l8 l' ?0 d% B4 b! y' z/ S
  6. OLED_WR_Byte(80,OLED_CMD);   //[3:0],分频因子;[7:4],震荡频率5 z( ~+ _2 F8 r7 j# t
  7. OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数7 w! B8 c/ t7 \7 z2 Q
  8. OLED_WR_Byte(0X3F,OLED_CMD); //默认0X3F(1/64) " W% w, g2 A5 Y* l7 P+ N
  9. OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移
    , |3 Z( l7 s3 R% u7 r0 p/ K6 w
  10. OLED_WR_Byte(0X00,OLED_CMD); //默认为05 I8 X$ A. r* ?1 E" ?
  11. ; c: o9 `' e1 {
  12. OLED_WR_Byte(0x40,OLED_CMD); //设置显示开始行 [5:0],行数.
    9 L0 \+ e7 N4 ?7 W. `) D
  13. : V1 G1 K1 N0 b0 M
  14. OLED_WR_Byte(0x8D,OLED_CMD); //电荷泵设置
    # i2 b1 E# J' L# K$ V* @0 p8 Q
  15. OLED_WR_Byte(0x14,OLED_CMD); //bit2,开启/关闭
    + s: S6 v( S' Y6 _) j8 Y
  16. OLED_WR_Byte(0x20,OLED_CMD); //设置内存地址模式# U* u# _, O& [9 }7 q6 Q* V% e& I4 a  [
  17. OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;4 R" f( ~1 @1 T& g
  18. OLED_WR_Byte(0xA1,OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127;
    , ~* E5 {9 x0 x2 `  _% c1 s
  19. OLED_WR_Byte(0xC0,OLED_CMD); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数; v0 J' _4 z# A: F3 _3 @
  20. OLED_WR_Byte(0xDA,OLED_CMD); //设置COM硬件引脚配置$ N  I1 S/ _: I  i
  21. OLED_WR_Byte(0x12,OLED_CMD); //[5:4]配置! h' F' s* F& k/ D) ~# M" Z- M
  22. . q. {6 {9 [7 p" z- }# B
  23. OLED_WR_Byte(0x81,OLED_CMD); //对比度设置
    6 e/ b/ X5 Y5 U; E
  24. OLED_WR_Byte(0xEF,OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮). H+ G- i! i& u' j2 h
  25. OLED_WR_Byte(0xD9,OLED_CMD); //设置预充电周期, }$ w$ _1 A" h* _
  26. OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;0 l, s: n3 o/ u; S- D
  27. OLED_WR_Byte(0xDB,OLED_CMD); //设置VCOMH 电压倍率* d) Y4 {# M3 r6 B
  28. OLED_WR_Byte(0x30,OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;. i2 w2 q3 [& z, i' p0 l
  29. " }, m% ]! t6 [- [" l0 r. o
  30. OLED_WR_Byte(0xA4,OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)+ j" l% V1 T0 R; m( l* G
  31. OLED_WR_Byte(0xA6,OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示              - ~' ]4 e- x' o* @; ?
  32. OLED_WR_Byte(0xAF,OLED_CMD); //开启显示  % H% j$ d: w/ z) j
  33. OLED_Clear();! ~& s4 A7 E- v2 ?7 `2 @3 x. E
  34. }  
复制代码

$ y; `) T% b( r) [- x
- d) J3 I( O, c2 |0 ?2 t0 c' I
然后在main.c文件如下位置添加oled测试代码,记得添加头文件和头文件路径。

# I( n( p& a8 @2 `+ q$ n  r. Y7 q4 H1 c/ A
! b) N" r, q1 t2 v* w! c
9.png . T- T: @. c% d

/ _" |# s" e/ v6 h
9 g, S% k. n4 ?
    下载程序,观看现象:: W# X  N. t' s$ X

4 A' r7 m, n! `& H
  o$ N3 d+ R! g! u
8.png : A7 m3 \- b8 @9 F# Z! ^

5 D) R* F2 v0 W
6 p- {& ^0 k, a8 H2 v0 l- j
    此 OLED 驱动的准备已经完成,下一步就是移植 GuiLite。: t: Y: E8 x7 j+ j7 }' r/ Q& N
# a9 m$ o# s2 H5 @8 H( G
4 Q) n1 D  E# H6 N
2.3 例程移植
4 s; O+ B; k7 m# c6 W' I2 O, S8 x$ ^    首先,我们上GuiLite的例程展示官网:GuiLiteDemo,选择Hello例程,将其中的 UI_Code文件夹复制到 Hardware 下:
& {  u3 I% ]1 o2 z& l5 C9 B% e8 G* t9 u% V2 e) n+ t' R" X
4 @0 x% O" E& E- x- L
7.png
8 n0 R8 t0 V) N; A* s- Q# _2 `8 Z. V  \* V. M. m% G

' i( M1 G# ]$ H; L' l* i- O, P    在 MDK 工程里面导入UICode下的GuiLite.h和UIcode.cpp文件。
: n8 x, |2 r2 C" o6 [, B4 G& H  A0 a; g) U9 i$ l

  ]) h+ X* v5 w8 B9 ?* l2 D) w 6.png
! _0 b4 m: c9 j# F, m* ~3 h3 R- b8 g
) [( R' Y: z/ ^9 ^4 I- s+ |; S( v

8 y! l# e, X3 q$ V0 j    我们在 main.c 文件开头添加 GuiLite 接口代码,接口代码如下:, M$ v8 Y  L) L3 \7 x, _( M5 [
  1. //画点函数接口
    0 V" P8 n4 C# N
  2. void gfx_draw_pixel(int x, int y, unsigned int rgb)
    : ?: z$ D* L5 ~2 j
  3. {: m% E0 e/ D# _: [. e2 \' }; V  z
  4.     OLED_DrawPoint(x,y,rgb);
    4 F+ f0 R+ j7 F5 ~+ c
  5. }
    : S8 Z( A' a" ^0 }- @0 V
  6. //画面函数(未使用)
    5 x( r$ J/ @. f+ h, x
  7. void gfx_draw_fill(int x, int y,int w, int q, unsigned int rgb)
      c6 O  L1 `8 Y( L* a+ d  L" ~
  8. { , U: q/ X- _( p8 @- m
  9. }
    : M# N4 H8 u0 N6 e
  10. //创建一个函数指针结构体
    & b1 q2 _% Z' }6 Y
  11. struct EXTERNAL_GFX_OP- {+ u6 p' G0 }: f* Y" S5 s, x
  12. {* M* L% B: b6 X; C3 E5 D- b2 }: h
  13. void (*draw_pixel)(int x, int y, unsigned int rgb);4 g7 _. |0 o2 w
  14. void (*fill_rect)(int x0, int y0, int x1, int y1, unsigned int rgb);
    . B7 W% T$ i+ B+ j
  15. } my_gfx_op;
    0 ?" k' M( V# X% H! ?; |) w
  16. extern void startHelloCircle(void* phy_fb, int width, int height, int color_bytes, struct EXTERNAL_GFX_OP* gfx_op);8 w7 R: ^2 f. S& H: j

  17. ' }4 I, F3 C# S, N
  18. //设定延时函数接口' [& }: v& J( Z
  19. void delay_ms(int milli_seconds)6 w$ b1 m1 F. L$ z" k6 p, X
  20. {) l: \7 \( `: Z& P5 ~9 Y7 w; r
  21. HAL_Delay(milli_seconds);* F+ h7 c0 n' e# `3 @/ V/ Z9 G
  22. }
复制代码
- K3 H  W1 M& l. a2 H. U2 j5 L
' T, N3 z6 I! }1 S) V% ~/ m" ?
7 K1 k* u/ L. H
之后在main函数中添加如下代码:  B! r' j2 _+ q% C% C
  1. //传递函数指针
    5 n: [$ |/ h9 Z* t* D' i' L
  2. my_gfx_op.draw_pixel = gfx_draw_pixel;8 E7 |6 D: Q& L: N" d% U1 S
  3. my_gfx_op.fill_rect = NULL;//gfx_fill_rect;
    9 W: t* A% i& V2 @: b1 |( u* E
  4. //启动画圆
      i" E2 ?; j- ?8 Y. q
  5. startHelloCircle(NULL, 128, 64, 1, &my_gfx_op);
复制代码

* L  I8 L' O2 z" o& ]5 ]

, I& P% f. o: `* |' _/ U 然后我们修改UIcode.cpp文件中的代码,添加OLED头文件,以及在UI执行函数界面处添加OLED刷新函数。
: Q- u3 P( q/ h

" |% b7 T& Q% u& I5 _

7 q$ f% t: ]& U, Z  G4 E- ~" |* K 5.png   ^5 O* r. k4 B3 n- p

! z+ a! D- f3 h( B% Y1 A) @+ r
0 b. l) B0 F3 E% a; E) V
    之后在UIcode的第8行修改3D圆的参数,因为OLED大小128x64 ,所以我的配置如下:$ W* }! z1 z3 c. _/ ?
( e$ u6 m+ _5 O: E1 G; ^

/ P9 ?  K( {6 C+ t% J 4.png
( e1 ~; ^5 I  N  T  Z! s# W( S7 ?
/ ~! h/ ^" j4 B. i

. f$ \5 M7 Y: S2 \    配置完成后,我们关闭Use MicroLIB选项,编译代码:
2 u7 J! r$ L8 J( U- o# n5 a
: |* X) o! x; q
' e8 [- \2 T6 r- ?
3.png ) \1 t' [6 o# t5 o
1 N6 z! N2 w- h( C6 |1 p

$ Z* X: ~) K4 f3 }2 ^* G    编译成功,下载代码。
7 v- [$ Y( J. p& W5 _" a2 b7 |+ l4 k8 E6 n
& B& w4 o3 t3 X6 x% @0 z5 `
2.png
/ k2 a# ~% v/ v0 X4 h0 M
( E7 \# E3 d; I. g/ g
/ Y0 z0 v- W* @8 m5 j
    下载完成后程序复位,可以在OLED上看到Demo的示例动画。
6 A/ S  B6 c' o! r: @$ g& {8 f0 q& K- |* \% V& t4 f
- P8 b3 x- ]0 d, c
1.png
  u- p, L$ t. Y5 M( L( o: }( Z! R% i2 z
转载自:[url=]芯片之家[/url]
" w' t/ C; ^' I: e! b1 h& F3 m) O/ I

9 l2 q! I8 O4 I
收藏 评论0 发布时间:2023-3-4 20:00

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版