一、原理图
1 P; |, Q2 `% p( ~, U% P6 B7 W$ l) d% @8 K. W' M% R
8 e& R+ Y4 ?5 x5 ^" I# l. e) v3 Z; i
芯片引脚连接
6 G L: B8 E1 B( p
# R# |2 o: p% [1 S
. t3 |1 |0 J0 S/ \- \3 n二、驱动程序
) @7 n, `/ W3 z7 yspi.c ]7 M& B7 N4 | i0 [
) J/ X6 y+ O; f
- #include "spi.h"/ S W$ n$ ?9 D9 H+ t- F
+ V5 r- E3 ~# `8 g6 n: y+ P- void SPI1_Init(void)
$ r5 v: K& ], B4 U) G - {: x! _- `, _" ~' X+ X, I; |
- GPIO_InitTypeDef GPIO_InitStructure;
i& s: |% n0 H; L. v - SPI_InitTypeDef SPI_InitStructure;
; d* N" W0 R1 l* U# [
+ m( ^! Z, ?. f' ~+ Z* I2 E+ {2 [- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );//PORTA时钟使能 . Y6 h' S1 ?6 g# [- J
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1, ENABLE );//SPI1时钟使能 & w% M& o& u; {, D
- / |$ i" t8 o, F4 O8 C1 _
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
. c5 j# @3 N3 [( Q# v - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
' Q4 E- Q- s& ^3 @ - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;5 `! R& ~' [& ^
- GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA6 A$ L3 j3 H5 H: X' C. B
/ q" K2 E o/ x* w' b) r- GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_7); //PB13/14/15上拉
; G+ S i' K2 t% V - 6 K9 p# Z8 \' I. R- P' X0 w
- SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
9 a& x% T: Z7 A8 j - SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI6 D% ~% ]& ~; S1 \0 U& }
- SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构
% a/ M! ^" Q7 a( `, j9 q2 l - SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行同步时钟的空闲状态为高电平3 S ?* o+ {4 p' [7 A* K- ~! d
- SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
8 G' R d/ U1 y/ s0 K* V# B9 }& ?0 W3 ? - SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
3 a$ c+ H! Y1 I5 S% r- W0 b - SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值:波特率预分频值为256
; t: P$ e! R! A - SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
: |4 U- U0 e3 Q* R) T - SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
C1 @6 u# _" ^' u - SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
- Y( U) [( N) i- J2 z9 v" g& T
9 F5 }7 H- D7 P- SPI_Cmd(SPI1, ENABLE); //使能SPI外设
. w3 f6 }# j. e7 R. } - 4 Z; m! e- r. _) `6 g# | s
- SPI1_ReadWriteByte(0xff);//启动传输
9 J8 n, |( M6 p! j/ a, c- ] K - % Y$ e4 i8 i0 f. F( L
- N5 b7 ^* {" M, o5 D- v1 }+ ?- } " @* @: H4 }* p; {' o
- //SPI 速度设置函数8 f& B. b6 b4 c6 E+ d4 X, L
- //SpeedSet:9 {- i2 z# @$ p
- //SPI_BaudRatePrescaler_2 2分频
9 F. J# P9 x- o" {$ r9 Q8 ^ - //SPI_BaudRatePrescaler_8 8分频
- ^3 }/ m: ~7 a7 P+ F4 p V - //SPI_BaudRatePrescaler_16 16分频
* f8 X% K/ K3 K* Y% @0 w8 V$ ]' d2 P$ N - //SPI_BaudRatePrescaler_256 256分频 G: A0 \( Q" Z6 V/ R9 X7 t+ }
- 1 T) I- f, `" \& V8 C2 W( e
- void SPI1_SetSpeed(u8 SPI_BaudRatePrescaler), u( Q$ T- g% ]+ N" n5 Z ]; m
- {
/ h- m1 G& _2 y2 L3 ~ - assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));+ W6 T' x, S. c& j$ e2 M0 ]0 G; x
- SPI1->CR1&=0XFFC7;
& S5 E: u" P# ^+ W% d+ V+ d- w - SPI1->CR1|=SPI_BaudRatePrescaler; //设置SPI1速度
1 }0 `& m2 x% H- d/ P - SPI_Cmd(SPI1,ENABLE);
0 s: j- d7 u' k. |* x - ' r, n2 W6 J; E: B$ H! E
- }
, r: t1 B( y# Y3 \* h
" _- h, U7 x, r$ \- B- //SPIx 读写一个字节
& n1 U0 t$ b3 [: n# F - //TxData:要写入的字节
j3 t' n( P6 L1 B - //返回值:读取到的字节/ z0 a5 g2 {" I* O
- u8 SPI1_ReadWriteByte(u8 TxData)# O8 j' A2 r) L' H7 B) R
- {
# ` ?7 J* i- b$ N - u8 retry=0; + {2 ?- I/ e# ]3 w
- while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
; m% ?" U" D0 r! G - {2 C5 k6 W8 @0 X% l: i i
- retry++;& d2 z' n6 H, F# t" o# C
- if(retry>200)return 0;) t9 q, L' F2 t- g
- }
5 J& F+ i9 `% e# v- w! ?$ ]$ z - SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据" F' ^: e: Y5 B: y% `0 K6 {2 ]
- retry=0;
5 M0 `9 O- T3 v2 `% l V; l! P6 ]
/ z1 @# r6 f) }( v! U4 N7 i/ C- while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位& I$ q4 `6 x8 O; T7 ^
- {
) M4 ~" @2 X6 O6 J - retry++;
/ P0 H# I& M8 x3 k M - if(retry>200)return 0;
+ |3 l7 G; y9 V* ~- { - } ( Z8 |$ W. o* R& v6 K0 e3 k
- return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据 0 a c" s2 O4 S& v5 O( z
- }
复制代码 ( B; a5 q4 Y& B! Z9 a" ]
oled.c# |! E4 l" v0 ^7 ~! [% A3 \8 t
9 @6 o" U* ~* E8 p9 T- H- #include "oled.h"
% t8 {. p+ R& K - #include "stdlib.h"
% R$ A$ l/ ]7 u$ O5 L4 q - #include "oledfont.h"
6 C+ s J% z; g" F - #include "delay.h"
H# G0 S& Z. a( c6 ^" k4 X - #include "stdio.h"3 p" E2 d/ f: B
- #include "spi.h"/ v1 D# o! E3 ^
- //OLED的显存
" [) l) D8 I2 D - //存放格式如下.. F Q* c" y2 U/ I' K6 |: o* K, Q
- //[0]0 1 2 3 ... 127
( O3 N- J" T% q3 d - //[1]0 1 2 3 ... 127
" k: h! W' S# _& \$ ~" \ - //[2]0 1 2 3 ... 127 2 d. w3 B) ]& S0 t& a
- //[3]0 1 2 3 ... 127 - e8 d; ~5 m8 U; ?% m
- //[4]0 1 2 3 ... 127
' m* e0 X3 F5 Z, Q: r; k - //[5]0 1 2 3 ... 127 1 N1 W* f1 ?7 \9 l' O; c: b8 G
- //[6]0 1 2 3 ... 127 0 f4 Z+ L( @+ ^
- //[7]0 1 2 3 ... 127
2 n' a: Y0 k" j5 F$ _) {7 g7 _
$ E* r" y& f+ B; P, S8 b- //向SSD1106写入一个字节。
- {9 F8 Q' y; j* {3 q6 W - //dat:要写入的数据/命令
" H9 D, L7 {0 p9 \ - //cmd:数据/命令标志 0,表示命令;1,表示数据;
3 }, e4 L+ U B' y/ l - void OLED_WR_Byte(u8 dat,u8 cmd)
+ u, \/ A3 G. i1 x+ i# N+ l - { 9 Z0 J) a1 T( R& B
- if(cmd)( ?& R- h5 W. s* N
- OLED_DC_Set();9 c, h# [$ s9 }9 D
- else
3 _- g1 P: W2 \8 m& p - OLED_DC_Clr();
( M) X1 A6 j0 o: H1 j: v - OLED_CS_Clr();, Q" N! v% m6 Q7 x
- SPI1_ReadWriteByte(dat); - v6 i- {6 J! B. `7 o0 c K% a
- OLED_CS_Set();
/ l( p% Q7 R& _; x+ T - OLED_DC_Set(); 4 @5 E8 Y6 x* b! M; W. R/ Q
- } ) ?6 x7 E) Q) j7 f2 e* Y
- ' _% m6 z) V2 ]+ E
- void OLED_Set_Pos(unsigned char x, unsigned char y)
( t X% c6 F' E, Q, W' R3 } - { : }" j& z1 V9 n+ Q; l- {
- OLED_WR_Byte(0xb0+y,OLED_CMD);
3 O5 U; R# v6 H2 K - OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);: X. H* N2 h! q7 L
- OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD);
0 U& o- |# M5 _ - } 2 G% K2 Z: m% o# S6 s% q
- //开启OLED显示 ( m5 l& R# }/ e: I5 p5 N; b6 Z, a
- void OLED_Display_On(void)/ b% G2 O, E1 e
- {
0 O+ H% t( o' y% P; J' m, Q - OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
' X5 d3 i1 a; C, K& [" | - OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON
6 t, D0 j! Q! h/ v. N0 s - OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON
~% a( I' ?0 r0 _; h0 d - }
& a3 [/ H: b* n& o7 ~- S1 Z2 S P - //关闭OLED显示 + _, B! x& V6 S: ^" ?; s
- void OLED_Display_Off(void)% D. k4 m+ t$ z- ?' A! W1 c x
- {0 d k c* X4 T
- OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
; v' k: n- M% n5 D- a/ V: \/ p8 S. R - OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF
1 e: V/ Y" R" K, E# ?7 ~ - OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF! [9 c. O; R* s6 N7 ?
- }
0 `3 I6 O5 b9 R4 j9 H. M5 y - //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!! - y5 V' @! s: H5 h
- void OLED_Clear(void)
5 t; p% Y8 C* J+ [) m% N3 K& p: j( o - { ' S: q" H% j- S6 G+ n
- u8 i,n; 9 E ]" V1 Z4 z/ g, G8 r" W8 `* p
- for(i=0;i<8;i++)
# r( _* q$ `+ j' p7 p- _& V - { 1 w4 F" Z5 X. A5 q- u
- OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)# \2 X* Q6 d' }- p. \
- OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
5 A9 D/ Y7 \, m; I" _ - OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
8 Z/ N, D, r3 B& w - for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
1 j, _/ I* h7 V* u' {! t& z. s" V - } //更新显示
7 I+ [( l+ k0 g2 U% z, s" ?( J - }- X* s( q$ n0 @2 ^: O) f
- ; f' `* ^ M6 e2 E3 m2 e
( j M5 C# o- P: | Y$ f- //在指定位置显示一个字符,包括部分字符
7 S1 L% h& X, ~* e. r - //x:0~127# Y6 Y5 h, Z9 K) v I; h1 _- P
- //y:0~63
* R4 P; X8 j8 E' n - //mode:0,反白显示;1,正常显示 " G1 J- p9 d1 c* q. k5 D7 x5 u
- //size:选择字体 16/12
+ A7 U5 E' Y0 D8 Q - void OLED_ShowChar(u8 x,u8 y,u8 chr)1 X' w9 ^+ R; a, e: }( \
- {
! \, M+ A" K1 d- N - unsigned char c=0,i=0; 3 N3 [7 B, ~0 t, d
- c=chr-' ';//得到偏移后的值
2 i- p. m. H i5 b' ] - if(x>Max_Column-1){x=0;y=y+2;}
& `2 h! T8 s4 Y, E7 u! P - if(SIZE ==16)7 Y" E( d: s( [6 C! K
- {4 \3 W; R+ X! g: {% v3 ^; ?
- OLED_Set_Pos(x,y); 7 Z$ H6 X+ ?+ z* P0 P2 f h8 Q* S
- for(i=0;i<8;i++)
6 Z* }4 s5 c6 P - OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);* X$ g* {5 ]+ a' D8 B2 G+ W
- OLED_Set_Pos(x,y+1);
# n9 Y- N" ]* d - for(i=0;i<8;i++)
* f; w5 I, E& V+ C% l" F; z - OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
, Z! r- |$ ~2 L& n - }
- B, j* N+ h0 r. y7 F- [) x - }7 C( F4 V; o! f/ u+ B( e" `; c
- //m^n函数* d4 o: k5 G: A& ^. w+ z$ u7 I
- u32 oled_pow(u8 m,u8 n)
+ B! y8 P& u* O3 s2 B* U - {
8 U! }; d& F. y - u32 result=1; 1 G, I& q& H/ Q) Q e- N
- while(n--)result*=m; - U( ~6 u/ a0 _; v* C) @
- return result;
# S/ `, Y( z0 @7 f0 T) Q - }
9 V7 n u) R, [6 p9 M - //显示2个数字3 m& ]/ V6 [3 k1 i( K- X
- //x,y :起点坐标 2 L8 ^3 l/ [" ^. o. {
- //len :数字的位数
' ?9 D; d) A4 t$ P4 w0 _& U! Z - //size:字体大小
9 G+ K8 w4 d$ V' n0 H1 G" l - //mode:模式 0,填充模式;1,叠加模式$ E! k, h/ E$ `& N% S
- //num:数值(0~4294967295); , b( H' L4 n1 u% e4 l: q
- void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size)
$ r: W; C/ m2 R% r. f* x T- J" a - {
- `# @2 P# k" |' S/ a. K - u8 t,temp;
# d" e4 ]6 g/ l - u8 enshow=0;
7 m' h) b+ ?6 y5 d1 \) O - for(t=0;t<len;t++)4 S& R- \. C: m8 }+ g4 g- j
- {' }7 r: F! t$ `' |) Y, f* |/ T7 F$ p
- temp=(num/oled_pow(10,len-t-1))%10;/ r3 ?4 ^" i+ `; F# W: X$ {/ t
- if(enshow==0&&t<(len-1))1 w+ h5 b* q( Y6 k% A6 ^
- {
& ?! d( K3 v0 b/ i& K! J; Z - if(temp==0)# M% C: b" t% `4 L3 j2 g) w& V
- {4 x. j* x" \$ s u
- OLED_ShowChar(x+(size/2)*t,y,' ');5 W% B, ^* n- g5 H/ y! T9 Y
- continue;
6 ?/ }6 |6 U* Z( F, t - }else enshow=1; S+ D1 D5 `9 T% p: i7 j
-
! |! A: n3 M$ |. `) V8 G# m$ Q* I - }8 C7 H( |& J; O Y ?6 b9 w% B( @7 e9 R
- OLED_ShowChar(x+(size/2)*t,y,temp+'0'); 5 T4 v' `! o- I* L! X$ D- I% V
- }
3 ^4 N6 \8 \) e* T8 S4 V1 C - }
1 I( l6 H8 Z8 R- s+ c - //显示一个字符号串
1 w9 {7 r5 e) n. O% ` - void OLED_ShowString(u8 x,u8 y,u8 *chr)0 t1 S1 S( I$ v' B/ [. T
- {1 ^1 K* U7 H" V. e. }& E
- unsigned char j=0;( R4 i! {8 o4 _% _( c! m1 Q4 `
- while (chr[j]!='\0')6 P/ ?4 W& A" ]: B; Q
- {
' h. W2 S, w2 y# @! ?( v - OLED_ShowChar(x,y,chr[j]);
1 u1 @! F n7 N- q7 P3 X7 ? - x+=8;+ R7 F, ~1 b/ e' t b0 A7 ?
- if(x>120)* p; [* h5 t7 Y7 y9 [
- {
9 |, T2 J* D* T) D% C - x=0;0 K: D5 M$ G+ A# _$ ?9 L" j
- y+=2;8 A" V2 V0 ` m7 C& l! e
- }
. Q' O2 p5 M. I8 E0 a - j++;
) J, ]( Q! s# } - }
, t, F6 J: K7 A! g - }
9 @# f: H* r/ W# p( y/ f" T0 b - /***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/! u! _0 k( j( E% ~# |" n* y
- void oled_draw_picture(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
9 L4 x$ e5 F; Y' c& J6 s - {1 h6 C9 j6 t3 O4 Z" J. `- J
- unsigned int j=0;
4 @! R$ d% o% ?& q - unsigned char x,y;1 D" ^. J# i5 _1 S) r0 n
- ) x. P( F9 Q! p- C. F5 x, r$ O
- if(y1%8==0) y=y1/8;
/ I( a+ U' r+ A" E: q5 f, A - else y=y1/8+1;/ \" ?. `( L `+ j" b0 c
- for(y=y0;y<y1;y++)0 e& C3 h/ D4 d+ j) t" y
- {
9 }+ e6 ^# Y" D8 g% i - OLED_Set_Pos(x0,y);. `4 R' L( L& Z* l
- for(x=x0;x<x1;x++)0 c, c5 G" S& X1 U1 q+ ?- Q
- {
! \4 T) U; d8 y2 `+ g3 x% X, K/ S - OLED_WR_Byte(BMP[j++],OLED_DATA);
3 |* y. f5 _' e; a. A% o - }
' ]" m0 ~9 l% U: I& |: g+ R - }; P8 b, {$ K) O M2 w8 [( k
- }, `( j3 b3 S X' q) F$ Z
- void oled_gpio_init()
: `+ d, x3 C: G6 V& ]/ @ - {1 f1 q5 P$ G7 b% Z- C
- GPIO_InitTypeDef GPIO_InitStructure;0 x3 F: }- h: ~* `0 \
' [! O) w1 }( A, h0 m- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);
' [8 U. e$ x0 `# Z0 d - ) ?# `5 s- N7 m- g, d2 z2 I+ Y
- GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); . Y5 F$ j7 @2 {/ u0 N; G" b
- * T D+ x. X$ E4 J) a7 Y
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_6|GPIO_Pin_8; 3 d1 j4 R+ A' r% Y
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
( Q- z! B. p5 ^( ?3 s6 X' f! } - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
2 T# R3 v/ ]% K; w; A - GPIO_Init(GPIOA, &GPIO_InitStructure); 1 S" |7 y$ h! b
- GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_6|GPIO_Pin_8);7 P& L* v5 O! q' {' |. x
4 l1 F$ {$ H5 [6 Z {-
4 E' i) }0 x# m - }5 I/ c# X5 \! N l* p
- . w8 P% c; X5 Q& M
- 5 J* r, N. {5 [; I
- * `% T# ~$ }: |
- //初始化SSD1306
% o- s# a# {$ x - void oled_init(void)
/ j" L# a% C$ H5 g/ r) I - {
. c$ \$ a( A" g7 m1 |4 h: b - oled_gpio_init();
- `8 u4 L6 K1 P/ D( W5 x: K% v. p - SPI1_Init();
* P8 g: v0 S7 @& F& E* ?
$ p! V% ~' r o6 i/ D0 w9 x- // OLED_RST_Set();//复位使用系统复位,所有此处不需要再复位4 Z8 A% S( k3 R* ~
- // delay_ms(5);
5 q# b) m7 b6 T - // OLED_RST_Clr();, Q) b; Q: U1 h V+ @
- // delay_ms(5);! J0 Z' ?0 b' j& Y
- // OLED_RST_Set();
* r9 Z, u7 o+ K4 i" ]) D -
6 d: Y4 X5 h2 ]) ]. D1 T - OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
4 G4 x) O1 n+ d5 X0 I& \ - OLED_WR_Byte(0x00,OLED_CMD);//---set low column address4 S- O) t4 T% h
- OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
1 r7 H; j& ?4 ~* ?2 _* f+ K* C - OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)- k" P* w2 m: d
- OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
7 X& w7 u# O; e: w1 `' k- t1 n - OLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current Brightness
/ q. M8 ?6 J" {6 _9 y - OLED_WR_Byte(0xA0,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常0 }8 A3 L) q. ?% C$ W
- OLED_WR_Byte(0xC0,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
* P3 a8 R, P; g6 I! x- u+ e - OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display; z* R0 W4 q$ v
- OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64); k, K$ T9 r( }4 n" \
- OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
, y5 h6 F/ Z) X( K; J - OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F). Y/ R1 u* ^, h- [' W
- OLED_WR_Byte(0x00,OLED_CMD);//-not offset1 X' ^ `1 M- C
- OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency- c/ l( l& I' b+ S, [* B7 e5 ?$ T* d
- OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
" \# i9 O. h; a% U3 ^$ B' |/ E4 L - OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
$ `& P# r/ z" y8 _ - OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
; T5 ~0 @: g; s - OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
7 P8 O% r/ M( P& v+ y8 z - OLED_WR_Byte(0x12,OLED_CMD);
5 {- L0 l, F& h! o1 e6 E* X. g C - OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh2 F1 [# C# Z% a/ L/ k8 T+ ^
- OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level6 h% ]% F; Y6 W' p! r9 o: E8 L
- OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
0 i$ k0 c4 E% {; c- P8 M - OLED_WR_Byte(0x02,OLED_CMD);//+ r9 w" w$ `3 N1 Y' [
- OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
- W, i; C/ l( f( n( Y, M! I - OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable5 S0 @7 N- {! V1 ?5 m' }
- OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
9 G8 L2 A2 l" g: }0 z) D - OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
( t9 n8 ^5 ]: p' R# b9 F2 E+ V1 m- w - OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
1 _. ~, ^# B5 r3 ] -
7 i9 O8 @" ?5 ` j' x - OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/ ; i: Z; @: [, }
- OLED_Clear();9 t4 N* ?9 l" F( [* j$ Y
- OLED_Set_Pos(0,0); 8 u1 I3 h) N% e3 i$ \/ G' Q
- SPI1_SetSpeed(SPI_BaudRatePrescaler_2);
& r6 S6 V, |1 K7 i, D7 U' J - }
复制代码 % T" t$ e5 T: s+ k/ I7 N' u
main.c
6 f! T E) R; c) X; I/ M( T& C6 W( n' l7 a- s6 s
- #include "sys.h"
/ {! l8 E7 a8 C7 b3 l" y$ z6 Y$ H - #include "delay.h"- P" Z4 i; p1 w' E# b8 ^
- #include "usart.h"
+ g+ R7 B* m+ ]2 ?2 y - #include "oled.h"
( n2 A$ A- A( L2 W - #include "tm1804.h"
& ^& q( e: o1 N5 c0 o) G. n1 q! ? - int main(void)
9 m1 {) M, N. W& x. X! g - { / q4 \1 A+ p5 x" b! ?- B9 ?, H
- delay_init(); //延时函数初始化
+ Q; t4 d) x& r0 _- w - oled_init();
+ w/ z9 M# u2 l5 j) T; `; I - tm1804_init();! e6 C: y0 Q* a R5 i
- OLED_ShowString(0,0,"xupengxisxveryx1");
# _& S4 ?: U! N8 c - OLED_ShowString(0,2,"xupeng is very");' ]$ f; J4 P4 V$ H& R0 h4 K
- OLED_ShowString(0,4,"xupeng is very");
1 J- u( h% w: F# j - OLED_ShowString(0,6,"xupeng is very");
8 F% C7 r! ~& O. L) S; _- J - 9 ^) w4 [* X( s) k+ | B2 b0 E6 D' O
- while(1)
) K5 h# `, Y, W! s* X - {4 t9 o9 w9 N, Z2 P, n
- set_tm1804_data(0xcc,0x00);
+ C; k" n( R6 |( f - delay_ms(1000);
3 Y5 o4 R3 x8 Y7 e9 \/ n# E - set_tm1804_data(0x00,0x00);/ y; G) ?$ |# ] ?2 L) u0 m4 }
- delay_ms(1000);5 F5 s3 V$ c, M6 ^& }
- }
) t/ e4 b* x& f/ x7 i - }
: M- x$ i! ?$ k+ B
复制代码 7 M8 _$ A, s( X' s; ]
4 w& A1 u5 A. x- F) W* E7 r; N4 w" M
3 k: Z% C4 J) q* s8 N: H. a; E) w& V+ C2 {- U* t2 L
|