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