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