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