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