一、原理图6 N4 M! X- b1 w e' b! w& m' ^' A
& t0 ]/ W% V# E8 e
+ ?; Q7 @4 K' X
+ X9 m+ Z! k7 H$ {: o0 Y9 K" k" n
芯片引脚连接4 o9 S* `7 A8 g
' ?/ {9 {$ k8 L* C7 k. j4 y2 b! ~1 U9 s' T( b$ ?: w
二、驱动程序* Z3 F. W- U V( D3 F
spi.c' u) U5 [1 j4 x+ ~
2 v8 v: U1 M; I" C9 I& ]- #include "spi.h"
) j) N+ D& Z9 H' g% c8 O1 E; `
" X& G* U3 Q6 W- void SPI1_Init(void)' e0 n$ T6 m) f: H
- {
# R3 i; X$ [9 ~6 g- }8 N7 z - GPIO_InitTypeDef GPIO_InitStructure;
* I: c+ \" `, \: s) ?! v4 _3 h - SPI_InitTypeDef SPI_InitStructure;
7 M5 k1 l8 {+ m6 g - 6 w; H1 v& ^( Q- s5 D( \
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );//PORTA时钟使能 ; Q( T- d, s) N* r6 F+ ^. A
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1, ENABLE );//SPI1时钟使能
8 i# ?! u- B$ \0 g2 n4 u - . x) v& L& z* L N- D* b
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
3 ~* G O! S# o: B6 Q - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
, J+ ^, t) u9 V/ p2 @% H - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;8 _% ^9 E C, w2 x6 ~4 m
- GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA
8 d. U b! d/ X$ N! T" j* b
+ U+ ]& _& l2 e$ _- GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_7); //PB13/14/15上拉; c! g4 p1 L( ^/ {% [
- + O" v& R- k/ g% I
- SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工$ q& y% Q& P f% v) s7 ~
- SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI
# h" h- d: h0 }* S9 f. z9 r - SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构
2 u" b+ p6 z+ [+ _ - SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行同步时钟的空闲状态为高电平
' k1 F+ d# b. v! } - SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
/ y2 Y8 X, Z) Q) q - SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制" F5 e% P' A% T) K+ Z
- SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值:波特率预分频值为256+ l `/ o* Y3 u7 v6 y- l
- SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
. ~; H- }- R7 Q, _ - SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
' E0 b/ p* I( ]6 j% W3 I/ Q' Z - SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
+ O( z5 m( S) h2 Q - 1 N; x$ t {* n% t3 m9 w6 l3 \" \
- SPI_Cmd(SPI1, ENABLE); //使能SPI外设
^8 S& ^) K$ d$ m5 b) b* B+ s -
: c4 j' I/ d2 r$ X; p - SPI1_ReadWriteByte(0xff);//启动传输 * x D* [: b6 R6 w$ T
! H# o% ~' j" e& r- . w2 P, A% ?; y. {
- }
+ b4 t% L) D0 v# v - //SPI 速度设置函数# \5 C: M; k" V8 K4 W" V
- //SpeedSet:
* j, {; L3 T" [/ Z, w7 r c4 H; W - //SPI_BaudRatePrescaler_2 2分频
) I! p5 \8 B3 G$ T3 f* d - //SPI_BaudRatePrescaler_8 8分频 r: p2 `. k& f! T9 t( }7 `
- //SPI_BaudRatePrescaler_16 16分频
) d( y2 q; [5 [# g - //SPI_BaudRatePrescaler_256 256分频
2 a r& s5 E6 D; F7 H/ A$ |/ v P - + K" m4 y! D) C2 N1 K4 R
- void SPI1_SetSpeed(u8 SPI_BaudRatePrescaler)% O( i Z+ T! A" ?7 a! ?
- {. J: r4 a4 J5 W( N" Q
- assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
& K7 x/ s! a) n) w - SPI1->CR1&=0XFFC7;& O1 ~& L1 R; L) P4 G
- SPI1->CR1|=SPI_BaudRatePrescaler; //设置SPI1速度
6 M) R$ z, m8 w; C1 |( ?) D - SPI_Cmd(SPI1,ENABLE); 9 r- }6 G5 {4 ~7 U+ D3 k' Z
2 r. r4 R4 i: S9 c: d- }
7 V5 A$ p4 r+ `- J/ R - 8 K0 c9 d' @5 f; z7 |
- //SPIx 读写一个字节5 d# D( i. N7 ~0 N$ U2 e
- //TxData:要写入的字节
_& |9 m# n4 V+ M7 \* ~# o' n - //返回值:读取到的字节
9 E$ q: p7 _7 I$ s; ^/ h0 f' B& A - u8 SPI1_ReadWriteByte(u8 TxData)- f% t( {1 V) A- R+ \; Q
- {
# H6 Z8 Q' Y2 z0 H Z2 x; I& S% g( i - u8 retry=0; ; H/ {1 f0 _9 y
- while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位6 ?% f$ p1 a2 @# U5 ?* Y9 P% B
- {
9 z* @! p! B9 N! i' W! I' l8 ? - retry++;0 f4 Z+ G' B8 J
- if(retry>200)return 0;5 T {- A! K. T0 B9 _
- } + u" o2 W, r0 z0 h7 P8 e, D
- SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据3 G& b) K& B- C2 a/ M e2 i
- retry=0;+ o5 v; [9 S. p7 L
- 3 S" c1 j. z: J4 |# i- x* s
- while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
4 M% O1 }, V; H% [7 x# f - {4 E( y( g: C/ _. c
- retry++;
1 R7 G! Y7 {4 i, C$ V( y - if(retry>200)return 0;
) u5 u3 G9 n& h, N - }
- n1 I& `. _" {7 x - return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据 - p# C$ J) l; w: h# C: |& N
- }
复制代码
1 D1 ~' y1 d9 m( goled.c' ~ X Y: S z; Q. B' ^
D1 x9 g. P( l" T
- #include "oled.h"4 z: }( |0 A) A1 S: {8 e
- #include "stdlib.h"
( x0 z ~* _0 z g4 }4 {; J - #include "oledfont.h"
- A- e9 ]2 y0 l; z* ?% j" o/ h - #include "delay.h"
2 E$ X8 j7 q5 f* C0 r% F6 ^8 _ - #include "stdio.h"
. ]( e$ C3 J1 E - #include "spi.h"; L; ^+ U5 l" ?; P& K) k/ O
- //OLED的显存
1 x1 A: b& L& f; E# W0 {/ U - //存放格式如下.* `/ y+ J' X0 k$ R
- //[0]0 1 2 3 ... 127
2 U6 y( [. ?/ V* c% N% {$ @# q - //[1]0 1 2 3 ... 127 : [/ U6 v7 w1 [/ Z3 K
- //[2]0 1 2 3 ... 127 1 |- W6 N8 S7 t: x/ G
- //[3]0 1 2 3 ... 127 O* } Q5 N$ g
- //[4]0 1 2 3 ... 127
3 ~" I( T L& a" p/ X, b - //[5]0 1 2 3 ... 127 * H9 g H! b* f1 G8 S
- //[6]0 1 2 3 ... 127 ' E# H1 V& Q$ j+ A
- //[7]0 1 2 3 ... 127 4 X$ n1 ^6 {6 ]) N; m
: |% w. T: ~. t" e+ ~* [3 D7 e- //向SSD1106写入一个字节。# F9 V: e, R* x" Y' o
- //dat:要写入的数据/命令
- |- l% d+ T" s8 Q5 O - //cmd:数据/命令标志 0,表示命令;1,表示数据; H2 a) _* D* Q! d$ @
- void OLED_WR_Byte(u8 dat,u8 cmd)3 F Q9 Y; |: s0 R5 C
- { ) y* R x' M e4 N
- if(cmd)# O6 y" j6 W+ t6 @8 o
- OLED_DC_Set();
9 A! M% F+ ?; l - else
& f1 E' f2 q# y |# Y, T - OLED_DC_Clr(); . y* F5 f. D$ n. s% H6 C# D( d
- OLED_CS_Clr();: ]% ~+ V9 Y6 ?2 [
- SPI1_ReadWriteByte(dat);
: ^* ^) V' r% G' ] - OLED_CS_Set();5 y1 |0 T# X9 r- {
- OLED_DC_Set();
5 }: @& ?2 ^2 p1 @: _ - }
$ D% ~9 D8 L* Q6 s. u - 6 \; @; K. g9 o0 S
- void OLED_Set_Pos(unsigned char x, unsigned char y)
: E8 G" c, j6 C% D/ M7 F5 D" O - { & t' h) q* \" O; p" T) B6 W
- OLED_WR_Byte(0xb0+y,OLED_CMD);, W% h. V( H6 G( a5 P
- OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);4 _' C: T5 Q4 T8 O- q% }. ^' I
- OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD);
6 h! l" T! Y( f$ Q3 _3 b; V" C - }
* ~" [5 k9 z. p4 `, v0 |2 O: P - //开启OLED显示 0 f7 X8 A, [2 V
- void OLED_Display_On(void)7 e/ ~% A4 |& `
- { x! a" s G0 g6 b
- OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令( P- f# C% e+ |/ ` U
- OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON
, @ H: h! u3 `% ]% u - OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON
* Y) T4 I' n- ~ N, J9 | - }" S( N8 j- O2 m
- //关闭OLED显示 5 R) W1 A3 Q9 q, A1 X3 T2 V
- void OLED_Display_Off(void), I. a8 n& w! n! u: G' v
- {
# q9 f! o) Z* l$ j3 T( i' N - OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令) }! Z) w' c/ a
- OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF& ?4 g1 B6 W) j7 J9 D4 L% T
- OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF4 S, u. `4 G* `; E& K* I; h
- }
4 w U$ E6 \0 E q0 a - //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
8 B* a P8 Q/ J9 u# h6 d$ C - void OLED_Clear(void)
2 @* M$ { m9 ~% k" ^ - { ; K: K& z% p7 r1 b
- u8 i,n; + N) Y2 ]3 e% V, P
- for(i=0;i<8;i++)
8 B( ?6 B2 M# m X, D+ ^' E. W! O - { ) s( ?. V0 H+ t1 B0 g, R
- OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
$ M$ z( N* V, I. ] - OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址4 V) {8 N- {) I0 R& |
- OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址 . Q8 q! l7 V' f- W2 k
- for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); # b; J; T. F, z+ S6 u
- } //更新显示$ K" A0 Q4 _6 ?# I/ g- q, k
- }5 p w' x- Y+ w# X0 V& l
- % d+ ], j0 m1 `6 N3 a# u% U1 o
- E! a/ h1 N3 F; I7 S6 k5 w- //在指定位置显示一个字符,包括部分字符4 R, t4 Q7 {# j; k- s8 O
- //x:0~1271 D; E/ \0 `! M3 V z( Q) y( M
- //y:0~63 e% n- q% M C: N, R* J/ o
- //mode:0,反白显示;1,正常显示
3 z. d3 `, S7 H, u - //size:选择字体 16/12
# y4 l/ X9 T) P% {+ d - void OLED_ShowChar(u8 x,u8 y,u8 chr)
R9 U2 h, i+ f+ B+ | - { . D" Y" Z6 l* c6 Z
- unsigned char c=0,i=0; ! Z9 p6 \1 n! ]+ \% P
- c=chr-' ';//得到偏移后的值 " N- f: ?4 v3 `
- if(x>Max_Column-1){x=0;y=y+2;}
$ E% f3 X+ X; a t6 s - if(SIZE ==16)
1 n, V' {: p- z/ g - {
- t Z4 c. D& m7 E - OLED_Set_Pos(x,y); , q5 H2 R5 M v
- for(i=0;i<8;i++)8 p1 Y3 l$ _9 u
- OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);8 _# A2 l' O: u {7 j( s
- OLED_Set_Pos(x,y+1);
0 X0 y0 e1 ~( s7 k* d" p - for(i=0;i<8;i++)
, |. I3 h5 }- b. Y$ J$ ~; i - OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
& B1 @+ y' D. S) } - }# ~. S+ B, _9 U Q( w: W2 b2 d
- }$ T" r. ?5 O0 I ]7 T- P! Z8 n
- //m^n函数8 i5 a0 F8 I6 }1 z7 I
- u32 oled_pow(u8 m,u8 n)
4 ` D6 _- D5 }1 q2 ]9 v - {
: \, B/ Q5 E' k( m1 w! B* {- E - u32 result=1;
9 {7 m$ U6 i! u2 v0 b - while(n--)result*=m;
, Z# H! F4 Y0 s7 [- u. z - return result;. w- Y, p& A. h2 r1 M
- }
4 n- a, H' Q3 L) d- ]" j - //显示2个数字7 Y* E( u/ b. o' |9 K
- //x,y :起点坐标 6 @# X; Y# X- U& G: k) |$ @4 i
- //len :数字的位数3 O. Y/ {3 N, Z4 D9 f+ m
- //size:字体大小
" d: q0 u0 ]; j/ t - //mode:模式 0,填充模式;1,叠加模式7 X# V; b% W" |2 g g% X. m3 V
- //num:数值(0~4294967295); 2 H; A4 t+ ?- N/ @" Z% A9 U8 `
- void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size)
; u/ X( D+ _% ~' n - { % Y' R/ j8 n( T6 `/ f1 _
- u8 t,temp;! u' ?3 N; O9 Z2 H, w
- u8 enshow=0;
4 v* _5 E3 \! X0 m% e - for(t=0;t<len;t++)
. U; H* J' Z7 X* u0 c* u/ n2 U - {
8 E! ]; Q7 m- ]: s5 R* W$ H - temp=(num/oled_pow(10,len-t-1))%10;# P0 c$ k# {/ M4 D5 L
- if(enshow==0&&t<(len-1)); M1 p+ S- q' _
- {
: E$ A0 m' P2 x8 G. `$ W. i - if(temp==0)
1 r$ ~3 d; a) ~: b; ~7 [ - {' r& i4 I1 @9 O# S, ~
- OLED_ShowChar(x+(size/2)*t,y,' ');
5 M2 o0 t' U. t3 x; l: L* r - continue;- ~6 `" |7 r0 d- e8 `" Q5 K/ s+ O
- }else enshow=1; & b8 w7 j2 k0 f- k9 `0 f" p, R
-
' g+ y- [. }1 e z0 \; D - }
0 D7 w" x/ _; t' [' f- G - OLED_ShowChar(x+(size/2)*t,y,temp+'0');
9 |, d N- n3 R2 ?2 r' O - }
2 A/ E; F# M6 ] - } 0 o4 I9 L2 P2 i2 `
- //显示一个字符号串/ d, F9 Q- G- |! A+ R" f& m4 R3 E
- void OLED_ShowString(u8 x,u8 y,u8 *chr)$ M- }% X, |4 {1 x n6 q2 E$ t
- {: k, X/ _1 c- \
- unsigned char j=0;. X! L4 }% c8 F0 m2 B7 ]& v
- while (chr[j]!='\0')
3 }1 U/ x# e: U - {
* e9 P( F7 Q/ b - OLED_ShowChar(x,y,chr[j]); N. u! f# q# S
- x+=8;9 |# s9 s4 H) c7 [, Z
- if(x>120)' d3 Z9 {. g9 E! |
- {
+ A V$ ^3 ~& p! l - x=0;! ^$ I$ J# Y7 y. ?) m: e
- y+=2;8 M, i8 e1 Q) Y" o. ]" E8 j* M
- }1 A4 g# d2 p, v ^; G$ w/ j
- j++;) Y t! f# X) a& n3 d7 a
- }
. _9 w. a; n% W v2 o - }
. H/ \% S, @+ P0 |" m6 d - /***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
/ g# t. n' u) D2 p" m - void oled_draw_picture(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])1 R C2 g# a6 I6 y0 n K$ h
- { L( w9 B5 Z% w- O- {6 [2 x' f
- unsigned int j=0;. ^) q: i3 G, I9 y
- unsigned char x,y;
: g5 ^' n" v. b8 k
3 K3 T# t2 ^9 u, v8 c- if(y1%8==0) y=y1/8;
2 z# a1 |) d. K8 ]- m* H4 [ - else y=y1/8+1;3 l& E* s. f' r, o; `' I, @ L
- for(y=y0;y<y1;y++): O1 X8 A, V3 A% n
- {4 D. q8 Y9 R' \
- OLED_Set_Pos(x0,y);) U2 V2 Z# x. |& j6 }
- for(x=x0;x<x1;x++)$ T- q0 a* @( [" o0 O
- {
`5 w3 y- x. V5 V! P! H! K - OLED_WR_Byte(BMP[j++],OLED_DATA);7 G8 p" o: e4 b* l$ e c) X
- }3 x, X$ S$ j1 N
- }
' l! a; V* i# |% m6 a9 q8 ~ - }- ~! C2 a( C& K) u- p8 r3 E
- void oled_gpio_init()
+ P V/ p$ p# C- s8 o - {
% v8 U; [9 e9 H$ X; z: j - GPIO_InitTypeDef GPIO_InitStructure;
$ G% `$ j# M& Y; M% n7 ]9 v2 M - $ V J$ b4 G% e/ g4 l- s9 _8 I& M+ m
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);6 m9 E" m8 e3 n; v) k# y9 P
1 _5 K, I9 [4 c0 x8 Z8 X2 E- GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
4 b, f+ G J3 P! A( s# I - 9 v& \! ^+ Q7 l/ I2 B
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_6|GPIO_Pin_8;
1 e# u7 \8 h c - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; & b/ v, P a( }- u1 K/ m+ j# N$ @
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; , c* |% X" Z$ [# N( i# R; N
- GPIO_Init(GPIOA, &GPIO_InitStructure);
7 `* |: T! S( c# o9 k - GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_6|GPIO_Pin_8);
& G2 b9 Z: f" D8 i6 `7 p
) N& ~" X0 K2 {" Z-
6 ?! Y; C0 i# k e/ A - }' D# Z( a$ b/ [, m# b5 c2 h
- 5 ]# P2 M9 x. I" p( [& e4 l- G
- 5 Z/ \+ T* [0 z
8 y" ~+ F/ p5 P0 t* p- //初始化SSD1306
% a% x$ k! s# L. w0 J) x - void oled_init(void)4 k) j3 P/ v# ^ F4 z
- { ' x( v( q0 }% H( O- Q# [ l- g9 x
- oled_gpio_init();
: [; c9 @2 J' o9 f7 S: ? - SPI1_Init();
, Z9 e* n6 T" h/ s( Q# f# `8 Y
" m- m! B h% n5 U% M3 @- // OLED_RST_Set();//复位使用系统复位,所有此处不需要再复位
7 s8 ?8 x3 k" O5 o! w - // delay_ms(5); P% Z5 k$ n. O# \0 _
- // OLED_RST_Clr();
9 y4 y1 l/ {, ~! @5 r, k, f( ]1 b - // delay_ms(5);! k: B6 o6 h3 v# {5 t
- // OLED_RST_Set();
* Z; A& u( i! ]5 f: v -
0 I1 T: C; b$ W- A- I2 ` - OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel2 n, J" X; \6 Z8 Q
- OLED_WR_Byte(0x00,OLED_CMD);//---set low column address8 u& x, n* p$ B( {, r
- OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
* n; l+ N. t7 ^- j - OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
) {8 E4 l* n! f+ ?5 s* f4 i - OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
3 a+ `) V" g4 X0 }% _6 ~, n: l - OLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current Brightness
3 q6 ~, g9 h9 @" U* y/ W - OLED_WR_Byte(0xA0,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常5 ^& Q3 g: y9 K4 V
- OLED_WR_Byte(0xC0,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常3 _7 ?( B& ~4 e L
- OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display; }7 [" ~: V4 V2 L1 s) L
- OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
8 f( c8 _- n \ u2 J - OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty& h+ D1 T% j+ x, D
- OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
. b; O- h3 u/ g+ H9 {) _# P2 A5 G - OLED_WR_Byte(0x00,OLED_CMD);//-not offset ]8 K2 L6 W- k r, Q8 F
- OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency) ]8 J( r4 Y# Q \. q }
- OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec4 I: a7 S/ G, F0 W6 Q% z( c9 i; d% q
- OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
+ B- P2 {# A2 X Z - OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
7 U N7 ~( s; Y - OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
! r5 M y7 Q0 ^3 ~. B1 o. d - OLED_WR_Byte(0x12,OLED_CMD);
~2 X7 q% e2 L% q- @* Z - OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh; S9 |2 q }' _+ ]
- OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
% Z$ Z1 s1 Q- B# B! n; x - OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
# E$ F+ w* U. p; V% P' \0 e9 F$ ~ - OLED_WR_Byte(0x02,OLED_CMD);//6 v$ t/ Z* D+ T- M7 [
- OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
, O D% U: Y5 _ - OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
8 {, v4 u! m6 p9 T9 B! ~ - OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
( P! z% h6 O" X8 X) `) a7 e: y# z - OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
, V& S# s9 Q/ f& J5 Z- \% c. t) w* @ - OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel# I: r3 D: Z* x& D8 }1 A. A! A4 Q/ {
- 8 M2 `$ m3 ?/ H& E8 g8 L
- OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/ 2 k0 U7 C* k% z* t/ R. g* z
- OLED_Clear();- t2 H2 U3 ~$ u: M3 m( _
- OLED_Set_Pos(0,0); , F$ z" x+ i& d2 K, M" l3 E9 A
- SPI1_SetSpeed(SPI_BaudRatePrescaler_2);4 M+ A) S& r, G r9 W3 `1 g
- }
复制代码
$ n" \* o4 }1 a3 Z _ d% Emain.c
" K$ _7 u7 [" @7 u
9 g% }2 `1 f' @. s- u- #include "sys.h"" F& u3 C. k/ F0 N; d0 v
- #include "delay.h"
1 ]' [* [3 }' e t* W3 J; u% b+ j - #include "usart.h"
% ~/ { a. @1 B9 ^& O* w d# g - #include "oled.h": ~# P! N3 K' k2 d' H! t6 F6 m- k
- #include "tm1804.h"! F/ g3 A+ d4 m% S* Q5 Q l9 \
- int main(void)9 w0 E* v4 L/ U$ v" O( n" u
- {
5 h. h8 R: V- [7 U. T R - delay_init(); //延时函数初始化
; X% H7 }) r" D. t* ? - oled_init();
' ] u! |( z3 e: H6 S1 ^& } - tm1804_init();
8 v7 E! C3 j1 l - OLED_ShowString(0,0,"xupengxisxveryx1");
1 D% ~# l, I$ N2 d, K) o7 @ - OLED_ShowString(0,2,"xupeng is very");
" a8 e, E: F6 B - OLED_ShowString(0,4,"xupeng is very");$ f; [- u" s! G- J/ L
- OLED_ShowString(0,6,"xupeng is very");
# ?8 {+ k! M! {9 ]" a0 h$ h3 N -
4 X% K0 n1 w3 y7 M- y7 w1 E4 A - while(1)
: h! `! |/ v$ v1 ?8 ?) r: V6 r9 ~" M - {0 p) L _) c. }8 f
- set_tm1804_data(0xcc,0x00);
0 Y1 L7 I) y% c+ a3 y - delay_ms(1000);; E7 U1 }) M- E0 X; \+ b
- set_tm1804_data(0x00,0x00);
! T6 I! {, a% c7 l) N. A: P - delay_ms(1000);; i3 d( k2 o3 d* T* A) s; K
- }. I+ J8 X! d- P4 {1 x5 n6 E
- }: [3 M; k( @1 ^+ C4 }
复制代码 + D. S4 j, Q/ X7 W! \) s$ D
/ x) S4 i5 _$ R, a6 O/ S% u/ A0 V6 S; n
5 ~1 r2 _* S* Y |