|
1 Gui移植结果 一些演示效果:
|
|
|
|
|
|
: w; S# b) l! c2 i0 a% {6 M% W0 u
|
| 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
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
) 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
- e8 Y0 H, G+ e- G" v9 `: O# ?
: k, w6 R. f( n/ ]7 |2 R5 L( V: e5 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
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
" 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
+ 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+ b7 ^) [! L2 J8 N. M! b% P7 v
. `, 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 ^- void OLED_WR_Byte(u8 dat,u8 cmd)2 ~0 Y, Q, }( C/ D6 _$ x+ B
- { * D! t1 Y8 o) }$ y
- if(cmd)
! c' K: L9 n O. f7 W - HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100);% R. h: j/ \8 t3 z: f* `
- else
% A6 h! x3 l, \; i7 } - HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100); * d! {( X" J" |- Z1 p
- }
复制代码
& 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
- //初始化SSD1306 ( O. I( X' f) v9 |
- void OLED_Init(void)
& a: \! X3 G( H - { 8 u" t6 U8 ~4 X3 S4 C0 C
- OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示
! \, I/ j/ M+ E, N# J2 i - OLED_WR_Byte(0xD5,OLED_CMD); //设置时钟分频因子,震荡频率
Z/ E+ K6 K- j9 M8 k1 r, I - OLED_WR_Byte(80,OLED_CMD); //[3:0],分频因子;[7:4],震荡频率% [+ b z1 T' X; { ?
- OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数" U( u9 [0 R3 J: C G; T8 k( B
- OLED_WR_Byte(0X3F,OLED_CMD); //默认0X3F(1/64) - v% g$ P+ D( q3 V1 X
- OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移
7 J9 T. |) ^$ [, F- s2 W$ g - OLED_WR_Byte(0X00,OLED_CMD); //默认为0* H. F; k9 I3 p+ Z7 j
+ f$ p; }( q3 ^/ j3 o: W8 V- t- OLED_WR_Byte(0x40,OLED_CMD); //设置显示开始行 [5:0],行数.
$ Q S O2 l% U - 0 r# w, }, v, V" x, ]3 |3 \
- OLED_WR_Byte(0x8D,OLED_CMD); //电荷泵设置
* j$ ~' d }9 f0 A* d& b - OLED_WR_Byte(0x14,OLED_CMD); //bit2,开启/关闭
+ j& v3 r4 }# n4 }: G( C( @ - OLED_WR_Byte(0x20,OLED_CMD); //设置内存地址模式' [6 @6 Z: ^. m( f
- OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;( Q6 u+ [9 R4 m6 [* t9 t
- OLED_WR_Byte(0xA1,OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127;
4 Y4 Q# d7 K6 d' ^, x ]# `/ ~ - OLED_WR_Byte(0xC0,OLED_CMD); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数5 i+ O2 O5 ^0 K5 ?
- OLED_WR_Byte(0xDA,OLED_CMD); //设置COM硬件引脚配置
l# w B- \# X1 k2 { - OLED_WR_Byte(0x12,OLED_CMD); //[5:4]配置
( d9 k5 K1 |4 A% D9 a - - ~2 H! `. Y/ H9 K$ g
- OLED_WR_Byte(0x81,OLED_CMD); //对比度设置
2 n) J9 S0 p) h+ t( Q; r* r. s& D - OLED_WR_Byte(0xEF,OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮)
+ ?3 \' |& y- y* X# M4 j5 y - OLED_WR_Byte(0xD9,OLED_CMD); //设置预充电周期
6 e U0 s D4 k7 n* f2 `7 R- b - OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;
. E+ I9 s* @3 {4 r* y - OLED_WR_Byte(0xDB,OLED_CMD); //设置VCOMH 电压倍率
5 a* `& L- Y1 d0 m- C5 r - 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 - & v1 F$ g' Q, T+ X% N0 f& e6 d
- OLED_WR_Byte(0xA4,OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)' Y; x* M& A! e1 `4 N* g
- OLED_WR_Byte(0xA6,OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示
2 H: l- ?; u3 R* h - OLED_WR_Byte(0xAF,OLED_CMD); //开启显示 ; x' \6 h& E) S8 T8 Y) B9 h
- OLED_Clear();% m4 C4 t0 l7 }9 w6 ?" \
- }
复制代码
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
) 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
: }% 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
& 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! }" @
9 S/ D* W$ c+ G) ]$ v, Z8 T9 M
7 i# ^, i( f! d; g2 m' G( f, @* p0 F5 M
我们在 main.c 文件开头添加 GuiLite 接口代码,接口代码如下:
4 \3 U# w+ Z- c2 @: @( m- //画点函数接口
. _; \( W/ _+ j0 W0 B N/ x& E - void gfx_draw_pixel(int x, int y, unsigned int rgb)
$ R7 e; t8 Q& g4 z' ]1 h - {4 ?1 ^" i. S5 {/ K) \1 O
- OLED_DrawPoint(x,y,rgb);( y6 x4 ?, f3 T
- }
/ r5 Z8 v7 r$ {1 W: }5 @+ r) Q - //画面函数(未使用)
, }. g( j3 a7 ^: I - void gfx_draw_fill(int x, int y,int w, int q, unsigned int rgb)/ _, g% z& g3 A" S: {# i( A
- { 8 o/ Y! k: f R* V* k) m3 G, Y, v
- }0 |- L7 _9 L0 C1 {. h6 k0 c
- //创建一个函数指针结构体8 r' p% W7 h6 o0 h1 f3 K7 ]" q% p
- struct EXTERNAL_GFX_OP
# \' z+ e5 i: y5 {4 U - {3 m4 }% c# ?0 [
- void (*draw_pixel)(int x, int y, unsigned int rgb);# C$ f5 ^& b% P3 s9 J
- void (*fill_rect)(int x0, int y0, int x1, int y1, unsigned int rgb);2 x& V1 Y8 [- H4 k' _* L* Z- e' d
- } my_gfx_op;
, c$ C. x' N' y# H, P: y8 Y - 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
0 e( R1 O8 U q: g }- //设定延时函数接口
9 y+ m- V, G1 p8 _( X0 S+ T$ u# h - void delay_ms(int milli_seconds)
, W* q4 j, C3 }9 U - {
" _2 N3 J2 g8 G9 s" ]4 ]4 M - HAL_Delay(milli_seconds);
1 _, p" q3 \' v: [ - }
复制代码 ) 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- //传递函数指针 k3 p6 s, g, p3 f* A9 {4 V
- my_gfx_op.draw_pixel = gfx_draw_pixel;% l9 G4 Q5 N8 W3 m3 w2 P/ P8 W$ ]
- my_gfx_op.fill_rect = NULL;//gfx_fill_rect;4 l7 q3 t: J- b* [
- //启动画圆
$ j5 _! O5 ]. m& r. A! B3 n1 _ - 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
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
& 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
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( [
! 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; ?
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' _& ] |