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

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

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

: w; S# b) l! c2 i0 a% {6 M% W0 u 17.gif
16.gif
4 C8 h' j& w( r9 h
2 GuiLite介绍: V  g% Z4 j" t0 T# i3 o
    GuiLite是一个开源的图形用户界面框架,只依赖于一个单一的头文件库(GuiLite.h),不需要很复杂的文件管理,代码量平易近人。
+ |  a) \+ M2 l+ H+ c    GuiLite由4千行C++代码编写,单片机上也能流畅运行,其最低的硬件运行要求如下:% B* M( r2 a6 f

! l  J) A: c' A" `8 ?! N1 I

- f$ e" B" `' |/ ~, n; N% d 15.png
0 Z$ C4 w" r/ b+ s6 e' E* }6 ?1 M5 f; R
GuiLite具有很强的跨平台特性:
  • 支持的操作系统:iOS/macOS/WatchOS,Android,Linux(ARM/x86-64),Windows(包含VR),RTOS… 甚至无操作系统的单片机
  • 支持的开发语言:C/C++, Swift, Java, Javascript, C#, Golang…
  • 支持的第3方库:Qt, MFC, Winforms, CoCoa…7 z. `( s! T: ]- L# c  H

  • 0 l6 t5 H; H# m% `
    1 U5 Z4 r# E# @8 Z! h
GuiLite 提供一系列辅助开发工具:
  • 完美的“云” + “物联网”解决方案:让你轻松驾驭全球IoT业务
  • 支持多语言,采用 UTF-8 编码;
  • 资源制作工具为你定制自己的字体/图片资源
  • 所见即所得的GUI布局工具
  • 编译活跃度统计,及实时分析
  • 支持3D & Web
  • 支持Docker,一条命令启动。7 N( e1 x- j- L: b5 I: ^; Z+ M

' x' ~3 I5 j" s7 V9 E! W  l3 GuiLite移植
2.1 所需硬件
% ~; a. |6 `4 g0 l/ y$ ^0 I& I* K" O$ {  _: @
, M: C9 g: l7 m6 {7 `/ k1 D
14.png
) O9 v* F  d: l9 f8 p: e6 d" Z; ~& e

9 C6 l4 q: X0 f, SSTM32F407开发板; V" \4 F2 |. ~4 [3 s4 ]: M
2 H- M) J& b- R$ @
( }6 X6 Y0 y6 k; o% y$ A
13.png - e8 Y0 H, G+ e- G" v9 `: O# ?

: k, w6 R. f( n/ ]7 |2 R5 L( V: e
5 s/ V! N* V2 ~; O. _" t6 X" ]  Y
OLED屏幕: ^8 v( d" W$ L- K3 q

2 `; J* T+ l8 y
; T4 `# H9 N0 H& I
2.2 驱动准备
: z: {6 J' p( f. x3 o; k  w0 ]/ W    这里我使用STM32CubeMX 对开发板进行外设配置,开启STM32的硬件IIC,这里我用CubeMX开启后如下:
8 k3 o0 H$ X8 u! e1 d6 `3 I2 f2 P- X

  N6 |' ]( o" w: t  [: ]5 g+ Z 12.png   Z- V- D: G" d6 o% m4 D
; z/ Y: j9 I2 S& F
2 P/ S3 R8 `* B: R
    配置完成生成代码,同时将分配的堆空间增大:! t) h$ \/ [  d: x( c. o. P
% w6 m1 r4 X( _5 u& e
6 k; R1 o  c3 l; w, @0 B
11.png
" R% h$ |. B2 V. u8 r, S7 z$ T" E% s5 A9 [7 c  K
& d; \8 l% S! R0 I1 t+ N
    代码生成后,我们复制正点原子的OLED驱动工程代码到Hardware硬件目录下,自己创建一个该目录。' A$ v* G; |0 A3 _; `1 u* y/ W

, [0 \3 v# |7 M5 |" C0 q: T0 H. Q

2 l! {7 V! P. l  j. Q 微信图片_20230302201518.png + S2 p( Q+ u' L8 h5 B6 H' [
- G  E+ ^# n! t3 y

1 w* r5 q: o% G$ Q    在MDK里面添加文件,然后我们进行修改,注释掉头文件里面关于端口的定义,同时添加三个类型宏定义。
: b$ F2 s5 O$ w! x1 l0 M
1 B6 z; I& q4 D5 L1 [6 G+ b
7 ^) [! L2 J8 N. M! b% P7 v
10.png . `, G3 v* m' I9 `7 I. J+ v

# V: ^; x# q' H
+ {# ?# ^7 q) C; J/ V( I! f
    然后我们进入oled.c文件,将void OLED_WR_Byte(u8 dat,u8 cmd)和 void OLED_Init(void)函数分别替换为下面的内容:
+ g% V4 x; F. y" V. |  BOLED_WR_Byte:
, ]$ J8 E+ p2 \- N8 ^
  1. void OLED_WR_Byte(u8 dat,u8 cmd)2 ~0 Y, Q, }( C/ D6 _$ x+ B
  2. { * D! t1 Y8 o) }$ y
  3. if(cmd)
    ! c' K: L9 n  O. f7 W
  4.   HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100);% R. h: j/ \8 t3 z: f* `
  5. else
    % A6 h! x3 l, \; i7 }
  6.   HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100); * d! {( X" J" |- Z1 p
  7. }
复制代码

& z- k& ?0 N/ {( o0 y
. |+ e; S" X. X: T9 |1 P

4 z1 _' _% y8 C* aOLED_Init:8 |/ K" z( U1 q! p. @$ X
  1. //初始化SSD1306         ( O. I( X' f) v9 |
  2. void OLED_Init(void)
    & a: \! X3 G( H
  3. {        8 u" t6 U8 ~4 X3 S4 C0 C
  4. OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示
    ! \, I/ j/ M+ E, N# J2 i
  5. OLED_WR_Byte(0xD5,OLED_CMD); //设置时钟分频因子,震荡频率
      Z/ E+ K6 K- j9 M8 k1 r, I
  6. OLED_WR_Byte(80,OLED_CMD);   //[3:0],分频因子;[7:4],震荡频率% [+ b  z1 T' X; {  ?
  7. OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数" U( u9 [0 R3 J: C  G; T8 k( B
  8. OLED_WR_Byte(0X3F,OLED_CMD); //默认0X3F(1/64) - v% g$ P+ D( q3 V1 X
  9. OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移
    7 J9 T. |) ^$ [, F- s2 W$ g
  10. OLED_WR_Byte(0X00,OLED_CMD); //默认为0* H. F; k9 I3 p+ Z7 j

  11. + f$ p; }( q3 ^/ j3 o: W8 V- t
  12. OLED_WR_Byte(0x40,OLED_CMD); //设置显示开始行 [5:0],行数.
    $ Q  S  O2 l% U
  13. 0 r# w, }, v, V" x, ]3 |3 \
  14. OLED_WR_Byte(0x8D,OLED_CMD); //电荷泵设置
    * j$ ~' d  }9 f0 A* d& b
  15. OLED_WR_Byte(0x14,OLED_CMD); //bit2,开启/关闭
    + j& v3 r4 }# n4 }: G( C( @
  16. OLED_WR_Byte(0x20,OLED_CMD); //设置内存地址模式' [6 @6 Z: ^. m( f
  17. OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;( Q6 u+ [9 R4 m6 [* t9 t
  18. OLED_WR_Byte(0xA1,OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127;
    4 Y4 Q# d7 K6 d' ^, x  ]# `/ ~
  19. OLED_WR_Byte(0xC0,OLED_CMD); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数5 i+ O2 O5 ^0 K5 ?
  20. OLED_WR_Byte(0xDA,OLED_CMD); //设置COM硬件引脚配置
      l# w  B- \# X1 k2 {
  21. OLED_WR_Byte(0x12,OLED_CMD); //[5:4]配置
    ( d9 k5 K1 |4 A% D9 a
  22. - ~2 H! `. Y/ H9 K$ g
  23. OLED_WR_Byte(0x81,OLED_CMD); //对比度设置
    2 n) J9 S0 p) h+ t( Q; r* r. s& D
  24. OLED_WR_Byte(0xEF,OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮)
    + ?3 \' |& y- y* X# M4 j5 y
  25. OLED_WR_Byte(0xD9,OLED_CMD); //设置预充电周期
    6 e  U0 s  D4 k7 n* f2 `7 R- b
  26. OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;
    . E+ I9 s* @3 {4 r* y
  27. OLED_WR_Byte(0xDB,OLED_CMD); //设置VCOMH 电压倍率
    5 a* `& L- Y1 d0 m- C5 r
  28. OLED_WR_Byte(0x30,OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
    1 J7 {( |, k. t* W% S! W
  29. & v1 F$ g' Q, T+ X% N0 f& e6 d
  30. OLED_WR_Byte(0xA4,OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)' Y; x* M& A! e1 `4 N* g
  31. OLED_WR_Byte(0xA6,OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示              
    2 H: l- ?; u3 R* h
  32. OLED_WR_Byte(0xAF,OLED_CMD); //开启显示  ; x' \6 h& E) S8 T8 Y) B9 h
  33. OLED_Clear();% m4 C4 t0 l7 }9 w6 ?" \
  34. }  
复制代码

5 q7 a7 X. y  ]
9 \# G9 Y6 B7 a3 Q
然后在main.c文件如下位置添加oled测试代码,记得添加头文件和头文件路径。

' [7 X: q) |5 C: k% D/ l0 U5 B8 W! j
2 _0 R$ G$ h4 p3 v
9.png ) K7 l- A1 Y, a0 s

+ p' @9 c% d& k$ ^: a

% c3 x, h. N, N- X    下载程序,观看现象:7 D2 M  S7 [9 f2 w" {* ^/ ~; H
* V! y5 N0 S1 Q+ y$ k
9 ^9 Y9 Q8 c$ @% T" Z) a
8.png : }% j6 d# k+ P( F- M5 j
5 c$ e& S' g! |# q9 F- a7 w

& l$ H& W, B+ c8 P2 E* d    此 OLED 驱动的准备已经完成,下一步就是移植 GuiLite。% ?+ f; ?& _6 A: q8 z( l
3 T: e8 \& s6 n0 [5 D6 D, D
- R3 `8 l$ @9 _9 ~; Y1 w) A
2.3 例程移植5 q: X# F8 R. ~7 I4 T# T  P6 n2 [
    首先,我们上GuiLite的例程展示官网:GuiLiteDemo,选择Hello例程,将其中的 UI_Code文件夹复制到 Hardware 下:
' c% N2 b# Y' C5 y& M! g% _/ U8 w) c

5 ^- Q  q# [2 F6 P. l) F8 s( O7 P 7.png
& E! ~/ f  N( ~& B9 U3 G9 s9 H. h2 g# Z) N
1 R* i' m8 `) Z" H2 s- q
    在 MDK 工程里面导入UICode下的GuiLite.h和UIcode.cpp文件。0 x' W/ V% e7 {5 E; E0 E
0 Y7 s  c( L& ~) L# y' Q* r* D

& U% u9 _2 w! }" @ 6.png
9 S/ D* W$ c+ G) ]$ v, Z8 T9 M
7 i# ^, i( f! d; g
2 m' G( f, @* p0 F5 M
    我们在 main.c 文件开头添加 GuiLite 接口代码,接口代码如下:
4 \3 U# w+ Z- c2 @: @( m
  1. //画点函数接口
    . _; \( W/ _+ j0 W0 B  N/ x& E
  2. void gfx_draw_pixel(int x, int y, unsigned int rgb)
    $ R7 e; t8 Q& g4 z' ]1 h
  3. {4 ?1 ^" i. S5 {/ K) \1 O
  4.     OLED_DrawPoint(x,y,rgb);( y6 x4 ?, f3 T
  5. }
    / r5 Z8 v7 r$ {1 W: }5 @+ r) Q
  6. //画面函数(未使用)
    , }. g( j3 a7 ^: I
  7. void gfx_draw_fill(int x, int y,int w, int q, unsigned int rgb)/ _, g% z& g3 A" S: {# i( A
  8. { 8 o/ Y! k: f  R* V* k) m3 G, Y, v
  9. }0 |- L7 _9 L0 C1 {. h6 k0 c
  10. //创建一个函数指针结构体8 r' p% W7 h6 o0 h1 f3 K7 ]" q% p
  11. struct EXTERNAL_GFX_OP
    # \' z+ e5 i: y5 {4 U
  12. {3 m4 }% c# ?0 [
  13. void (*draw_pixel)(int x, int y, unsigned int rgb);# C$ f5 ^& b% P3 s9 J
  14. void (*fill_rect)(int x0, int y0, int x1, int y1, unsigned int rgb);2 x& V1 Y8 [- H4 k' _* L* Z- e' d
  15. } my_gfx_op;
    , c$ C. x' N' y# H, P: y8 Y
  16. extern void startHelloCircle(void* phy_fb, int width, int height, int color_bytes, struct EXTERNAL_GFX_OP* gfx_op);
    & z- a# P  q: H+ i+ X

  17. 0 e( R1 O8 U  q: g  }
  18. //设定延时函数接口
    9 y+ m- V, G1 p8 _( X0 S+ T$ u# h
  19. void delay_ms(int milli_seconds)
    , W* q4 j, C3 }9 U
  20. {
    " _2 N3 J2 g8 G9 s" ]4 ]4 M
  21. HAL_Delay(milli_seconds);
    1 _, p" q3 \' v: [
  22. }
复制代码
) C! |0 E) n  u
" k; S! G& Y- G# n
/ \2 P* U2 L7 B$ ]* V  J+ h( l/ o0 \
之后在main函数中添加如下代码:
, G: \& B$ N& [7 p$ k
  1. //传递函数指针  k3 p6 s, g, p3 f* A9 {4 V
  2. my_gfx_op.draw_pixel = gfx_draw_pixel;% l9 G4 Q5 N8 W3 m3 w2 P/ P8 W$ ]
  3. my_gfx_op.fill_rect = NULL;//gfx_fill_rect;4 l7 q3 t: J- b* [
  4. //启动画圆
    $ j5 _! O5 ]. m& r. A! B3 n1 _
  5. startHelloCircle(NULL, 128, 64, 1, &my_gfx_op);
复制代码
7 o; P+ T. y9 G- `+ E: Z! t' q

/ L" M# V; ~: U4 d4 w 然后我们修改UIcode.cpp文件中的代码,添加OLED头文件,以及在UI执行函数界面处添加OLED刷新函数。
1 t6 P4 A& G' @2 p: C5 |

, n, [$ u1 M# q0 s
. B* b( A  d3 }6 l/ Y
5.png 1 @; y4 ?% c; Y* {0 _2 Z6 X" s. L9 S
! L8 C+ n/ O% D* y$ K
7 Q% u( j. A& U' s: u0 l
    之后在UIcode的第8行修改3D圆的参数,因为OLED大小128x64 ,所以我的配置如下:( n  T) o3 d+ q$ q  g8 ?
* A$ y* `6 Q0 k6 M/ f' Q9 J
. w( O5 x) R1 K9 J' q
4.png
& D; y4 [2 z. b7 r5 d! ?, U- A5 U1 y  }6 l/ V8 [6 U5 ^% ~7 _

1 c! i; O# x- @3 L- B, `- J    配置完成后,我们关闭Use MicroLIB选项,编译代码:
9 ?4 _1 h0 P, a% f) W) s4 B0 r6 ]0 {, }% Q, ?/ [& e# o9 m
# c5 N' P& h  D
3.png
9 @0 {4 v' O" X. Z+ [" Y4 W6 \
! f: c7 r4 o# O( Q. l
: P9 ^+ a0 Y% n5 _  K4 n
    编译成功,下载代码。
$ b8 {7 `% D# i4 E
$ _/ I5 }) Z3 D% s; n

- g; B" @+ b" }9 b9 W( [ 2.png ! j+ U2 W' x( w: G9 a

0 t1 ^" W% A5 a% L' c0 {
  e$ a7 j! _/ J" t  a
    下载完成后程序复位,可以在OLED上看到Demo的示例动画。
9 a& `1 K! h: ]. t5 k7 o
6 X& V$ v' {5 g9 |* V. @3 E5 N; R  S

4 ^3 T/ B$ e* ~8 d" z6 s7 Z; ? 1.png 0 u5 k, U+ j* }5 w, r! r/ F) I
) E; ^# X% i. V
转载自:[url=]芯片之家[/url]% t! x5 v( F- r7 ~  B
" B2 y- W( j* h) W% ^

, W# K# L. v- ?4 p9 Q4 \/ D' _& ]
赞 收藏 评论0 发布时间:2023-3-4 20:00

举报

0个回答

所属标签

相似技术帖

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