01. OLED概述
# c7 x+ ~% E2 g: i3 n2 |, @OLED,即有机发光二极管(Organic Light-Emitting Diode),又称为有机电激光显示(OrganicElectroluminesence Display, OELD)。OLED 由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被认为是下一代的平面显示器新兴应用技术。
9 b5 ~. t: D5 ~' e9 ?2 k6 k* w
- a9 h4 {3 X! E6 F% R$ XLCD 都需要背光,而 OLED 不需要,因为它是自发光的。这样同样的显示,OLED 效果要来得好一些。以目前的技术,OLED 的尺寸还难以大型化,但是分辨率确可以做到很高。; V( w3 L: l# R. J' H! g
* [, u# s. H- R9 S% x: i
02. OLED初始化
z+ S/ j; t3 a& M1 V/ a1 ^( k. e" Z" y; \$ d' V0 ~- {" P" C
& a) o% G) K' O+ w Q* ]8 s: w v: r8 X$ t# d5 ~1 t! ~4 H
驱动 IC 的初始化代码,我们直接使用厂家推荐的设置就可以了,只要对细节部分进行一些修改,使其满足我们自己的要求即可,其他不需要变动。
R5 Y" O& e( b/ q/ t+ d* I, i, c: ]1 D+ s
OLED 显示需要的相关设置步骤如下:
! g2 _2 {, E! t# W" X2 c- {2 T3 V, a: T9 g+ }2 f |' r& ?3 c1 ^
1 )设置 STM32F4 与 与 OLED 模块相连接的 IO 。
( D' p9 p( d F+ X: a- U; _这一步,先将我们与 OLED 模块相连的 IO 口设置为输出,具体使用哪些 IO 口,这里需要根据连接电路以及 OLED 模块所设置的通讯模式来确定。+ z" D( H7 ?& Q% W/ Z/ O- p* p$ F& j
J; O; W5 h2 D* z1 w1 t2 K
2 )初始化 OLED 模块。
% D; ?, p, m0 J( }其实这里就是上面的初始化框图的内容,通过对 OLED 相关寄存器的初始化,来启动 OLED的显示。
: t5 A* w% Y& X A- l# ^" X6 L3 a4 D0 j7 H1 z7 k2 \0 c) S
3 )通过函数将字符和数字显示到 OLED 模块上。+ Z4 S( _; E1 c0 h" B6 U; E
这里就是通过我们设计的程序,将要显示的字符送到 OLED 模块就可以了
5 |/ D4 O# ]/ s6 P2 S* b! G0 ~( P; {) {7 b0 f
通过以上三步,我们就可以使用 ALIENTEK OLED 模块来显示字符和数字了。
' q7 ]) Q$ w) U; u: v6 t/ {' U
' u) `5 t# e' R1 ^03. 硬件设计
2 k/ l. p- }7 n& K5 T3 w' y用到的硬件资源有:
: r9 `% j6 r4 {) \+ P- w7 w( Y1) 指示灯 DS00 U6 I+ l& L! v9 k; I$ z
2) OLED 模块
6 F8 M+ J/ X+ ]4 u! P6 {+ `, F+ m
) E' F0 D2 b$ r2 M, Y& j5 A硬件上,OLED 与探索者 STM32F4 开发板的 IO 口对应关系如下:
6 _* t5 p, C- U* U' y x4 f9 pOLED_CS 对应 DCMI_VSYNC,即:PB7;
( b1 u2 t$ L0 j0 [* q/ bOLED_RS 对应 DCMI_SCL,即:PD6;
* T& u, t6 `" b# S% K" ] SOLED_WR 对应 DCMI_HREF,即:PA4;
7 K: ~: N1 \. [# Q4 N& q5 uOLED_RD 对应 DCMI_SDA,即:PD7;
- {6 G7 ]( }/ p8 c; ~1 k1 c1 yOLED_RST 对应 DCMI_RESET,即:PG15;
# h# _, Q R8 I# |* lOLED_D[7:0]对应 DCMI_D[7:0],即:PE6/PE5/PB6/PC11/PC9/PC8/PC7/PC6;4 ?0 v0 Q) C( t1 d
- I. F' P; \6 F* R$ ]# ]- _
04. 程序示例
( `; _4 w: F: \4 D7 d, U) aoled.h: H+ |$ Y |' X; P% Y: ~1 H
- #ifndef __OLED_H+ D1 x; e# p7 H: S3 r
- #define __OLED_H
8 R9 u3 y$ e% ? - #include "sys.h"
5 _+ m: m1 v! X - #include "stdlib.h" - T0 D6 U: S% X
- ; V, z3 w; s3 s
- //OLED模式设置
. v. ^; K5 e6 R - //0: 4线串行模式 (模块的BS1,BS2均接GND), n5 a0 H) j" D. e9 G7 D
- //1: 并行8080模式 (模块的BS1,BS2均接VCC)/ V- i$ K- i" N5 R* i9 t8 P
- #define OLED_MODE 1
- p8 U* r# ~- }& a/ } - ! J# n5 Y! S- @: V, o# |
- //-----------------OLED端口定义----------------
: M t# m% ^7 i8 _, ?; [! Q8 T5 b* e. I - #define OLED_CS PBout(7)' z9 M8 H) g6 v. o1 p1 j% ~
- #define OLED_RST PGout(15) ! i( z0 I2 {; h( S& H
- #define OLED_RS PDout(6)
- U$ R) ]3 [. g2 i - #define OLED_WR PAout(4) r' u! G% X: V' ^) ~
- #define OLED_RD PDout(7)
' t- W% C. V: l. y W - $ f# B2 ~ c+ S3 m7 g# r
- //使用4线串行接口时使用
5 P& `! o; I9 c" J/ C5 a) g6 S" ` - #define OLED_SCLK PCout(6)
) ^9 V/ U# S; q - #define OLED_SDIN PCout(7)
- }, H# Q3 Z) B- O - ' {* {. s( Q2 j- S9 K9 [
- #define OLED_CMD 0 //写命令
" k) _5 V/ P( {& o# K0 K6 f2 r - #define OLED_DATA 1 //写数据
`1 \0 n6 W! B! f* a0 ?7 F$ l, y! m - //OLED控制用函数
7 a, a& Z2 P+ I2 q3 L- H- U9 n - void OLED_WR_Byte(u8 dat,u8 cmd);
$ Y; f! g, u2 [) M j" D! H - void OLED_Display_On(void);
9 y) ?" ?% o/ ?7 C; i7 @7 ? - void OLED_Display_Off(void);
; G) A7 l) x/ l( t1 H3 g - void OLED_Refresh_Gram(void);
% n6 G, {. d- e; T# ~ - 6 r+ T; X" R. c5 |
- void OLED_Init(void);
2 R, E% W7 b/ d- U% h/ ]" g* | - void OLED_Clear(void);, f& Y5 J. ~4 w: ?0 U
- void OLED_DrawPoint(u8 x,u8 y,u8 t);3 s& B$ i5 O9 o# ]
- void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot);
. V, Y8 L; _/ R - void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode);
5 r" G2 F5 ^, `) {, C* F - void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size);& U7 K! X- G! w9 K: O. g8 l0 o
- void OLED_ShowString(u8 x,u8 y,const u8 *p,u8 size); 1 c1 v- R0 g* P/ m9 e" S
- #endif 0 U) c; K/ S# a- S9 y$ T
复制代码
8 T* Y' d, m/ q# H2 C" coled.c j+ ] v, i3 v* o; P- S
! i7 }% t" k9 O6 @: E
- #include "oled.h"
/ N' K( H& s9 a4 `7 n" f0 k - #include "stdlib.h"
& A) q3 L& n* h& h7 d" d - #include "oledfont.h"
: k- @; Y+ _, A3 M E - #include "delay.h"0 S4 L+ M2 r" h+ y
- $ c/ a. p M% O# _& e9 T/ C
- //OLED的显存
* m, h0 l! I3 K" ?% s* ?, O7 I7 ^ - //存放格式如下.* }' v2 I6 T/ T) ~. a9 B
- //[0]0 1 2 3 ... 127 + S4 V3 j Q" j3 H5 d9 C4 @
- //[1]0 1 2 3 ... 127 " J1 t. ^ p* j: _
- //[2]0 1 2 3 ... 127
. b8 ^- Z) `- `( N0 t! A - //[3]0 1 2 3 ... 127 ( c. K7 v( ]+ Y& d6 m$ W g
- //[4]0 1 2 3 ... 127
: q, M0 n; P' O6 A - //[5]0 1 2 3 ... 127
' b# l( y, m! j- R: T l8 X: `7 k% T - //[6]0 1 2 3 ... 127
: b+ V$ ~& }) l( ^ - //[7]0 1 2 3 ... 127 6 q. `4 @% ?9 ^9 t
- u8 OLED_GRAM[128][8]; 2 Z) [3 o, s- p0 R, L% ]
- 5 c; S7 o: e& ?1 z- ?
- //更新显存到LCD
w4 |( O6 A" L' G7 a) m( v - void OLED_Refresh_Gram(void)
- u. x2 j: F& G0 ?# {8 m - {
" J% ^, [ e! i! ` R% @ - u8 i,n; 8 ]( N8 l" h7 O; `& p" W
- for(i=0;i<8;i++)
J1 N ?8 D' b2 ^7 \* n - {
k! V+ p6 @6 r* } - OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)( ^/ e. u7 d* M7 ]9 F+ e1 V
- OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址- i3 ?+ @1 o& i$ Q6 V8 Q
- OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址 # W+ ~: s6 p- u5 c- n$ A: K; J
- for(n=0;n<128;n++)OLED_WR_Byte(OLED_GRAM[n],OLED_DATA); " o, a& z: O0 g3 l0 h2 @
- } - {. r/ o. H2 Q: q8 S
- }5 H7 P# @# N8 u# u Q# C8 ^' V
- //8080并口) m( M3 a, K# _7 p; y8 y
- //通过拼凑的方法向OLED输出一个8位数据
* I: j8 c. D' H% l5 ?, |+ @ - //data:要输出的数据
6 y+ ?9 [! a2 N& V: L# s - void OLED_Data_Out(u8 data)3 W, F8 Z% e# z% f h9 P% }
- {
* E( Z7 n ]1 e; F+ ^* T7 I - u16 dat=data&0X0F;0 h6 g" @4 ~" q; v# E
- GPIOC->ODR&=~(0XF<<6); //清空6~9
; j1 f8 T+ p7 D3 h4 p/ Q5 Y* ` - GPIOC->ODR|=dat<<6; //D[3:0]-->PC[9:6]
! q8 Y7 x! U" f1 z - GPIO_Write(GPIOC,dat<<6);
- u" [! w6 D6 z - PCout(11)=(data>>4)&0X01; //D4
3 ]" ~9 U% r/ }' u' |3 ^ - PBout(6)=(data>>5)&0X01; //D5" u6 X3 a+ R8 E& i* c6 i
- PEout(5)=(data>>6)&0X01; //D6
6 M9 I- X( U# Y8 p- [ - PEout(6)=(data>>7)&0X01; //D7 ! Z8 L3 o4 W" @9 y9 B0 @3 ~. f
- } , i- l1 S( C _ q- E2 Q$ \
- //向SSD1306写入一个字节。
# t) O7 H0 E, W$ [: p( o - //dat:要写入的数据/命令% O( h6 r! k1 t2 a2 S
- //cmd:数据/命令标志 0,表示命令;1,表示数据;* x; Q. ]0 b5 u, a
- void OLED_WR_Byte(u8 dat,u8 cmd)
+ X' {$ M/ I4 K) ^1 b! v3 E - {, e3 j8 K' x& h& r
- OLED_Data_Out(dat);
! m c0 k' H2 h8 E - OLED_RS=cmd;, v& M4 k& f8 S3 I
- OLED_CS=0; : }( x0 g; F2 H5 i( e# ?
- OLED_WR=0; 0 X2 ~ C. Z& H
- OLED_WR=1;
1 t8 }' ]3 l2 e) ~ - OLED_CS=1; ( `6 S) R, |; \/ C f/ e
- OLED_RS=1;
% x( }& r, Q5 J; w* s - }
! ?# f$ ]: r% Z( X5 M0 X -
" N- J# m, V* ]$ N B3 H" h - //开启OLED显示 1 F9 E$ v9 h; q3 k8 A; w7 C# |
- void OLED_Display_On(void)- M' k0 o) G$ G: Q E) j& R) F
- {* |- X) I+ h @2 {7 K1 V
- OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
' p8 K! W/ M7 \' X - OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON; N' L" X# a( v/ F! u
- OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON5 a4 j# o3 d0 s" W+ g3 T2 ?7 N) b" U
- }5 g+ w+ a* ]9 n5 w5 Z
- //关闭OLED显示
& w! p4 J; _1 N' e& |: o - void OLED_Display_Off(void)" h( L' y5 W: M3 v
- {
/ R/ H" x- A. {8 P% B; Y: m - OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令8 b1 W5 p- f8 V0 K0 c u, x6 ^$ G I
- OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF& {. v: `* _3 O l7 v
- OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF
( _! y" C* s; @/ z6 N - }
3 ~: O* P; P/ a7 ?; G4 f2 Y' y. @ - //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!! , U$ `: B5 f0 v4 V: K, M7 R
- void OLED_Clear(void) 0 ~ [2 O# Q& z" g# `* [. `# |
- {
- ]! n9 G& U: s) r& ^+ X - u8 i,n;
, a2 B. u3 n. P2 F Y9 w* \& _ - for(i=0;i<8;i++)for(n=0;n<128;n++)OLED_GRAM[n]=0X00; * W! P# V% t; J
- OLED_Refresh_Gram();//更新显示* H% R5 F- L" p! N& w0 D- E
- }
" p) V: A, P/ [- G, l! X, B - //画点 C5 O2 e# y* W+ ~* g
- //x:0~127
, m6 s- i$ g9 A9 p$ {# B - //y:0~63
! ^5 S5 w# S8 t) T/ ~ - //t:1 填充 0,清空 - v4 F7 M2 Y; m
- void OLED_DrawPoint(u8 x,u8 y,u8 t)
" |, {' v g) Y - {
" p( L% I4 w# v/ j+ j- p f6 A2 ^ - u8 pos,bx,temp=0;
+ f7 r2 P" ]5 W z F - if(x>127||y>63)return;//超出范围了.3 {2 j8 c7 m, U
- pos=7-y/8;
+ T$ B2 y0 n% Q - bx=y%8;
1 R+ u) Y. E( l' v$ _( h# [ - temp=1<<(7-bx);4 V5 {' J5 T3 B0 B/ |; P
- if(t)OLED_GRAM[x][pos]|=temp;3 i2 |( R% u' W e
- else OLED_GRAM[x][pos]&=~temp; 4 W5 v+ u% n# P" L6 l" z2 L8 f
- }
: z( W, d$ c# b- `4 I - //x1,y1,x2,y2 填充区域的对角坐标
9 L' O! Y2 r+ K! f7 }3 I - //确保x1<=x2;y1<=y2 0<=x1<=127 0<=y1<=63
: E# e1 {$ @ M! D1 n9 E0 E) I - //dot:0,清空;1,填充 # b6 C9 m8 q- N. j4 K
- void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot)
W) _! P- c( c& U2 ] - {
# U Q# u9 d; i; M/ o - u8 x,y; & `+ S# Y$ _; A4 C2 u
- for(x=x1;x<=x2;x++)1 v$ \( p- h4 ~1 k( I4 [5 F
- {$ c) C5 x) o' ?1 A2 y. T
- for(y=y1;y<=y2;y++)OLED_DrawPoint(x,y,dot);' d" L+ l7 ^8 n
- } ; |; @3 A6 _" m" z @9 v
- OLED_Refresh_Gram();//更新显示
& n8 i* b; L! _5 {! W - }
/ h+ G0 X, z0 X/ F3 L; ~' f. _. J - //在指定位置显示一个字符,包括部分字符
4 G: d% Y& W R/ ^ - //x:0~127
3 P! w( c0 y; L0 b - //y:0~63
2 k2 g% n, W/ u% ~- J( m - //mode:0,反白显示;1,正常显示
0 z, B0 @4 \! l$ ] - //size:选择字体 12/16/24" r' U9 Y. F1 j6 B- \- ~3 u, ^
- void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode)
; K8 Z+ S; N8 n - { ' \: Z7 h& e) Q) T( X
- u8 temp,t,t1; D% [: k" u" a7 N+ b; f0 X
- u8 y0=y;
$ Q0 Q; k4 C' l7 v - u8 csize=(size/8+((size%8)?1:0))*(size/2); //得到字体一个字符对应点阵集所占的字节数( M$ {* U" k. J* c
- chr=chr-' ';//得到偏移后的值 5 _+ `/ f7 N& i1 Y; ^2 L! b% l2 H
- for(t=0;t<csize;t++)
' l }6 v, h) {8 b - { ! r \! ]6 g$ [. m J' i
- if(size==12)temp=asc2_1206[chr][t]; //调用1206字体) q3 \* t+ l5 V/ `( N+ K. h6 f' S
- else if(size==16)temp=asc2_1608[chr][t]; //调用1608字体
l) m8 A( P4 Y - else if(size==24)temp=asc2_2412[chr][t]; //调用2412字体
- m, L: D, i5 L. U. z: V - else return; //没有的字库
: | l/ Y: `0 S - for(t1=0;t1<8;t1++)
' R# ~$ A( p7 q" f$ H - {7 o( B' B' l& X& r' \0 r8 R
- if(temp&0x80)OLED_DrawPoint(x,y,mode);
* s* h! R9 P6 P7 e6 @6 f$ F - else OLED_DrawPoint(x,y,!mode);
+ H3 n4 m8 m6 r4 d/ J - temp<<=1;
1 n$ f9 i; a" k7 Y& Z6 ^3 a- r - y++;
0 f$ q3 {+ X8 W5 m$ w - if((y-y0)==size)
a- Z1 r6 a/ X' y - {
! N, s* u( H5 ^ - y=y0;
! f3 x! ?/ C1 m: d9 d - x++;: G" v2 k9 ?* \5 a( T
- break;
7 r$ J d/ d# y1 W6 H - }
8 T7 x( u3 a( `# G - }
7 `$ y3 X* f/ C9 F - } ' V+ p+ v l; E u& U6 a, e$ V8 m
- }
6 _% `/ M, l3 ]% L! c2 `, s - //m^n函数
3 ~- y5 V l. @- A - u32 mypow(u8 m,u8 n)
% R r8 X( l+ @+ C" r' G4 I - {; p" ~, }) V# L4 M) ~) O* g
- u32 result=1; 2 i; B0 q( o9 n2 R) C6 R* p
- while(n--)result*=m;
5 g3 |, p7 u! ]8 |3 q; ?6 x" P - return result;
2 r V) X- u& U* Y1 f - } 0 @* n* f3 x: n, @0 @
- //显示2个数字
- |; y( v* g" u i9 s8 h - //x,y :起点坐标
w: i% V% f' P+ [; ?3 V( Q - //len :数字的位数 x/ A. Y8 P; O+ r' Y# z0 F
- //size:字体大小& ~# R( f& e. Q2 {8 ^3 o7 N+ o1 S
- //mode:模式 0,填充模式;1,叠加模式
, t- e; y1 `+ C; U( p - //num:数值(0~4294967295);
9 _# ^, X4 |& P& q - void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size)4 Y( A( K! N' g) _# q8 r
- {
* [# f6 s$ V7 ]$ K L9 s( A - u8 t,temp;
( z* f9 D6 w6 t: S - u8 enshow=0; # t( C' c" Q, ^+ W+ g/ {4 U& }
- for(t=0;t<len;t++)
/ Z. P C; M2 o6 Z& F% N1 u P - {! M) G+ i- C; S. X; }) Q/ {
- temp=(num/mypow(10,len-t-1))%10;* ^1 @$ T* d# X5 b% h, R0 O' |
- if(enshow==0&&t<(len-1))* @0 t. r6 G9 Y! ]& o# H" D
- {
3 g$ `( g% S; S - if(temp==0)/ C. E+ n7 }' p' j, q" E( A
- {0 b; a0 }- @7 c- b9 P7 E
- OLED_ShowChar(x+(size/2)*t,y,' ',size,1);8 x9 c. C0 V" M) d% L: V, H7 ~
- continue;
2 f! W6 V1 R+ _$ q6 M. O* [/ n - }else enshow=1;
% U- m. I6 r8 ~# j# a1 U# y - Z* c: K5 i+ c; F0 J; Q% _7 U- o
- }! t( J$ f' \/ P: K. ^ W) }3 E
- OLED_ShowChar(x+(size/2)*t,y,temp+'0',size,1);
2 M) ]. |; r, P4 g# ? R - }
, k- R( E' s9 r% n( c6 Y - } 1 f7 T2 |' E$ i4 m" x
- //显示字符串
2 w5 M8 A/ ^8 Y+ D - //x,y:起点坐标 + K; o3 E7 H# ^2 D1 h0 ?) p4 A+ w
- //size:字体大小
6 K) h# z7 K" z! I - //*p:字符串起始地址
+ P1 m/ a) S" B# o) s' e - void OLED_ShowString(u8 x,u8 y,const u8 *p,u8 size)9 t3 N+ F- [ |: T+ [3 q7 O9 ?6 k
- {
5 E. x4 {; M& t/ R+ i: a - while((*p<='~')&&(*p>=' '))//判断是不是非法字符!1 y& l8 b6 l. z4 ^8 J4 X; M2 ~
- { : ]9 G" |+ a% x: t7 s/ @
- if(x>(128-(size/2))){x=0;y+=size;}
/ w1 b$ Z& J5 u: O - if(y>(64-size)){y=x=0;OLED_Clear();}
7 x& h( j* Z6 {# v$ D) m( s - OLED_ShowChar(x,y,*p,size,1);
( p* A2 D# k) H: h }4 ?, S - x+=size/2;
4 o, R$ p5 m* A' p8 k# C - p++;
8 S3 y, F' u4 x: @ - }
- t4 A* A6 l7 U( [2 a -
4 ]- ?8 x! G3 c# K: o - }
) z( X) c; z4 X) [3 Q - //初始化SSD1306 9 J' ^0 i' F$ A& o7 A
- void OLED_Init(void)! F3 i9 i% _; H' `3 i
- {
( E& t4 @1 h* U* ]3 n: V - GPIO_InitTypeDef GPIO_InitStructure;
4 ]1 |* L9 j% c! U9 e - % Z+ B% Z2 e; \4 a$ z
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOG, ENABLE);//使能PORTA~E,PORTG时钟5 q* u8 }/ _/ {& Q% X
- % y. |/ D7 q9 E2 h
- //使用8080并口模式
! L3 Q, v9 {; R$ Q) ~' w! ^ - $ _4 N" I, u/ @1 D/ Z
- //GPIO初始化设置, T" W8 Q& c4 y; r! A) \ Z
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ;
" I( w8 d" Y( I0 L/ t) m2 K - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
/ G w+ J" {9 j - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出1 f1 \$ u" c0 ^ R6 x$ A/ r
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz/ o! b- e1 d/ G% I
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉7 Q2 i+ g1 _! o# |0 ~& k5 J
- GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化& t* }! P/ U6 Q! q# [6 q
-
& N' `. S9 J. Q6 x - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7 ; $ H7 ~* A$ O9 i- N# K
- GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化; L L2 h7 @% _5 g* a( d5 w
' h8 J9 s7 m/ r0 {3 Z0 S0 Q- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_11;
8 o) p" O: b# r6 \# C7 L, `7 U* } - GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化
7 `1 S) x9 Y( V+ H& y
0 d7 r$ Q% B2 r) N. I& T2 W$ R3 @- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; - U1 p. D$ j& ~9 {# C
- GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化
0 c" {9 N* N0 W1 j' k - 9 x* X0 V2 z- T: n# \" n
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_5;
9 T* `7 u! L: o - GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化
) B) O/ z0 G5 Q5 Z" Y @ - 4 g! Q; A. g, {5 X' {2 O
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; 8 V( i% x: P# d
- GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化
1 H+ H) ?/ x# O - 0 \; o1 w5 J- j8 C( D4 \
-
' r5 ^" w, X7 I9 y. H - OLED_WR=1;
& N- u; Q, X2 b; q# E5 A4 o4 m' s - OLED_RD=1;
4 m! V: [% I6 v p( D% ~) O
* W+ _7 {8 ~ j! h/ ?- OLED_CS=1;
a0 k V7 y5 o9 {# G6 s( { - OLED_RS=1;
M; \% u K/ Y -
4 h1 N" e& y- }1 T) a) Y - OLED_RST=0;9 P3 G" W7 | r& c% l4 x7 I! S
- delay_ms(100);- J1 S- I; m! z$ R* Y
- OLED_RST=1;
+ P$ X9 p/ [& X/ s - ; n9 Y) D+ e. w, H5 `' p
- OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示( h+ Y% ?, I( }4 {
- OLED_WR_Byte(0xD5,OLED_CMD); //设置时钟分频因子,震荡频率
. u& h) B7 p( I! y4 U - OLED_WR_Byte(80,OLED_CMD); //[3:0],分频因子;[7:4],震荡频率, l, [' u* L& _
- OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数
' s5 Q) L! d5 L, Z. K- C: Y2 d - OLED_WR_Byte(0X3F,OLED_CMD); //默认0X3F(1/64)
1 v! I! z! o1 B: M. Z3 v - OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移
, F' n. o7 [3 {0 D7 z - OLED_WR_Byte(0X00,OLED_CMD); //默认为0
5 K+ O! M- g. i. @9 Q `# g - % @- J" }% q6 c" j* r5 `$ R
- OLED_WR_Byte(0x40,OLED_CMD); //设置显示开始行 [5:0],行数.% \% E0 m, w, N K1 E+ e
-
3 {7 M% H: Z2 i& G/ V" F, r1 e1 F- } - OLED_WR_Byte(0x8D,OLED_CMD); //电荷泵设置/ I8 B/ g, t7 J$ K9 s
- OLED_WR_Byte(0x14,OLED_CMD); //bit2,开启/关闭. f* s7 C7 D) L* B
- OLED_WR_Byte(0x20,OLED_CMD); //设置内存地址模式- z, w6 s+ A9 \/ I t; _
- OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;8 D/ J2 I* v/ c/ [" @+ d/ R/ C
- OLED_WR_Byte(0xA1,OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127;; e' F, B1 v& f" C
- OLED_WR_Byte(0xC0,OLED_CMD); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数
+ A L" {& _1 c9 S2 m5 d- D - OLED_WR_Byte(0xDA,OLED_CMD); //设置COM硬件引脚配置
V( c* [ e* m, p/ w S - OLED_WR_Byte(0x12,OLED_CMD); //[5:4]配置$ x4 i9 U5 Q4 k0 d) q( Q
-
8 Q! \$ n- L- ?3 |' { - OLED_WR_Byte(0x81,OLED_CMD); //对比度设置
7 U2 w' |3 \2 h: Z. t - OLED_WR_Byte(0xEF,OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮)
\8 X) g; M. C - OLED_WR_Byte(0xD9,OLED_CMD); //设置预充电周期
4 |1 G+ D* F4 _* Y- E6 Q9 ^5 P - OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;
3 I0 N+ n0 @9 Z - OLED_WR_Byte(0xDB,OLED_CMD); //设置VCOMH 电压倍率
7 ~4 U; {- i6 p& w7 f3 e7 N# t - OLED_WR_Byte(0x30,OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
% i' W, f1 Y& F% ~, t - ; S% X* ~9 u A! Q
- OLED_WR_Byte(0xA4,OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
# @0 e9 i& a3 u/ P n% p$ | - OLED_WR_Byte(0xA6,OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示
" J$ ^7 \ X W2 _( J# u - OLED_WR_Byte(0xAF,OLED_CMD); //开启显示
+ M3 U& T) ~$ _1 | - OLED_Clear();! P+ e( h, H# N8 L3 [( h
- }
复制代码 7 { a! J3 g+ ^% [& b" l& t
main.c& y8 o& Y9 u' \0 m$ R# I* ~
" {. ~8 @* V ]0 n+ z& u: X
- #include "sys.h": X0 m4 ?7 x3 c0 B
- #include "delay.h"4 b$ V5 a% h z. x; v& L
- #include "usart.h"& }' \) O I" a) {# j
- #include "led.h"0 A+ g. q9 f, R
- #include "oled.h"
5 j! A" g9 r. E1 _, b8 H! T5 ?: V - 5 b$ K( O- i: Q+ a0 B% B8 [
8 Q/ j0 x. l- {- int main(void)
+ g& R, I2 y3 c- h# Q- v - { C5 x/ f' ?. J c, R1 O
- u8 t=0;
- b3 k4 m2 j/ x2 I" { - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
4 s- z2 a8 o! R t - delay_init(168); //初始化延时函数
6 N W( C2 g7 M" o" i6 S* |0 y - uart_init(115200); //初始化串口波特率为115200
* {2 \" P% `/ n0 ~8 d6 g: y7 N# Q - LED_Init(); //初始化LED
{- ` I8 T% ]' G. O( q: J - OLED_Init(); //初始化OLED
+ t8 g/ K$ [( E4 v9 ^! } - OLED_ShowString(0,0,"ALIENTEK",24);
/ |5 m5 A5 z2 @/ a - OLED_ShowString(0,24, "0.96' OLED TEST",16); 9 m; r8 V. P2 V* Z$ h* T( I2 G
- OLED_ShowString(0,40,"ATOM 2014/5/4",12); + r, S; Q) _5 H7 n+ f0 V2 [
- OLED_ShowString(0,52,"ASCII:",12);
: g& }. h" _+ g6 Q3 B+ E - OLED_ShowString(64,52,"CODE:",12);
: E9 }+ X Q+ ~* V$ a - OLED_Refresh_Gram();//更新显示到OLED ( M1 X; D8 z( Z% f
- t=' ';
; N$ z) j% h: L+ {1 W - while(1)
& z& }3 N/ G5 { - {
7 I# e5 d' L4 i - OLED_ShowChar(36,52,t,12,1);//显示ASCII字符 : v7 u" {% e8 W
- OLED_ShowNum(94,52,t,3,12); //显示ASCII字符的码值 5 n- ^. x* G. ~: Z4 e
- OLED_Refresh_Gram(); //更新显示到OLED
% D- q6 q# J3 ^, p5 L - t++;
8 x5 q# L b3 M8 j/ P, p% h - if(t>'~')t=' ';
- {" a; t* L6 x- ~( W& ^: r5 W! k - delay_ms(500);
6 l" s! E# _" U - LED0=!LED0;! L! o+ [1 a+ I9 ~) Y& K% R0 j* J" q
- }
: g1 H# y3 t+ p/ N" P4 p6 ]) W - }: s) _9 ~/ i2 B
; C- T+ o" C8 G9 z# \! f. X }' n! ]
复制代码 ( E4 R/ O" l$ J) o0 k, N
q7 |/ @/ P, z8 w |