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

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

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

. S2 V! b# O& T2 G 17.gif
16.gif
; M" K0 w; v* }; \4 r
2 GuiLite介绍0 c$ i+ D( u6 K5 F& X
    GuiLite是一个开源的图形用户界面框架,只依赖于一个单一的头文件库(GuiLite.h),不需要很复杂的文件管理,代码量平易近人。  M1 N0 {  e7 {1 n. ^
    GuiLite由4千行C++代码编写,单片机上也能流畅运行,其最低的硬件运行要求如下:* F! ~2 V" G# I4 H& {" o3 V

! l- Z% {+ P) i5 W1 ^
- a  }+ q  K1 |, N# V1 \3 D
15.png
5 [6 d& v6 Z, V
5 [+ \8 }, f# T  d- e1 ZGuiLite具有很强的跨平台特性:
  • 支持的操作系统:iOS/macOS/WatchOS,Android,Linux(ARM/x86-64),Windows(包含VR),RTOS… 甚至无操作系统的单片机
  • 支持的开发语言:C/C++, Swift, Java, Javascript, C#, Golang…
  • 支持的第3方库:Qt, MFC, Winforms, CoCoa…
    ( G& F/ R# T" D# A& p
  • / |5 ^2 v% t  K, B7 Z

    0 C) X8 C. x2 m
GuiLite 提供一系列辅助开发工具:
  • 完美的“云” + “物联网”解决方案:让你轻松驾驭全球IoT业务
  • 支持多语言,采用 UTF-8 编码;
  • 资源制作工具为你定制自己的字体/图片资源
  • 所见即所得的GUI布局工具
  • 编译活跃度统计,及实时分析
  • 支持3D & Web
  • 支持Docker,一条命令启动。
    5 D( S- K3 d/ N. i# K4 N

9 K0 a; x. V* N, r* d  G) [3 GuiLite移植
2.1 所需硬件
- ]: N1 w* O; E
7 t5 a. }, ^" P- ~, y. C
3 a* j5 u6 ~( {
14.png
/ Q( I/ \7 z3 [7 V8 ~0 j: ]* C) _7 ]; D
* n8 H- _) U. n) {

, W! M  V' e) l/ q: A. qSTM32F407开发板) q* i& M8 _' ^' U4 B
$ a  Q7 G  ~  M

; `" D$ Z# [8 o# W  Z% r. J7 } 13.png
! \/ n# B7 H7 b$ W
" |( l3 a, D8 `, N
) F/ `3 z* X, o
OLED屏幕
3 Q, Z8 i1 w/ x  g
0 V* v# N  U, y9 t* j
4 \9 N8 g$ Q0 v$ o, G# f3 P) K
2.2 驱动准备
$ {, F2 [/ ~$ r/ i; Y4 k    这里我使用STM32CubeMX 对开发板进行外设配置,开启STM32的硬件IIC,这里我用CubeMX开启后如下:
9 \$ M, v, s  F6 t, I0 o4 F* m6 {" @- G( W0 Q

7 m( P+ p( d  l/ c. J 12.png 5 w9 T: Z: c/ f

% B! U4 {1 v0 Y) [/ u+ g* L

7 {/ @; H0 P+ N) o( {6 h    配置完成生成代码,同时将分配的堆空间增大:$ C& d3 S& Z. R+ O

* Y1 @3 _+ y! B, o! e/ y2 ^

- k( [. {( H$ [0 c4 j 11.png ! N" o, e+ J; R, F

+ p  t" u2 O' e  ]8 M" y
8 W3 L4 m, ~4 l% E, T. q
    代码生成后,我们复制正点原子的OLED驱动工程代码到Hardware硬件目录下,自己创建一个该目录。
5 Z. w" N% z1 z5 w' Z* y
1 B5 B1 m$ m- g$ n/ g8 j' }

0 Z4 Z( {/ r/ y: g+ V3 q 微信图片_20230302201518.png
8 c% U8 |8 n3 z! l* ]8 U$ C1 _& h+ U) j4 `  L

5 O& }. f  j, C1 g3 I    在MDK里面添加文件,然后我们进行修改,注释掉头文件里面关于端口的定义,同时添加三个类型宏定义。& ]6 N1 s- O7 h. F& p

# l" j, M, c  _
! b0 v  \; i! U
10.png
( E) e% I6 P# Z# H  H& h; |9 I8 F: V1 D3 S  }$ V5 |

) ^* y$ x3 m9 `$ x( {/ \    然后我们进入oled.c文件,将void OLED_WR_Byte(u8 dat,u8 cmd)和 void OLED_Init(void)函数分别替换为下面的内容:
" ?2 v: f- ~$ D) W& COLED_WR_Byte:
. {! e8 |5 e" X+ ~2 J( f1 v
  1. void OLED_WR_Byte(u8 dat,u8 cmd)
      @) N! ^5 I/ R0 Z  v
  2. { ' F" |& ]/ Q6 Q. t3 g* ]9 R: u
  3. if(cmd)
    , _4 L* C; g% _$ }$ s2 R4 h
  4.   HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100);0 K3 T8 M2 Z0 Z" K/ {$ R
  5. else
    # X* J5 u% S) ]1 H
  6.   HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100);
    - N$ |$ i  B  P7 I) j. V
  7. }
复制代码

) @8 T6 D- O( G& F) @5 E6 ~
: k4 {9 S# C8 }2 z: Y9 t
- L2 j! y) q9 b4 A& ~9 L
OLED_Init:
$ W; L' P# q( t$ g9 K& q% e8 e+ ?
  1. //初始化SSD1306         5 V. @5 U1 K+ c- M, K- E9 T
  2. void OLED_Init(void)' ?/ [" T" ^  Q  f: i& h
  3. {        
    5 e. m7 l; j/ \! Y
  4. OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示& f: h' k/ j7 k# e' X4 c
  5. OLED_WR_Byte(0xD5,OLED_CMD); //设置时钟分频因子,震荡频率" a. j2 l0 k% Q2 x0 |; E' x7 V
  6. OLED_WR_Byte(80,OLED_CMD);   //[3:0],分频因子;[7:4],震荡频率
    4 T& A( {# @/ K' e# l+ r, ~$ Y3 r6 n
  7. OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数0 r' H' h# j, Q. ?
  8. OLED_WR_Byte(0X3F,OLED_CMD); //默认0X3F(1/64)
    / _7 q/ v6 ~0 E; }' h  B
  9. OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移
    2 _# a) f9 P- u
  10. OLED_WR_Byte(0X00,OLED_CMD); //默认为0
    , m6 a; B6 n/ g* k! L6 r1 B

  11. * h8 X& ?, ?4 W7 ?
  12. OLED_WR_Byte(0x40,OLED_CMD); //设置显示开始行 [5:0],行数.
    9 M% ^; Y8 `: a2 g
  13. ( M3 Z) s* u6 i& x/ z, Z
  14. OLED_WR_Byte(0x8D,OLED_CMD); //电荷泵设置
    5 U* c9 f; L- n! i1 [' u
  15. OLED_WR_Byte(0x14,OLED_CMD); //bit2,开启/关闭: i. O+ ~! k( l) }4 R
  16. OLED_WR_Byte(0x20,OLED_CMD); //设置内存地址模式
    7 R' L9 n% N. \3 P  o+ }2 ^
  17. OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;$ @: {* a, r" n1 h: f9 y  c
  18. OLED_WR_Byte(0xA1,OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127;
    + ~* i0 Q6 }3 e5 A1 ~- s
  19. OLED_WR_Byte(0xC0,OLED_CMD); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数4 l: E5 o5 e" [7 k  m8 H
  20. OLED_WR_Byte(0xDA,OLED_CMD); //设置COM硬件引脚配置
    9 m' n! ^+ @# \+ B: w8 x9 k3 O
  21. OLED_WR_Byte(0x12,OLED_CMD); //[5:4]配置) }+ k* _1 o) {8 p$ P. |& Y6 l, H
  22. " x0 ~) v+ p9 @$ N1 R, ?9 v, ~0 ]
  23. OLED_WR_Byte(0x81,OLED_CMD); //对比度设置* I5 J7 X" |4 D
  24. OLED_WR_Byte(0xEF,OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮)
    ' Q, z9 _9 K2 z7 W+ j8 y
  25. OLED_WR_Byte(0xD9,OLED_CMD); //设置预充电周期% \3 D; K5 k) x) \
  26. OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;: J* [7 m- j6 l2 D7 c: [9 b) N
  27. OLED_WR_Byte(0xDB,OLED_CMD); //设置VCOMH 电压倍率
    % a- M0 C8 F' B
  28. OLED_WR_Byte(0x30,OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;' K5 @0 a" ^" a& X
  29. 7 u( D7 r/ e* d, K* i& _
  30. OLED_WR_Byte(0xA4,OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
    " F+ x2 z# E* R& l9 ^
  31. OLED_WR_Byte(0xA6,OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示              - L2 |. O+ P: @+ a6 d6 e
  32. OLED_WR_Byte(0xAF,OLED_CMD); //开启显示  3 v0 D# k5 t* ~/ t6 B/ {
  33. OLED_Clear();/ m1 a$ n5 ~4 E( Y& t! w- N
  34. }  
复制代码
5 x. X; f( U  h$ J5 |$ H

+ z9 a! l9 a& d2 p. X7 J然后在main.c文件如下位置添加oled测试代码,记得添加头文件和头文件路径。
8 g. f( C9 s0 r7 z& A; m$ l7 Z

% o1 j" s/ e; c; u
, [1 [* ]; q5 Z/ a9 _
9.png
3 B4 ]! e0 ]- u9 q& J, g
9 I$ b5 O. z; _7 s! T
" e# R/ O0 ~  ^8 i
    下载程序,观看现象:# b4 c6 O9 s5 f5 Q7 K: M
! e: Y+ G* D+ G# D' @8 V+ E8 d
: ?4 D7 V; b  E) ~  w7 n! z0 p
8.png + v# v$ C; q* B% u

0 l, t2 d8 E* i

3 H6 n+ N1 N2 F5 p; S( w0 ]    此 OLED 驱动的准备已经完成,下一步就是移植 GuiLite。# E- B+ E7 g, j2 i1 u& \

. p5 |% ~1 Z) w! ^

# G  l/ R* Z  T5 u& E2.3 例程移植: M. f6 k2 u4 v: T/ w
    首先,我们上GuiLite的例程展示官网:GuiLiteDemo,选择Hello例程,将其中的 UI_Code文件夹复制到 Hardware 下:
8 X5 S, A, x$ Q3 Y, t1 ~- n! ^8 Z7 c, Z( a" z5 [, C5 U+ {/ A
* a4 ~2 k8 I" u8 R
7.png
' A: E3 n! z" B/ T, ]- z: Z! y5 P+ W" J- @

  f( D. F! `2 t0 p& v    在 MDK 工程里面导入UICode下的GuiLite.h和UIcode.cpp文件。
1 z8 L$ Y  e7 F0 f0 E4 P8 r9 U
2 z. T! S- B0 Q& Q8 J7 @

5 S/ U  }8 O0 u; S2 _# D 6.png
2 b* I+ I2 X8 e) c" {  L5 |9 D: @! k9 b% J
/ J  q# v4 b6 Y) K
    我们在 main.c 文件开头添加 GuiLite 接口代码,接口代码如下:
% ^0 @8 L( ?" @) y; }$ d
  1. //画点函数接口
    # y1 L) D) ]  {/ C  \
  2. void gfx_draw_pixel(int x, int y, unsigned int rgb)
    $ Q1 j/ j' B' ^3 z7 G0 ^; K9 J
  3. {7 w) d' g; U+ ?. W% |
  4.     OLED_DrawPoint(x,y,rgb);
    % }- I* Q% K- l7 W
  5. }; f0 S1 B. n/ \& D3 _
  6. //画面函数(未使用)
    / Q+ e& ^3 q! d3 @1 P0 Q1 `& X
  7. void gfx_draw_fill(int x, int y,int w, int q, unsigned int rgb)4 q; S, R2 ?  p* G
  8. { 4 d2 O$ Z  d, L8 j- {
  9. }- Z! N. D6 z* j' I9 o
  10. //创建一个函数指针结构体% C, ~* f+ d+ Z  N! }1 E
  11. struct EXTERNAL_GFX_OP1 e* n  j' s! o: [6 h, p
  12. {
    ! o+ |' b2 V2 c! a$ \
  13. void (*draw_pixel)(int x, int y, unsigned int rgb);
    4 C, z& u. J2 M5 m2 A7 {
  14. void (*fill_rect)(int x0, int y0, int x1, int y1, unsigned int rgb);
    . J, o3 c! _- ^  _3 ^
  15. } my_gfx_op;
    : V5 U2 x! ^- X  ^- L$ F
  16. extern void startHelloCircle(void* phy_fb, int width, int height, int color_bytes, struct EXTERNAL_GFX_OP* gfx_op);
    2 Y5 E' v* |! }  H( y% P/ C
  17. ! @# j4 z0 K) T
  18. //设定延时函数接口' X( A8 D  }& ~: d: j0 j
  19. void delay_ms(int milli_seconds)5 r/ B- o# J. [' v9 g5 H1 @
  20. {. H0 T# }5 Y# |' q- y
  21. HAL_Delay(milli_seconds);3 d5 k" I+ d7 L8 ?5 C8 ?& i/ O
  22. }
复制代码

1 U5 f/ H( {! c, y% k0 |0 ?3 K: r( t& ?
" T* T! n0 h/ P
之后在main函数中添加如下代码:! F. C( y1 O  h( W. d
  1. //传递函数指针/ k% ^0 ^9 e4 ?5 L
  2. my_gfx_op.draw_pixel = gfx_draw_pixel;; _5 @+ e7 n9 e& m
  3. my_gfx_op.fill_rect = NULL;//gfx_fill_rect;
    - o$ Y$ d5 j$ I/ Z2 e
  4. //启动画圆
    : _9 M; j! i' H3 I- {/ ?' e
  5. startHelloCircle(NULL, 128, 64, 1, &my_gfx_op);
复制代码
% _6 g) L' ?% l7 q  A1 a
5 S6 L: S4 m9 S: D
然后我们修改UIcode.cpp文件中的代码,添加OLED头文件,以及在UI执行函数界面处添加OLED刷新函数。
! f* V; `& `( Q8 {
7 P( W. q$ f& [/ i; m; s2 D
6 V) F1 |! Q: ^7 b" j) s0 i
5.png
) h  @9 t) P3 |# X( B" b
) Y4 w3 C$ l8 \/ M# i  A7 ]. @

9 y8 A+ U  ]' O# G/ U! K- s! K9 F    之后在UIcode的第8行修改3D圆的参数,因为OLED大小128x64 ,所以我的配置如下:2 I' f4 i; U- X# j: K$ u# V3 `1 a
- D% m% ?' I6 ]- d' o' A
' |% t3 G: N3 }, K$ ^. x( g! G
4.png ' C5 B# C0 Z- a3 y  x

+ J+ B/ E, _$ V! r4 V) S3 }6 e. t$ G
. l+ ?3 E& E0 f3 r4 O
    配置完成后,我们关闭Use MicroLIB选项,编译代码:
& B; v, }5 f- V6 [
$ _' k3 q4 `) C/ N4 V' z

' s4 f* y3 m' @; C' s8 B 3.png
" o9 b* h2 G6 e- z0 K; ~# H: |2 d& j% ]! _

) b+ X1 O1 v# n+ Q1 H, R    编译成功,下载代码。
7 H' h7 O' m, ?5 g' o
6 g+ |! Z: R8 E; z8 R' @. Y# g/ ?
+ \& \2 W; P% f6 T* G* R, z
2.png * l. v# |, S8 h. q  m" J
# |. M# z" X1 g2 d; \  y' L4 X0 {% Y
0 j' i! N: O/ k0 T# H5 E* k
    下载完成后程序复位,可以在OLED上看到Demo的示例动画。
/ f* D4 b5 b; Y& {2 ^( @5 `8 w& k3 o
( _( q  ]" o0 R
9 z! E  n8 S6 Y* k! u
1.png 9 h# p: z+ V5 ^6 v3 s2 z; m% Y
2 X& J* m; A1 \$ h
转载自:[url=]芯片之家[/url]# l4 g. c0 ^% u. L2 M6 m

: r: ?* Y1 N+ ^0 b; H" _

1 i# w4 B8 B+ C7 w8 Z+ e. ^: O% v
收藏 评论0 发布时间:2023-3-4 20:00

举报

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