|
1 Gui移植结果 一些演示效果:
|
|
|
|
|
| : K; u/ ]% |4 H6 t% G# L& \ P
|
|
5 Z v V2 F5 k* r) g3 z1 @. e2 GuiLite介绍
! s( ~; k7 c# T% U- @# ?! v GuiLite是一个开源的图形用户界面框架,只依赖于一个单一的头文件库(GuiLite.h),不需要很复杂的文件管理,代码量平易近人。) F) B* m! s5 B. Z% W1 f1 P: G
GuiLite由4千行C++代码编写,单片机上也能流畅运行,其最低的硬件运行要求如下:
; E, B2 |2 x$ F& |/ N7 D: q! X- }+ R% D+ k T
0 t' L3 @ C7 U& U6 {' ]. l9 H
; K& ]! N6 W5 J( g e
% }9 s2 \* ]( S9 [GuiLite具有很强的跨平台特性:- 支持的操作系统:iOS/macOS/WatchOS,Android,Linux(ARM/x86-64),Windows(包含VR),RTOS… 甚至无操作系统的单片机
- 支持的开发语言:C/C++, Swift, Java, Javascript, C#, Golang…
- 支持的第3方库:Qt, MFC, Winforms, CoCoa…& [( H1 T. t# V" i
: v4 M/ p, x& c9 T$ f7 ~, U2 {0 K Z+ `9 e3 l
GuiLite 提供一系列辅助开发工具:- 完美的“云” + “物联网”解决方案:让你轻松驾驭全球IoT业务
- 支持多语言,采用 UTF-8 编码;
- 资源制作工具为你定制自己的字体/图片资源
- 所见即所得的GUI布局工具
- 编译活跃度统计,及实时分析
- 支持3D & Web
- 支持Docker,一条命令启动。2 x2 H% W E& u( B
D0 j; k% V6 k+ R3 GuiLite移植2.1 所需硬件5 Y/ q4 h* @# J( _3 _8 _* q
2 G4 L" ?, K* Q; {# J% U
; @0 K% g8 s$ Q& ], g
4 E* s) d# {# ^% {
1 ~7 b$ C* N2 t- r4 W0 n3 N
9 O+ b, h7 Z0 A8 C7 d% KSTM32F407开发板5 n3 n$ j* Q6 G% g. a
g) m" J" d" l0 b/ r0 w. V9 u/ G& Y
& _( N5 k1 q9 k7 b3 l8 b1 @
: b" g1 z) A8 C0 O
$ r- n! }1 c9 V3 m0 Z; ?OLED屏幕4 ]" l) Z! `+ ?
, M' f% M* ~6 r# | c. T Z; v) q6 b: J5 E0 y% _, r" ^' W) b
2.2 驱动准备6 B7 M: x) Q2 G
这里我使用STM32CubeMX 对开发板进行外设配置,开启STM32的硬件IIC,这里我用CubeMX开启后如下:' D3 u _9 E E3 _' Y2 f; c
+ Y% b. T/ Q, I6 G' }1 M
" n1 `+ R8 z! A
0 l7 |) Z( t2 U
# u b5 D6 s" i$ k: {! Z
$ p6 j# J8 c" ]% D& k7 ~ 配置完成生成代码,同时将分配的堆空间增大:" D( x5 {# V# U- l& H
) j, A: x: j, y6 N/ `
, x1 S/ \& E8 p) E# [4 r
" a4 T; e E& A; `/ u- s5 d3 @
( X* S' N! ?3 N4 o% g. j
8 Z% g0 ?* y" o8 l' j 代码生成后,我们复制正点原子的OLED驱动工程代码到Hardware硬件目录下,自己创建一个该目录。
2 y2 P9 `0 M0 Q. @( _9 L1 N1 i7 s$ O2 k) r7 }
) Y* V" k& z& \
9 _5 i- ]/ g8 Y% |
) b+ I B- V( I8 [4 e
7 |5 K% h3 R$ X2 y 在MDK里面添加文件,然后我们进行修改,注释掉头文件里面关于端口的定义,同时添加三个类型宏定义。
, L! C: k& U2 x$ ~! J6 O* l$ Q8 t% [6 M$ t
% g* X; m; s7 `9 T! O, b0 v7 |
* w. @ j' B$ E3 L
& j; _' ]( w7 _2 V$ ?! B/ F7 F& T" p8 Q# m' f' a
然后我们进入oled.c文件,将void OLED_WR_Byte(u8 dat,u8 cmd)和 void OLED_Init(void)函数分别替换为下面的内容:4 B0 V/ m0 b7 V. _$ O
OLED_WR_Byte:' K9 M# j6 r$ \: z7 T
- void OLED_WR_Byte(u8 dat,u8 cmd)
& J) _; J9 g, f; u0 f( M1 t - {
$ e) F# b5 I1 O" A' U) K1 X - if(cmd)& A$ b" V S4 N, L
- HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100);0 F. Y! v* }# ^& }: U$ ~6 A& Z
- else3 H6 Z8 o+ k4 Z, m7 i
- HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100); & L8 \ ^' f, E. I4 o9 |
- }
复制代码
p! T. M8 y9 ?: F# p
1 P$ B; h. p& ?4 G: l( @3 z/ p9 T. }/ Y' G/ A" \2 F7 [
OLED_Init:
& w/ v; a o# x+ z) h" Z- //初始化SSD1306 , {4 H6 r# L3 k
- void OLED_Init(void)
5 |' W; Z& K" m7 y# ^ k' K - {
5 r0 M# D2 W4 I7 O8 V1 E7 S- i - OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示. }1 D$ t; \- q7 b4 m
- OLED_WR_Byte(0xD5,OLED_CMD); //设置时钟分频因子,震荡频率9 ~; c9 q" ?% {. p0 Z8 a w6 a
- OLED_WR_Byte(80,OLED_CMD); //[3:0],分频因子;[7:4],震荡频率+ u( s3 ]9 A5 a" ^! D
- OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数
4 {0 K6 x* |# ^1 y2 V2 G - OLED_WR_Byte(0X3F,OLED_CMD); //默认0X3F(1/64) " B2 e6 L, ?/ C6 N
- OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移4 q7 M6 `8 h* L- \$ K" ~) A S
- OLED_WR_Byte(0X00,OLED_CMD); //默认为0' R5 Y+ T9 c7 ]
- ! \/ ]5 C+ m# ]- E5 i0 w
- OLED_WR_Byte(0x40,OLED_CMD); //设置显示开始行 [5:0],行数.8 A& p X/ C. Z ]0 o
$ r' d5 N9 V2 Z- l, q2 t$ C- OLED_WR_Byte(0x8D,OLED_CMD); //电荷泵设置1 n8 w- }- |0 e4 P
- OLED_WR_Byte(0x14,OLED_CMD); //bit2,开启/关闭
2 W& k$ D% `; ] - OLED_WR_Byte(0x20,OLED_CMD); //设置内存地址模式
- q- B; P! t& o2 a6 N8 p1 S - OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;
- i* P5 T. Z! Z3 v - OLED_WR_Byte(0xA1,OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127;
2 n$ i8 \+ G& _+ d) U - OLED_WR_Byte(0xC0,OLED_CMD); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数
2 j7 C7 p5 m5 l3 ?! k. d- {6 ^ - OLED_WR_Byte(0xDA,OLED_CMD); //设置COM硬件引脚配置7 u1 E, m8 E0 ~
- OLED_WR_Byte(0x12,OLED_CMD); //[5:4]配置
3 Q S5 M9 [& n" b( l
+ e, y# B3 S4 R- OLED_WR_Byte(0x81,OLED_CMD); //对比度设置4 }! W% B4 H/ n7 h! s
- OLED_WR_Byte(0xEF,OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮)
2 }! T/ b6 t, v' N& m4 j/ t: F& ? - OLED_WR_Byte(0xD9,OLED_CMD); //设置预充电周期
$ X4 `5 `) h% C$ x9 L5 p, S - OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;
9 m9 a3 `) X, f% d) R5 Q" n - OLED_WR_Byte(0xDB,OLED_CMD); //设置VCOMH 电压倍率
1 r }/ j* c8 O$ I" w - OLED_WR_Byte(0x30,OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
# U" t( Q) |. s1 @& O - % J4 n9 C8 a) j- n; G" X6 W6 `
- OLED_WR_Byte(0xA4,OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)- R8 h* \8 s( I [7 X* }2 u
- OLED_WR_Byte(0xA6,OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示
y/ S5 U0 d2 q9 u, X& M - OLED_WR_Byte(0xAF,OLED_CMD); //开启显示
& y' Q* b3 N' \5 T7 P- _+ L/ \( w - OLED_Clear();
5 R! a/ |6 L3 U2 `4 u- m& { Z' \ - }
复制代码
3 m- B7 }$ I% U" `
7 N/ w" X7 T% A9 \* q! B然后在main.c文件如下位置添加oled测试代码,记得添加头文件和头文件路径。( e4 d8 T( y7 L' R3 s
' g7 f' O# u Y8 V
8 I. ?8 _& U- `& F' y# X5 d
' j% W5 z- W6 n& J) v" h1 }. d
; i6 ~+ A$ F+ R* q2 j! z; E4 t6 c* x3 z& C& j9 _& }8 i, I$ s
下载程序,观看现象:
* ]/ ^( q; G* V4 B& x2 P6 Y* s2 Z* u
8 ^7 G: n0 T X- e/ |
* ^7 y9 q$ T+ |% m) S; z
* b1 s. p2 t5 k5 v6 B7 A! ~2 {% V1 w S+ Z' I8 n
此 OLED 驱动的准备已经完成,下一步就是移植 GuiLite。7 ]8 x0 k6 Z# j" z8 o1 d" F* K
: W. z' l( a' V, v/ q
7 O( \8 ^) X Q n3 n8 b7 a2.3 例程移植! f. Y" N- e; |$ ]: D
首先,我们上GuiLite的例程展示官网:GuiLiteDemo,选择Hello例程,将其中的 UI_Code文件夹复制到 Hardware 下:5 ^( G# f, M' O3 ?7 }. h8 y
* o: F! R. U) \: z: ~
# ]" w( B% ?* a8 _8 v3 ]4 [# v" D
" x# K+ [& R8 J6 o' L6 y% Y* e* ?" I" ?. [( _
; `6 I! H! f) J/ O/ H 在 MDK 工程里面导入UICode下的GuiLite.h和UIcode.cpp文件。! t. s1 d0 ?7 y. ~ G0 T
7 }% o% M$ \" n: j: p; M+ J
5 U% K2 t# e8 R. D i, u- z) P
- i! b+ d- x0 [9 X
" a2 z6 v9 u8 o; {
6 f/ ^$ J+ D9 A7 w9 ^$ u
我们在 main.c 文件开头添加 GuiLite 接口代码,接口代码如下:
w4 ]0 C- B5 v) A1 e$ ?. k0 F6 q6 h5 B- //画点函数接口
. I- l+ y( {, O. U# l - void gfx_draw_pixel(int x, int y, unsigned int rgb): z& J& r* [& v) ^ }' X
- {; S0 F% s1 Z$ n6 H
- OLED_DrawPoint(x,y,rgb);
) E. ~" x" j, ^; x) j( c, n U! F - }
+ ?- ]5 b3 [+ O3 i( D/ V4 f - //画面函数(未使用)2 i7 O) M! l" n' j# I& e
- void gfx_draw_fill(int x, int y,int w, int q, unsigned int rgb)
- b# H* X ^$ e2 B' z$ K - {
) ?+ X; T) G4 r! `2 h! _8 l - }: C# O$ V x; a8 Q
- //创建一个函数指针结构体, l \% I% |3 V
- struct EXTERNAL_GFX_OP. F( W' u9 [2 |2 n5 v$ ?
- {
/ _& ^$ o! S/ P5 \ - void (*draw_pixel)(int x, int y, unsigned int rgb);
4 {3 i, w( e# Q4 B. A$ \. z4 ~ - void (*fill_rect)(int x0, int y0, int x1, int y1, unsigned int rgb);
2 `2 ~2 C* L. ^+ m2 G - } my_gfx_op;6 s4 k. |# H' b5 U
- extern void startHelloCircle(void* phy_fb, int width, int height, int color_bytes, struct EXTERNAL_GFX_OP* gfx_op);
8 i' j5 y' w: w) }6 G- t$ o. n - ) t& O& q$ w) L6 ]
- //设定延时函数接口; t3 x7 @- U" p
- void delay_ms(int milli_seconds)
8 K, B- t0 }# M3 H! _1 U+ {, w0 n - {( A- t; }2 R) y: W; J
- HAL_Delay(milli_seconds);8 c4 F j. K( A0 b, h
- }
复制代码
) w# u2 k. _8 ?$ h5 }$ x
0 H L( w" @5 s; S9 a* \# O5 p8 L& x0 I: @, q4 p5 x* ^% U0 Z" W, x
之后在main函数中添加如下代码:
; l4 f: Z6 X2 x- //传递函数指针. L0 @; z W9 g$ ]; O. f7 f. u
- my_gfx_op.draw_pixel = gfx_draw_pixel;
& y! n/ [# V; V1 F0 X& X - my_gfx_op.fill_rect = NULL;//gfx_fill_rect;
& ~% b; w# Y3 X - //启动画圆
7 d2 P! [! A' m6 h! w4 d+ b - startHelloCircle(NULL, 128, 64, 1, &my_gfx_op);
复制代码
% f* @4 V( n* k9 [
; e! q/ @5 y0 H: @1 }7 N# q 然后我们修改UIcode.cpp文件中的代码,添加OLED头文件,以及在UI执行函数界面处添加OLED刷新函数。% _9 |+ G* K/ L1 {7 e. j2 ]7 m
- x" T5 E5 e- ?6 f1 O
9 B7 n+ W/ K- c6 o0 f( u. ?
+ ^4 A( ?1 O" y6 |! P" K) p% v' E$ @& Q0 [# ]" X
0 T1 b6 v5 v' m* \0 B5 I
之后在UIcode的第8行修改3D圆的参数,因为OLED大小128x64 ,所以我的配置如下:9 n$ y& a3 W1 U& q, V, E! g& k! E
3 [8 ~/ h, v5 g! [
2 @ }7 U R% g; q' ]
" a- E8 V. W& e M) ?
: D) P8 l& h& m, @" U! }( @3 D- V- L3 A3 d9 A ~
配置完成后,我们关闭Use MicroLIB选项,编译代码:! j4 v/ L% {' S; L N9 R2 f# ~
. j+ v7 V- Z* ^* L
3 k8 y' {0 a8 K" I; h
1 K5 j* p8 { B3 O' k5 t9 f* d5 o$ T
3 @. E) X7 e! s0 E/ Q1 j 编译成功,下载代码。
7 e7 K7 i; P$ q1 S$ c5 k6 |1 z* C& N1 r c" S, b
|8 ` m5 c3 N
: u5 T: h+ \. T" h5 D% t
) w. `% J" X0 h3 ~2 B
# q& l# e) x$ W- U
下载完成后程序复位,可以在OLED上看到Demo的示例动画。$ F7 ?! T4 I! M5 C
; ]. r( E2 x( n9 x& y
" j* P; p3 l, G+ S) ]- w# I6 x
" x( [. w9 b, S, n4 U
% W; z. u$ X* U* |' O+ \% l( }
转载自:[url=]芯片之家[/url]2 V$ @2 u1 M4 a" B i: V
6 y: V: O. A& s1 U* }+ ]& A+ Y6 o; s k5 R; S" f; i @- X
|