|
1 Gui移植结果 一些演示效果:
. k( X1 t- _) u/ F0 w" G
& n6 G6 E/ [2 o2 [: j
2 GuiLite介绍 GuiLite是一个开源的图形用户界面框架,只依赖于一个单一的头文件库(GuiLite.h),不需要很复杂的文件管理,代码量平易近人。 GuiLite由4千行C++代码编写,单片机上也能流畅运行,其最低的硬件运行要求如下:* {: h5 J$ t6 e
, `5 p% a E+ t' ]
3 s, Q" h0 i0 l* ]. K+ w0 j# a GuiLite具有很强的跨平台特性:- 支持的操作系统:iOS/macOS/WatchOS,Android,Linux(ARM/x86-64),Windows(包含VR),RTOS… 甚至无操作系统的单片机
- 支持的开发语言:C/C++, Swift, Java, Javascript, C#, Golang…
- 支持的第3方库:Qt, MFC, Winforms, CoCoa…: N s# F7 I2 y" Z
GuiLite 提供一系列辅助开发工具: - 完美的“云” + “物联网”解决方案:让你轻松驾驭全球IoT业务
- 支持多语言,采用 UTF-8 编码;
- 资源制作工具为你定制自己的字体/图片资源
- 所见即所得的GUI布局工具
- 编译活跃度统计,及实时分析
- 支持3D & Web
- 支持Docker,一条命令启动( t6 S0 ]: v) O- t/ j, S& A6 c$ ~
, w/ v9 {$ {) E$ l' P
3 GuiLite移植
7 D" S, q3 h7 j1 |# R" n4 M. ? M3.1 所需硬件STM32F407开发板 ; w1 O m, J) C( w
OLED屏幕 6 q! C# R; d' N1 W% O5 ?! E" j
2.2 驱动准备
- |3 I, I4 z% S) S, o5 s 这里我使用STM32CubeMX 对开发板进行外设配置,开启STM32的硬件IIC,这里我用CubeMX开启后如下:
6 W; u: _" t( z$ p- a6 C
" P2 w0 D: ^5 H! \7 R0 |! G 7 m4 K, F3 X4 G0 Z" G
: q/ d9 L0 v' } }8 L/ P; L# t) l 配置完成生成代码,同时将分配的堆空间增大:
" n5 G( H) o( P% g- O+ E* j7 v$ J% i/ S2 f( P- A2 q
' g: a/ Q/ S3 f' {6 h6 Z! P: _
代码生成后,我们复制正点原子的OLED驱动工程代码到Hardware硬件目录下,自己创建一个该目录。
+ c# d3 y9 R# ^; \% [ u
) K) }* h8 s: l% b 在MDK里面添加文件,然后我们进行修改,注释掉头文件里面关于端口的定义,同时添加三个类型宏定义。
! ^. b m; N2 Y/ O8 f/ g, u( T$ P' q* `- m! o4 Q5 d/ n: l4 f/ _( R
* N; L# B! F5 X0 K1 _' T$ e: i; y) W* M6 Q* F, n' a$ ~
: {0 e6 n# b5 N 然后我们进入oled.c文件,将void OLED_WR_Byte(u8 dat,u8 cmd)和 void OLED_Init(void)函数分别替换为下面的内容: OLED_WR_Byte:
0 f/ f/ p* j( N8 @- void OLED_WR_Byte(u8 dat,u8 cmd)0 `% R0 l% ]1 K
- {
9 j, A4 h: V4 I+ A( I* E - if(cmd)! @ }* t8 Z. T! y& u; `$ Y o
- HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100);
! R& a: i" Y, K7 W - else7 x3 a7 l# V/ }6 m1 b' G
- HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&dat,1,0x100); ; `4 Q' Y( r" ^
- }
复制代码 0 p# R: D0 x: [! d o+ u s& n8 _9 P
- o# b; t/ ?6 _$ r
OLED_Init:
) M4 [3 X5 V& R5 w% J% G, H! h- //初始化SSD1306 8 n+ A4 I0 ~; E) Q* ]" `3 S6 M Q x
- void OLED_Init(void)8 N" ^9 h/ K& X7 W. V
- { : d1 Q% y; @0 k" f4 r8 `0 k
- OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示
( M n$ }8 \- ` - OLED_WR_Byte(0xD5,OLED_CMD); //设置时钟分频因子,震荡频率
" r! P# n( B7 _! v7 _ - OLED_WR_Byte(80,OLED_CMD); //[3:0],分频因子;[7:4],震荡频率' u6 O, Q( R, f- r6 `
- OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数
" L' V% N6 o+ b5 d - OLED_WR_Byte(0X3F,OLED_CMD); //默认0X3F(1/64)
6 v! \, {! s/ J3 ~7 y' P& a5 g - OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移
, k! P7 X; Q+ M, E - OLED_WR_Byte(0X00,OLED_CMD); //默认为0$ K2 ]9 L+ k3 V3 Z6 B. F
- 1 ~$ ~ S# s* s* w/ p
- OLED_WR_Byte(0x40,OLED_CMD); //设置显示开始行 [5:0],行数.
# U; p: L( B( @# r* v8 s+ ^
& l& ?# _; w0 Y& @- OLED_WR_Byte(0x8D,OLED_CMD); //电荷泵设置
?" T& b7 [- @6 f; Z - OLED_WR_Byte(0x14,OLED_CMD); //bit2,开启/关闭$ H. M/ y) N3 i" z) s% w
- OLED_WR_Byte(0x20,OLED_CMD); //设置内存地址模式* D1 n" W: w: g5 L1 w# T z/ J
- OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;
6 z2 R0 x. {" ]# z; t - OLED_WR_Byte(0xA1,OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127;
& [, {5 W8 K' p1 {, v& y+ y" e - OLED_WR_Byte(0xC0,OLED_CMD); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数# T1 y( x* k6 A& r6 n4 j
- OLED_WR_Byte(0xDA,OLED_CMD); //设置COM硬件引脚配置
9 B4 q5 C( e/ R" y0 j3 t) }9 e - OLED_WR_Byte(0x12,OLED_CMD); //[5:4]配置6 p$ `% t) E/ x
- 3 g5 d9 O4 S' i6 U$ }* f
- OLED_WR_Byte(0x81,OLED_CMD); //对比度设置( v8 _3 i1 z7 h' ^+ R9 d
- OLED_WR_Byte(0xEF,OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮)8 c& z8 D! E0 ]9 C2 r# z$ j/ |
- OLED_WR_Byte(0xD9,OLED_CMD); //设置预充电周期' g% C9 p& v1 [/ g3 _7 V" i: s8 ~
- OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;
$ @! i- t2 o+ s8 W! ?8 M - OLED_WR_Byte(0xDB,OLED_CMD); //设置VCOMH 电压倍率
* y5 `, d' q. L5 r# p: p% K7 Z8 c - OLED_WR_Byte(0x30,OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;+ v5 z: f$ u" ?- K3 K0 m
5 n7 i" o/ y4 G( U- OLED_WR_Byte(0xA4,OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏) H8 A5 M0 l0 j; E! }
- OLED_WR_Byte(0xA6,OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示
3 G$ y7 g7 f) g& |$ d5 b8 F+ m; K( a - OLED_WR_Byte(0xAF,OLED_CMD); //开启显示 / y2 w) R- O+ k3 V: p9 V
- OLED_Clear();
$ K7 Z3 v) G \) _ - }
复制代码
/ g0 D1 m: Q$ L( s% U) _5 x. Y4 _然后在main.c文件如下位置添加oled测试代码,记得添加头文件和头文件路径。
y+ v3 R% H. B I0 @" s9 p u" Q6 |! Y
, w+ Q- a" h5 h4 ]" p b6 b1 k1 w/ I
: o& i& W7 i3 l( s4 G9 |( q* c t3 n 下载程序,观看现象:
2 V7 l/ W2 |$ a6 p* ]4 z ^) Y6 p
5 A2 o+ a/ V/ P4 P2 o
# L( w/ Q0 s" I5 h! w 此 OLED 驱动的准备已经完成,下一步就是移植 GuiLite。
# p9 b. s$ f2 B. u
2.3 例程移植 首先,我们上GuiLite的例程展示官网:GuiLiteDemo,选择Hello例程,将其中的 UI_Code文件夹复制到 Hardware 下: + M; _* b3 j5 z: M1 M6 M8 m
+ [# Q1 D2 U& H
在 MDK 工程里面导入UICode下的GuiLite.h和UIcode.cpp文件。 ( A6 p3 K) M' P4 v# Z8 E+ J
6 q0 Q; ~8 X& C* Z, A) }
我们在 main.c 文件开头添加 GuiLite 接口代码,接口代码如下: - //画点函数接口
, a' n- ?( W, h& _( f# W - void gfx_draw_pixel(int x, int y, unsigned int rgb)/ Z! S$ K) t: ^& P+ H+ S
- {* j; \/ x$ f K$ ^* V
- OLED_DrawPoint(x,y,rgb);, ^, f: k* O+ ]- p+ X
- }& j: x% ^0 U1 l
- //画面函数(未使用)
- {# l/ ?/ i6 F, x - void gfx_draw_fill(int x, int y,int w, int q, unsigned int rgb)
5 u+ p) `. ]7 ]4 t* r$ H. R/ G% Z - { 3 W/ @4 c3 f2 P9 h
- }) w% x: W! t, Z/ `1 x
- //创建一个函数指针结构体% y3 V" a. S6 |( U6 c! k4 l
- struct EXTERNAL_GFX_OP
% B3 [2 Q/ R2 B- a6 h - {; j; u0 E2 [& r: R0 u0 f
- void (*draw_pixel)(int x, int y, unsigned int rgb);% b& z- r; p$ Z* c
- void (*fill_rect)(int x0, int y0, int x1, int y1, unsigned int rgb);" W. { K* ~! K' Y- f
- } my_gfx_op;
$ K; U" l/ o9 r3 ]! M4 \ - extern void startHelloCircle(void* phy_fb, int width, int height, int color_bytes, struct EXTERNAL_GFX_OP* gfx_op);5 ~9 c" W6 \9 M6 P7 Z7 |' p$ U2 t, A# E
- . e3 |; m3 P- g& B* v+ S
- //设定延时函数接口
/ S7 {$ s/ a) G7 V* | - void delay_ms(int milli_seconds); F; C, x3 B& E5 A6 X4 Z+ v
- {
& e% |4 K8 F: q6 M$ A" {5 D - HAL_Delay(milli_seconds);! u! G. [4 Y, B5 m4 b6 c' N4 @
- }
复制代码
$ ]3 B. ~6 K1 F }2 y8 C
之后在main函数中添加如下代码: - //传递函数指针
5 G- G0 l+ Z7 Y- [ - my_gfx_op.draw_pixel = gfx_draw_pixel;
# e V- r5 `5 A. c/ w# T) C - my_gfx_op.fill_rect = NULL;//gfx_fill_rect;
+ q; m: N& }5 A8 _1 W - //启动画圆
4 v6 @: x1 ]) X1 J5 t5 q" e C6 O - startHelloCircle(NULL, 128, 64, 1, &my_gfx_op);
复制代码7 l; e) z5 G( y+ H, Y! c
然后我们修改UIcode.cpp文件中的代码,添加OLED头文件,以及在UI执行函数界面处添加OLED刷新函数。
- ]& q/ Y3 W" P5 z
3 P0 W/ B/ i4 l2 O+ ]5 W! b
之后在UIcode的第8行修改3D圆的参数,因为OLED大小128x64 ,所以我的配置如下:
, Q/ ~. d( I9 C a6 k3 c2 N' M0 M5 w% {7 e
1 {9 l2 B& D* F, w% J+ R
配置完成后,我们关闭Use MicroLIB选项,编译代码:
+ F$ ~ q4 `( T
) v4 ^0 W/ |- }
9 ?. t2 y3 |8 q5 a2 o
. v3 e* c& |- n6 e8 ?
7 ?0 \5 _0 `2 {& B( ^
编译成功,下载代码。
: l: W; q. B( E; S5 y* k9 b/ J5 u* k6 Y: j G; c
- f5 N7 }8 X4 x
$ Q+ M$ z( `& Y) k$ H+ l3 P/ N! V# k5 i# n% ^2 e
下载完成后程序复位,可以在OLED上看到Demo的示例动画。
, \0 g2 M7 z, y. G/ m1 x* R4 n2 e# o1 W$ `) P5 ?( A. q f
' ]& Q# ^, q4 b# W% g
& K: r' b9 F" e1 m. b- |4 ~4 C9 D, m0 l; T
; H( [! ]$ B% p# Q1 b3 s转载自:STM32嵌入式开发 " o, N9 j0 y. j+ P# z% y0 ~* L
0 F7 D4 Y" o8 O& g4 e' {/ W1 U4 y: m' G# S
5 V9 \5 c6 [' }) _* T8 g1 }; f
0 n( [, b! B U1 Q! r$ O) l9 X. }% C: `4 z
' g- I; t! [: l( E
|