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

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

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

2 u) b4 T1 U  @  @: @ 17.gif
16.gif

2 k6 Z- d- i; M: f6 g% Z/ ~
2 GuiLite介绍
0 C' D  I+ A: F# |! I    GuiLite是一个开源的图形用户界面框架,只依赖于一个单一的头文件库(GuiLite.h),不需要很复杂的文件管理,代码量平易近人。& D7 M5 [- I2 b% ?5 J3 k
    GuiLite由4千行C++代码编写,单片机上也能流畅运行,其最低的硬件运行要求如下:
; a8 L% h! u4 Z) n& L' V; m2 F. x$ X
+ D, k6 A, B" `' @% m
. |6 M3 ^; G- a5 Q+ H4 g
15.png * S  p% C' Z) O: a# L9 _5 t$ H
* \. u, h* r; X& c+ {( @
GuiLite具有很强的跨平台特性:
  • 支持的操作系统:iOS/macOS/WatchOS,Android,Linux(ARM/x86-64),Windows(包含VR),RTOS… 甚至无操作系统的单片机
  • 支持的开发语言:C/C++, Swift, Java, Javascript, C#, Golang…
  • 支持的第3方库:Qt, MFC, Winforms, CoCoa…
      y. t6 g, {( V* n- E
  • 1 G+ q, P4 [& v9 R
    0 c" W- U( ?/ s$ o$ Q( `7 P
GuiLite 提供一系列辅助开发工具:
  • 完美的“云” + “物联网”解决方案:让你轻松驾驭全球IoT业务
  • 支持多语言,采用 UTF-8 编码;
  • 资源制作工具为你定制自己的字体/图片资源
  • 所见即所得的GUI布局工具
  • 编译活跃度统计,及实时分析
  • 支持3D & Web
  • 支持Docker,一条命令启动。8 m# |( s: ]8 M3 b4 h$ p  D
' f3 l( D" l* N1 ?- I" W& @1 |
3 GuiLite移植
2.1 所需硬件) ^; O- p! x) Y' d. R0 L. {  b8 M
$ _: r& g& H# Z4 {  H  j: H+ d! N: L
- R1 y, u; l3 E* p- J9 _+ B
14.png
# B9 \$ }' C# d: }
  E  l" p7 G! U" r- C& Y
( i" V' ^$ z2 G. ]/ b; g' L
STM32F407开发板
' s- a# j5 s# l9 A, F/ f% n
* p, I" P4 T( ?# O( J
* o- g9 t) O8 h  m6 B) f* ~
13.png " K# m, r1 W) |! n& `, M! J
/ N0 n4 P+ P, b& c

8 n+ |/ p) f2 g- R" f; L( |3 b* YOLED屏幕
9 _; k! Y3 z  r5 R2 }* v2 t, M% t/ [0 D: ~4 E# k! ~
0 y. j. m0 a9 h
2.2 驱动准备
. s' }% T; y* o6 F9 H6 ~0 ~    这里我使用STM32CubeMX 对开发板进行外设配置,开启STM32的硬件IIC,这里我用CubeMX开启后如下:2 {& z/ y1 R. u
8 }9 }6 W4 d8 r6 ?2 j3 y5 W
  F. M1 \  j: G9 g5 J& {
12.png
4 i* S' n8 i) H  ?2 H* b1 {3 s  j3 V8 r* {+ O$ P

3 T' n. R' g+ P* q2 s    配置完成生成代码,同时将分配的堆空间增大:1 |6 {/ J! C+ q8 z; U8 D; i. a

# z& h# X2 H! b9 i' p4 ?
* m* M8 n1 H4 A
11.png
- r: S6 _' i( t5 E* k
$ C) R8 B; h$ ^
  {, z( B5 b. V, W6 c
    代码生成后,我们复制正点原子的OLED驱动工程代码到Hardware硬件目录下,自己创建一个该目录。/ s3 e0 B. m7 K  ?
( f" t% ]% R1 n. @" o% X+ T: e. w

$ H& t) d  _7 Z- X! I 微信图片_20230302201518.png 8 Z$ r, O0 |1 N3 |! a3 \

( l! q4 D) w3 Z

# g" N4 x; X* S4 h+ m    在MDK里面添加文件,然后我们进行修改,注释掉头文件里面关于端口的定义,同时添加三个类型宏定义。
: ]3 g  e/ ^( h0 R9 z" ?4 v0 d3 A' K
8 y" I( V% S9 o2 f
4 R# c3 x- E$ V6 W, h- h' ]9 x
10.png 0 b- }; }* N+ N9 P+ x  o# r6 `
- I  T4 G" i& y3 w
# D, E5 Y; u0 B! N' X$ [
    然后我们进入oled.c文件,将void OLED_WR_Byte(u8 dat,u8 cmd)和 void OLED_Init(void)函数分别替换为下面的内容:# I3 j! `3 _$ h& j4 s
OLED_WR_Byte:6 X7 |$ K- d: z  [* n
  1. void OLED_WR_Byte(u8 dat,u8 cmd); @" `( s" o0 O& G- B
  2. { ( S- B2 Q) ~  \* v4 m: v% ]0 X
  3. if(cmd)5 p  c4 e8 W" r8 J" ~0 |
  4.   HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100);
    1 Q* ]! D! Y; g7 k+ i6 v! _' w
  5. else
    8 g1 d+ I: l+ l  `3 s7 z% H
  6.   HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100);
    " Z( ~9 O  i9 [& y/ w! ~6 Y
  7. }
复制代码
' n8 B1 h" ]' h# D: o1 `

. X' m4 |. L+ c, Q4 U6 J

. Y5 Z+ _9 U# _9 H  q5 S! _, GOLED_Init:7 G8 g1 x+ o5 @, e7 r9 ~
  1. //初始化SSD1306         
    7 C2 ]9 e' D# N6 |
  2. void OLED_Init(void)
    - ]$ O0 \! F. U- Z5 D+ I3 `% g  [8 E
  3. {        
    8 w! s$ j. y% h. C7 K# g/ Q
  4. OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示6 T6 Q2 v0 B9 S- t% k) B
  5. OLED_WR_Byte(0xD5,OLED_CMD); //设置时钟分频因子,震荡频率9 k7 s( W0 o+ @' c" D
  6. OLED_WR_Byte(80,OLED_CMD);   //[3:0],分频因子;[7:4],震荡频率( A6 M$ M" o9 h( _" \* C: b
  7. OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数
    * m; f7 i% ?6 C+ g) R
  8. OLED_WR_Byte(0X3F,OLED_CMD); //默认0X3F(1/64)
    ( R8 v: i* ~4 U* {! C2 i8 x
  9. OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移
    # l9 P1 Q4 W7 ^  }2 ?
  10. OLED_WR_Byte(0X00,OLED_CMD); //默认为0
    ( {: J1 c2 R( I+ N# }
  11. 7 r8 m. l% u- i+ i7 w
  12. OLED_WR_Byte(0x40,OLED_CMD); //设置显示开始行 [5:0],行数.
    9 K& f$ F! `+ ^3 {3 A* O( c. I
  13. % A( W9 b: [: l+ i( ~
  14. OLED_WR_Byte(0x8D,OLED_CMD); //电荷泵设置0 `0 q0 Y: Y$ z
  15. OLED_WR_Byte(0x14,OLED_CMD); //bit2,开启/关闭9 |) |/ |+ V/ @( ~
  16. OLED_WR_Byte(0x20,OLED_CMD); //设置内存地址模式/ X! n9 ^* c* O5 G( O5 ]8 y
  17. OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;5 v3 }* P/ Y" i3 _' I* k
  18. OLED_WR_Byte(0xA1,OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127;
    ) v8 k) X" @  s7 _
  19. OLED_WR_Byte(0xC0,OLED_CMD); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数
    ) q2 ~/ b' |1 c: ~3 M
  20. OLED_WR_Byte(0xDA,OLED_CMD); //设置COM硬件引脚配置
    ; @% R6 h1 v" w" r6 d9 N+ J
  21. OLED_WR_Byte(0x12,OLED_CMD); //[5:4]配置0 q+ X7 a7 [/ ~5 A
  22. 3 ~$ Q- `; r' i: ~% N
  23. OLED_WR_Byte(0x81,OLED_CMD); //对比度设置- U9 N8 ]: [. G6 g$ F9 R; Z
  24. OLED_WR_Byte(0xEF,OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮): b/ k7 R6 t! ]$ W
  25. OLED_WR_Byte(0xD9,OLED_CMD); //设置预充电周期5 E$ I+ p' q3 m* O* ^) a
  26. OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;
    7 w, V  Y( M. u. A
  27. OLED_WR_Byte(0xDB,OLED_CMD); //设置VCOMH 电压倍率
    6 X  e3 g. S) a  i( e
  28. OLED_WR_Byte(0x30,OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
    4 A- h7 O+ C1 r/ _7 n+ D% h3 d

  29. + [6 n: I: S5 n
  30. OLED_WR_Byte(0xA4,OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
    , a& r1 l9 s7 V0 c6 k% K" B
  31. OLED_WR_Byte(0xA6,OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示              1 s: k0 S! Y+ `$ O2 c
  32. OLED_WR_Byte(0xAF,OLED_CMD); //开启显示  
    * v0 Q$ y; Y3 u- P; c: y
  33. OLED_Clear();
    ! v7 F. }, t8 m
  34. }  
复制代码
: @. P. k' q/ g) u: {5 Q4 H( S4 i5 s
  h& I/ w6 k) V
然后在main.c文件如下位置添加oled测试代码,记得添加头文件和头文件路径。

6 ^& n! R- w+ o3 s9 S8 x
. N2 N) Z3 C4 b9 y
2 s; b# z4 y% k; z4 s
9.png 2 A/ c* _3 G1 I1 d1 v3 |

5 F8 Q  ~. c$ d

: ^; Y& c6 x4 D- ~    下载程序,观看现象:4 @5 Y/ ?" C" P3 Z
' p# ]" [; {& a3 {5 W8 Z% v. M
. p# l1 E* B1 j
8.png 0 x4 {0 l4 q; I" y

3 k! b8 F7 V/ j; ~

, S& p$ P7 O" g% F    此 OLED 驱动的准备已经完成,下一步就是移植 GuiLite。
! s7 N/ v+ C* \& w; t! T7 s
, W) }1 G5 j8 p8 x

$ w+ n0 u4 Z3 K' F8 [2.3 例程移植1 a8 O4 q' i5 O7 O& e
    首先,我们上GuiLite的例程展示官网:GuiLiteDemo,选择Hello例程,将其中的 UI_Code文件夹复制到 Hardware 下:
8 G  C0 O  A$ E: j1 J7 F2 V! A  k0 b
% |* r" C- z+ ^- o1 E
7.png 9 m- F3 v1 E7 ~# o! G6 P* S+ K' o
- ]7 ~! H4 S+ I% G; y0 o
2 `9 L7 B/ S+ e7 L/ q1 L( x
    在 MDK 工程里面导入UICode下的GuiLite.h和UIcode.cpp文件。
; o( [! u0 A! m+ S7 D# T4 F* `& C' s3 q" a  h4 i

$ W) O8 K4 j5 F 6.png ; f3 Y: q# B9 d$ L1 i4 G
" t6 o5 }& M# w. b3 h' E

. D1 y( j$ \5 p! J    我们在 main.c 文件开头添加 GuiLite 接口代码,接口代码如下:3 o# I/ Q' Z/ n6 F& L0 i
  1. //画点函数接口) h7 z% l7 k7 L/ b  _6 E
  2. void gfx_draw_pixel(int x, int y, unsigned int rgb), {. n- Q- d& @7 B$ Y& [. `  N
  3. {) F* p2 _6 y! @2 i$ w: P) x2 e* J9 D* R
  4.     OLED_DrawPoint(x,y,rgb);
    5 ?" T6 X, a$ W: C( z! q
  5. }
    ! `9 s% H/ G: {/ {
  6. //画面函数(未使用)
    9 F7 h0 D& y. H1 j( g% B5 F1 c
  7. void gfx_draw_fill(int x, int y,int w, int q, unsigned int rgb)6 ~0 @% @# o( x& w& }% R
  8. {
    , i/ u- q: B2 M) v) |6 ~% L
  9. }
    ' S) N3 F# r5 \+ I5 c" v
  10. //创建一个函数指针结构体
    & e. T3 `$ K! G) W
  11. struct EXTERNAL_GFX_OP1 [9 U8 I8 K9 d& T! `, ]( T
  12. {: i" s, |$ H+ x9 d8 L
  13. void (*draw_pixel)(int x, int y, unsigned int rgb);$ K2 s8 F+ q( Y9 h7 m
  14. void (*fill_rect)(int x0, int y0, int x1, int y1, unsigned int rgb);" K" n0 e- L$ m  t/ a, h8 k. K3 p
  15. } my_gfx_op;# b: M3 U/ }0 }8 c, e  i" S
  16. extern void startHelloCircle(void* phy_fb, int width, int height, int color_bytes, struct EXTERNAL_GFX_OP* gfx_op);
    9 v4 z  O5 [$ E, c4 p

  17. 2 p% w- f- W' o7 h3 p3 g
  18. //设定延时函数接口6 g' \" w2 F( {$ c* M  M2 m
  19. void delay_ms(int milli_seconds)! x# z3 |* Y7 Q! Y
  20. {
    * d; J5 X! f( ^: x8 c
  21. HAL_Delay(milli_seconds);
    9 I) H& X9 D2 \6 Z
  22. }
复制代码

8 g7 `" p6 [) |0 H: K+ B1 |) |" k2 a4 g; Y* D  Z

' h7 m6 s$ h9 g. O, p; N9 x之后在main函数中添加如下代码:
% C5 ^; u& U1 L* n0 Z1 J: `
  1. //传递函数指针4 ^8 K6 J- D& D% X9 o+ H( h; e
  2. my_gfx_op.draw_pixel = gfx_draw_pixel;8 Z+ n# m0 c1 E7 {
  3. my_gfx_op.fill_rect = NULL;//gfx_fill_rect;0 k) V" {* |/ t4 V( f0 @4 ^7 G
  4. //启动画圆4 ?! ^% V( H! `! W' }- W, h$ N0 l
  5. startHelloCircle(NULL, 128, 64, 1, &my_gfx_op);
复制代码
! N( t' j0 K% r7 b; D, a3 a, I6 o7 E

3 y  `" A" r1 `8 @ 然后我们修改UIcode.cpp文件中的代码,添加OLED头文件,以及在UI执行函数界面处添加OLED刷新函数。

' q  K/ c  G# W: N3 j! m
  {* @) E- v7 q$ ?7 A. ]" [6 N
% p% q; |: {' m; p
5.png ; `* r# u9 v% [" O' x, K
  U- r) e- w) I$ _; L( C

; w7 k7 l) Y" f1 S) E    之后在UIcode的第8行修改3D圆的参数,因为OLED大小128x64 ,所以我的配置如下:6 D$ u0 m6 x9 t. I; l
* Q7 O# g# D8 V' x* r( }. s6 Q
4 B  b- c7 c& i7 }; T6 }' m$ Q  \
4.png
$ `6 @0 c9 r1 I0 {
% a/ D! S- U- W9 g" Q4 y6 }

' [& @, s/ r: [# Y  d& J    配置完成后,我们关闭Use MicroLIB选项,编译代码:
+ i. R- l7 @9 ^4 C. k
% L2 V+ y$ ]) y3 Q0 w4 Q+ t

5 x! J& t; {9 M/ J& C1 e$ T: | 3.png ! d3 m& F- O  O9 ?8 r$ K
( x# y; [4 r0 r1 t" r3 [: s
/ s$ Q1 x$ }/ z" [
    编译成功,下载代码。
8 N! x% {; x: Z- M0 _" G' Y& R- G) C3 l, g" H, r- G

, e$ s; b& T1 b/ J 2.png
% I7 z* e& J, m$ C1 `
  `( ^5 c! t" b: n$ }
& m8 F: M% s* E  `' C
    下载完成后程序复位,可以在OLED上看到Demo的示例动画。
6 z2 b( \5 V: F7 c5 V4 x- l0 w5 x
, h& l8 i9 Q) ?( `7 s3 m/ w1 N
- K# T0 s4 k4 k& ?& d1 ^9 f
1.png % S% I) J6 i  ?* }  C

# |5 ]4 A' w' i转载自:[url=]芯片之家[/url]
# G' B6 h, k& `- b4 s* _% {
- i" o" e$ a2 j+ p& e

' t. _5 T2 v# X1 n5 o( _/ G7 P
收藏 评论0 发布时间:2023-3-4 20:00

举报

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