1 Gui移植结果 一些演示效果:
$ e- u$ P9 P# f# W2 GuiLite介绍/ I& T0 {9 {# A% h3 Y2 q$ `
GuiLite是一个开源的图形用户界面框架,只依赖于一个单一的头文件库(GuiLite.h),不需要很复杂的文件管理,代码量平易近人。
9 ~: G& @9 r2 y( R GuiLite由4千行C++代码编写,单片机上也能流畅运行,其最低的硬件运行要求如下:
( B& B& P. [6 a H& S+ q- B. |' U1 B
. M/ r( k; h% D) D# p" g4 f. _
& s. [; U; V* c! S/ q$ l* D; Z6 N2 Z' _1 o: n t1 n
GuiLite具有很强的跨平台特性:- 支持的操作系统:iOS/macOS/WatchOS,Android,Linux(ARM/x86-64),Windows(包含VR),RTOS… 甚至无操作系统的单片机
- 支持的开发语言:C/C++, Swift, Java, Javascript, C#, Golang…
- 支持的第3方库:Qt, MFC, Winforms, CoCoa…9 M: q- w, k1 ^8 l& E8 E
- . P; r U6 h8 ?. t. o
. n( ]; E8 f. L7 ?" i' o
GuiLite 提供一系列辅助开发工具:- 完美的“云” + “物联网”解决方案:让你轻松驾驭全球IoT业务
- 支持多语言,采用 UTF-8 编码;
- 资源制作工具为你定制自己的字体/图片资源
- 所见即所得的GUI布局工具
- 编译活跃度统计,及实时分析
- 支持3D & Web
- 支持Docker,一条命令启动。" Q7 ? q/ _1 A9 w, ^- E1 b
t) T+ b6 { ]3 GuiLite移植2.1 所需硬件
# R" n/ W2 T/ O2 k9 B7 d# t0 p$ ?: i, Q7 ]) i( @* z; Q
% n6 b) W: R! e. J Y
9 O, R! F' e4 U+ S( J$ T5 u" t( v0 U2 ?
2 p" [3 J. x' `' c; P1 N, f$ `7 Q# J5 [+ |
STM32F407开发板* h: r g2 W: W" ~
9 e5 b/ a$ w* D
. f' x6 z5 \- i9 l1 G9 J' J6 K$ v
; I; L e; N9 h0 p% W4 B
( C3 d h2 P7 B8 [% m; R
' b7 x. n7 r- _" y% pOLED屏幕: d) J1 K6 x9 l! K% l/ w3 F
" B4 G4 N+ v$ r( N! @7 t
4 n' A& S2 d1 X1 L* `2.2 驱动准备
) j& n% s9 R4 h& @ 这里我使用STM32CubeMX 对开发板进行外设配置,开启STM32的硬件IIC,这里我用CubeMX开启后如下:$ t* Q( F( k& f6 H8 @* W
+ V0 k6 U. A+ q0 Y% @5 j( R( p# ~) I5 i" \3 h: n, F8 k9 @
2 _2 ^- a" d6 x5 ?
6 k$ O& j/ L0 L. m- r
. [: F5 \" C( O5 r! p) v, | 配置完成生成代码,同时将分配的堆空间增大:
* D T! X+ h, P9 {! ^3 n& ^1 k, \2 k% u' p/ O
. M8 Y7 o. r" ^; j. l6 ]; H) Q
: ?3 }6 R8 [( \3 P1 e- M7 `
. a7 P3 D5 V0 v, P' w# `
6 R }9 J' A1 ^7 w 代码生成后,我们复制正点原子的OLED驱动工程代码到Hardware硬件目录下,自己创建一个该目录。6 R0 d: U% ] i3 M& R
8 E1 E, o9 a; j5 q- r+ T Q
& o6 h: B2 h4 ^2 q* B# A; \' f
u8 C7 Y* o* k$ D# B
4 L+ S3 `- S% L D/ x6 }
* U) X0 z4 Q- e! @ 在MDK里面添加文件,然后我们进行修改,注释掉头文件里面关于端口的定义,同时添加三个类型宏定义。
' q2 e5 o/ V( y( T+ n( S1 X3 H1 r$ C/ O7 s- p
$ N o0 ^& p+ p3 O
N: O( }# P, B) L) S+ |
9 y9 C8 F! R/ P
6 S0 j/ Q3 f; O M; y 然后我们进入oled.c文件,将void OLED_WR_Byte(u8 dat,u8 cmd)和 void OLED_Init(void)函数分别替换为下面的内容:7 _$ c8 `; q" Z- M2 M
OLED_WR_Byte:
, m2 u# Y& A6 K: W, M+ Q4 }& N- void OLED_WR_Byte(u8 dat,u8 cmd)) l: p) \4 k4 o9 ~# o q7 W/ ?( ^/ o! u
- { 8 J, x U+ e6 F+ o- q4 D
- if(cmd)
6 g% E" @4 _3 Y1 f8 j: N1 | - HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100);
& G$ [ a. h* v* q - else+ w8 \& m7 h8 Z' f
- HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100);
# R& x: X9 @5 ^- ^5 V! z; G. `) G* F - }
复制代码 1 p* u5 n. [. {9 @( J
; f5 X& |* ?: j5 L3 \( R0 }& n
* G0 w8 q5 Q1 F, ] D5 j3 b
OLED_Init:) d1 f4 c1 {2 h, b% r: D9 U
- //初始化SSD1306
0 h( s3 `; M. J1 \ - void OLED_Init(void)
. m( g1 g0 F6 } - {
# l9 q) q5 e% @/ q3 h) Q6 e - OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示
" n+ ]' b# M7 | - OLED_WR_Byte(0xD5,OLED_CMD); //设置时钟分频因子,震荡频率
, G* \" H" g8 N0 f4 O0 K8 U - OLED_WR_Byte(80,OLED_CMD); //[3:0],分频因子;[7:4],震荡频率
: V4 `- q; m) H' m0 R" q - OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数$ ?0 x' i' J) a3 w8 e
- OLED_WR_Byte(0X3F,OLED_CMD); //默认0X3F(1/64) 2 T- L/ ?! h( h: a
- OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移& @" D* T1 X% E9 I) j/ u$ D
- OLED_WR_Byte(0X00,OLED_CMD); //默认为00 ^6 U& B: @1 _. H7 E8 A3 M2 S
- " L$ ~ `9 O) H
- OLED_WR_Byte(0x40,OLED_CMD); //设置显示开始行 [5:0],行数.
, H9 K& F! k5 A - ' R) o a5 N9 d8 a
- OLED_WR_Byte(0x8D,OLED_CMD); //电荷泵设置, b) z4 G7 ]# L0 ^
- OLED_WR_Byte(0x14,OLED_CMD); //bit2,开启/关闭
0 c0 Q) C1 G! Q9 U - OLED_WR_Byte(0x20,OLED_CMD); //设置内存地址模式
2 [6 p$ V! V* H% z0 M - OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;3 ], X6 D3 [% |5 |1 O2 J D6 _
- OLED_WR_Byte(0xA1,OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127;
3 w+ {* Q8 Q- H+ M2 E - OLED_WR_Byte(0xC0,OLED_CMD); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数6 J/ \* P6 m! b8 k, A9 F
- OLED_WR_Byte(0xDA,OLED_CMD); //设置COM硬件引脚配置
$ d" I I5 s8 |1 _& Q - OLED_WR_Byte(0x12,OLED_CMD); //[5:4]配置$ h" a9 K% v9 F7 n2 z0 s
- ' T, |& w( G* U& n
- OLED_WR_Byte(0x81,OLED_CMD); //对比度设置, J" S- B/ W$ R7 R
- OLED_WR_Byte(0xEF,OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮)& R. M6 h$ d9 _/ _( x, F
- OLED_WR_Byte(0xD9,OLED_CMD); //设置预充电周期: ^& m5 N8 J6 }# }/ o- s, _4 J
- OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;9 H% D3 }/ w0 K p! n
- OLED_WR_Byte(0xDB,OLED_CMD); //设置VCOMH 电压倍率
( e3 T$ k& r% _) n2 e$ E& d - OLED_WR_Byte(0x30,OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
! g0 H0 j+ u x8 S
/ \6 v! H p7 w) B) O; H8 m0 J- OLED_WR_Byte(0xA4,OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
4 m" o: c/ N a7 J) M( ^ - OLED_WR_Byte(0xA6,OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示 . V( \% e$ g# B8 v
- OLED_WR_Byte(0xAF,OLED_CMD); //开启显示 % U8 S2 P- ^9 y( [$ u
- OLED_Clear();
; D6 Z# ^ L+ w @; o( l - }
复制代码
! J. ~/ V, f z( H9 C( d4 ~3 A# f
9 H- ]) D# i P* o# b然后在main.c文件如下位置添加oled测试代码,记得添加头文件和头文件路径。
" e# ^* |- B# A8 b6 q, E
7 A, i* s: S5 B, P8 S w }# E
0 E( W; r: j; K7 `) d' _# F
8 R$ L4 S- Y% D+ |! I! @9 t" I u, _
; H+ s0 c' X2 N+ V. v! p$ _7 | o% u+ `6 c' U
下载程序,观看现象:9 |$ U) X' }! {2 ~9 U8 w# j
, `" A2 v& c8 c' d5 a9 m1 p# C& G9 l& k7 Q9 ]
, N* G) U# ^2 J# ?0 D; x' c
7 v# H5 e4 I+ r8 g' O% B0 ^( n+ g# Q w
此 OLED 驱动的准备已经完成,下一步就是移植 GuiLite。
. J/ t6 J5 H$ D& t4 v! M, x6 G# V o d* N6 i% H' f- ?6 X) C& {( q
3 T% ^) I) P9 H
2.3 例程移植$ z/ a3 q {4 Z& v% F d
首先,我们上GuiLite的例程展示官网:GuiLiteDemo,选择Hello例程,将其中的 UI_Code文件夹复制到 Hardware 下:
8 f- x0 g/ z4 q' y% T" r
4 [; h2 x% K4 x4 g1 x. P
0 \2 [* m# N! T7 y! b; \8 ^
( s+ V8 Q9 j v0 O! S: I
( H8 F5 p( B* a4 R- \
4 H# g: G# Q2 m4 `: j. Y 在 MDK 工程里面导入UICode下的GuiLite.h和UIcode.cpp文件。
9 g9 t e4 _7 }6 Q6 T' d
0 F8 j; y$ C% I* {) x( W2 Q4 W# U, o+ z( P9 T1 O2 d
# M# q: O3 h6 h- o& y. b
$ R+ y4 S$ r; C; T0 e! Y) B
# d$ U0 F( i/ m) k5 |5 h$ { 我们在 main.c 文件开头添加 GuiLite 接口代码,接口代码如下:
% W# _+ f! T- ]0 ~1 {- //画点函数接口
6 [) W+ f7 _' C1 W4 V# F - void gfx_draw_pixel(int x, int y, unsigned int rgb): @+ h+ {; i4 q- e/ w/ S
- {
: Y" t/ t a8 a- K: H - OLED_DrawPoint(x,y,rgb);6 w9 d# W" F! Z# R' H+ k$ q. f
- }
: }( Z/ M2 W) g( @ - //画面函数(未使用)/ L) `' x9 V, c+ ^! H N t, f% n
- void gfx_draw_fill(int x, int y,int w, int q, unsigned int rgb) x3 r" S4 z( i7 E! H# U. H5 ?
- { ! `: T' y; U. C: x
- }2 c" Q! w8 d) b$ h8 z
- //创建一个函数指针结构体& U- r$ V% j$ n; U( T i* R
- struct EXTERNAL_GFX_OP
! n7 v$ D: m' ` B9 M - {9 z% H- O7 f9 [) G$ X: y
- void (*draw_pixel)(int x, int y, unsigned int rgb);" p1 h: f7 n" J+ e. k; z
- void (*fill_rect)(int x0, int y0, int x1, int y1, unsigned int rgb);
: Q% ^/ K$ @2 i0 ]. o+ ~8 w0 r P - } my_gfx_op;
% H! T: V( O! N3 F2 U - extern void startHelloCircle(void* phy_fb, int width, int height, int color_bytes, struct EXTERNAL_GFX_OP* gfx_op);# B. |/ U) |+ ]8 f
, L& p# V, [( i& b6 w& w- //设定延时函数接口
) u0 H, j/ e. B5 T - void delay_ms(int milli_seconds)
% d4 l2 N$ M2 t. g6 s - {
. d( J0 T1 q n* m3 K( _: p - HAL_Delay(milli_seconds);
+ `) E) \# D h, c4 G4 @/ x8 C - }
复制代码
6 P) P& U6 H# P7 {& W5 n: ^
& Z2 a) V. j$ p% b; e5 y: S. ]3 D b; w& q* x% ?) z7 `+ S
之后在main函数中添加如下代码:: j& n5 T# k3 n* d( `7 L$ Q
- //传递函数指针
. w v- ^: c8 d7 Q0 X - my_gfx_op.draw_pixel = gfx_draw_pixel;. T2 L/ V2 i( I! k. M2 c+ G0 r
- my_gfx_op.fill_rect = NULL;//gfx_fill_rect;4 z; c: N( J. x* D( J
- //启动画圆
* f! @0 C+ E$ U: ]: r3 T - startHelloCircle(NULL, 128, 64, 1, &my_gfx_op);
复制代码
- E/ _1 n3 ~! g1 r/ }1 Z2 f
9 [, X: z" {1 O4 H- D) p; W5 s2 a; M 然后我们修改UIcode.cpp文件中的代码,添加OLED头文件,以及在UI执行函数界面处添加OLED刷新函数。
8 U2 a! L O( f& P" m" a2 n
! o v; K2 Y3 B( I- p- W9 A2 E3 u" U- }1 K. `% c/ z S* Z7 v
( ?' M- b3 K! n E/ H9 W
0 F5 g5 f$ X$ i( z2 g4 r# H" K0 A- `" J' m# o) q, i5 z
之后在UIcode的第8行修改3D圆的参数,因为OLED大小128x64 ,所以我的配置如下:0 L! c1 k& P5 q7 q4 k
7 {! l# i9 E* `6 J
# @# j3 t% s, f8 r" O" Y# x4 h# \
7 K! M# G8 W# q6 b. N: w
: n) e9 X6 B; W% w/ f
+ W- P5 P8 b4 p, d& u1 Y; M 配置完成后,我们关闭Use MicroLIB选项,编译代码:" Y/ u: K# m4 \
$ T* t3 m: a+ G
2 c* f/ K3 K) z5 Q* [2 Q" W
9 F( V& w" `- l: O# v/ b
( V& P: X0 D: H) L4 u2 W% u3 q
. x8 N: C8 x" |" D+ _' L) n 编译成功,下载代码。# ?$ } \& R7 v' B- y: B* k
/ v& O' k( y# K" E2 }1 k2 g
( S1 I$ k% J/ |5 D# e3 Y# v) a
% w# E' v# L2 B+ d. N
- I/ A$ V* x) h3 v ?, t! j% v, R5 O' J/ \( e
下载完成后程序复位,可以在OLED上看到Demo的示例动画。
% T7 T& G9 ?4 U" _& o0 F. H5 l0 s% M
9 l4 d' W% e r; X, ~2 A# R/ y
# q9 ~5 [) d$ g2 T- m6 M" n
7 y& p7 D# Z. V8 \8 A+ h转载自:[url=]芯片之家[/url]7 K1 `; [8 B5 ]- Y$ B: L+ X
" r# M9 d. R8 c) T2 T
. A6 C$ K2 p5 u" w7 O
|