之前有项目使用维信诺一款OLED 核心控制器为SH1108,一直埋头搞项目,没有实际做点记录查看SH1108数据手册,感觉这个图很好,把SH1108描述的很形象,这里贴出来
8 m* i# \& u' o8 f m$ M
8 d, u6 y6 }4 N1 Y/ I7 f' d硬件部分
9 i4 F. g1 E0 ?( x z- w- s u! ]+ w8 {7 z3 F. S& L
+ p/ d$ @. |5 Q" i
9 ]; E/ A# x/ Y3 a: o# H项目选择是用8080接口,采用IO模拟的方式进行SH1108通信
/ y$ `+ Q% S/ I! {; c+ r: G. H# l8 ?) l
! O/ _3 E, `4 Z' [$ @
: m; W/ x; P- `4 ?* s
( Y+ \9 D, _- `. N6 P
7 [2 r% k* O4 O9 V$ e# Y
项目使用的OLED屏屏为128 COM× 160 SEG,该屏幕有128 个column与20 个Page,每Page有8 Seg即一共160 Seg。
* K1 l! `& y8 F+ j4 R4 L& ~0 w+ Q8 {! v8 r: H
OLED和STM32的硬件连接,STM32使用外部晶振25Mhz,倍频到72Mhz。
( B' l( V. |( d7 Z. o8 N2 ~/ y# z# ]4 I; j2 H! `, l; e
' ~' w' d4 m- g* |6 i* \/ _- Q& [7 `" \; ~
2 u- y9 x3 d8 y- t) v软件部分% }: y. t% q) s7 }! s! n6 |
关于stm32和OLED的管脚定义如下所列- //------------OLED ------------------------------------------------------------------! W6 M( C2 W5 g+ Z5 T
- #define OLED_SH1108_CS_PIN GPIO_Pin_1 /* PB.1 -------> OLED_CS */
0 M, N4 r: i9 k0 V& `3 P - #define OLED_SH1108_CS_GPIO_PORT GPIOB /* GPIOB */2 o" u3 {8 b8 j _. o
- #define OLED_SH1108_CS_GPIO_CLK RCC_APB2Periph_GPIOB
$ L5 I6 x" m! ^: \) N6 K - 4 q! g# {% _0 c$ p: k9 b9 v- P
- #define OLED_SH1108_DC_PIN GPIO_Pin_13 /* PB.13 -------> OLED_A0 */
. u6 t1 r$ n. ] - #define OLED_SH1108_DC_GPIO_PORT GPIOB /* GPIOB */
. D. d6 A7 C0 t( z, n - #define OLED_SH1108_DC_GPIO_CLK RCC_APB2Periph_GPIOB" W8 l2 r" _8 W6 f
- ) W. \3 B4 V4 M0 Y- Q, h. h. G
- #define OLED_SH1108_WR_PIN GPIO_Pin_14 /* PB.14 -------> OLED_WR */
?* {0 s% h) B4 V8 f" f1 A. w# ^ - #define OLED_SH1108_WR_GPIO_PORT GPIOB /* GPIOB */- S, f' ~6 S7 C3 K" p3 O6 b
- #define OLED_SH1108_WR_GPIO_CLK RCC_APB2Periph_GPIOB
: S* G, h& r( z5 F3 _ -
8 P+ i/ T! p0 y2 }- C* N - #define OLED_SH1108_RD_PIN GPIO_Pin_15 /* PB.15 -------> OLED_RD */
8 I# j& P7 e8 _. \ - #define OLED_SH1108_RD_GPIO_PORT GPIOB /* GPIOB */
$ H5 E& K3 W7 d) J, A1 Y - #define OLED_SH1108_RD_GPIO_CLK RCC_APB2Periph_GPIOB- v; W) U1 \( ^, W
-
: ?- N. {4 q) a7 v - #define OLED_SH1108_RES_PIN GPIO_Pin_12 /* PB.12 -------> OLED_RES */
1 i% n7 z$ l: d8 K) H3 v' W - #define OLED_SH1108_RES_GPIO_PORT GPIOB /* GPIOB */
( D* }7 l; L$ Y1 p( s0 H; a% N# h8 S) h - #define OLED_SH1108_RES_GPIO_CLK RCC_APB2Periph_GPIOB' c8 Q& r# Q4 J. E
-
! ^9 k1 T" L( e7 [( u - #define OLED_SH1108_D0_PIN GPIO_Pin_0 /* PC.0 -------> OLED_D0 */
- r# C; L" F) N5 r1 x( b - #define OLED_SH1108_D0_GPIO_PORT GPIOC /* GPIOC */! H, {6 }: T+ Z# ~ E1 O
- #define OLED_SH1108_D0_GPIO_CLK RCC_APB2Periph_GPIOC
$ C3 Z* V. H3 w E1 X. p/ ^ -
$ [' l4 R E# H, o9 G6 j - #define OLED_SH1108_D1_PIN GPIO_Pin_1 /* PC.1 -------> OLED_D1 */: C8 b* W- k$ Q9 f E ^; c
- #define OLED_SH1108_D1_GPIO_PORT GPIOC /* GPIOC */. m! g3 b) v( I( q+ S2 l1 V
- #define OLED_SH1108_D1_GPIO_CLK RCC_APB2Periph_GPIOC9 V O$ W7 M: M; e, `
-
% U% o$ P0 L: y) g/ Y; Q+ Y - #define OLED_SH1108_D2_PIN GPIO_Pin_2 /* PC.2 -------> OLED_D2 */) d/ K, s" O4 f* B
- ; m: w6 N0 ?8 A0 g8 V& _; U) ~, V; E4 \
- #define OLED_SH1108_D3_PIN GPIO_Pin_3 /* PC.3 -------> OLED_D3 */
# s0 G- `2 s, V) G% S& n - # T9 x( Y8 w1 x Q6 }: S
- #define OLED_SH1108_D4_PIN GPIO_Pin_4 /* PC.4 -------> OLED_D4 */9 V. m6 z3 m) v3 e
- + _. t" ]. A( F- d; q: g( |3 C
- #define OLED_SH1108_D5_PIN GPIO_Pin_5 /* PC.5 -------> OLED_D5 */4 L+ d5 N' @/ v9 ?6 Y0 Z- y" d
- * R. ^, {/ I% f6 s; y+ C
- #define OLED_SH1108_D6_PIN GPIO_Pin_6 /* PC.6 -------> OLED_D6 */
- G9 c/ c- p: z+ s; g& P, t - 3 u% F- Y7 S1 x9 F
- #define OLED_SH1108_D7_PIN GPIO_Pin_7 /* PC.7 -------> OLED_D7 */
& m% h% n1 F: \& A7 t. u7 p - % q/ b5 G1 r9 N
- #define OLED_SH1108_XDATA_GPIO_PORT GPIOC /* GPIOC */
) Q/ `1 D9 V7 V0 y - #define OLED_SH1108_XDATA_GPIO_CLK RCC_APB2Periph_GPIOC
. `+ s! J" b0 k/ m& f- Z# ]* O8 f -
9 w, Z7 L2 F" K+ @" q5 h1 @ - #define OLED_SH1108_RES_LOW() GPIO_ResetBits(OLED_SH1108_RES_GPIO_PORT, OLED_SH1108_RES_PIN) & S: Z/ j# V1 Z, H
- #define OLED_SH1108_RES_HIGH() GPIO_SetBits(OLED_SH1108_RES_GPIO_PORT, OLED_SH1108_RES_PIN)# v3 { r2 F. H" [6 @9 f/ h
-
6 {' C) T; c b" ~+ f0 n - #define OLED_SH1108_CS_LOW() GPIO_ResetBits(OLED_SH1108_CS_GPIO_PORT, OLED_SH1108_CS_PIN)
7 Y# O3 V: f/ @: {7 m/ O9 M# A - #define OLED_SH1108_CS_HIGH() GPIO_SetBits(OLED_SH1108_CS_GPIO_PORT, OLED_SH1108_CS_PIN)
, K1 N' D! b6 @' g -
4 j$ O3 C" c3 t, C - #define OLED_SH1108_DC_LOW() GPIO_ResetBits(OLED_SH1108_DC_GPIO_PORT, OLED_SH1108_DC_PIN) . c& ^0 b9 `; j; ?5 z$ {1 n' }
- #define OLED_SH1108_DC_HIGH() GPIO_SetBits(OLED_SH1108_DC_GPIO_PORT, OLED_SH1108_DC_PIN)4 t5 a0 K* F6 | }3 B- |
- 3 u/ O# e7 Y9 d! [1 G0 O1 ^
- #define OLED_SH1108_WR_LOW() GPIO_ResetBits(OLED_SH1108_WR_GPIO_PORT, OLED_SH1108_WR_PIN) 4 o3 K8 l, } u$ r- ] z# M/ f
- #define OLED_SH1108_WR_HIGH() GPIO_SetBits(OLED_SH1108_WR_GPIO_PORT, OLED_SH1108_WR_PIN)1 c* b9 e+ G# B: Y
-
- {' s0 N! [. u) J: I3 J - #define OLED_SH1108_RD_LOW() GPIO_ResetBits(OLED_SH1108_RD_GPIO_PORT, OLED_SH1108_RD_PIN)
- V& [. R' T- b ?1 g, b - #define OLED_SH1108_RD_HIGH() GPIO_SetBits(OLED_SH1108_RD_GPIO_PORT, OLED_SH1108_RD_PIN)
" \ g$ F$ B, E& W - - ^/ o' I% l8 Z, ?- s3 ~8 S% j. h1 F
- #define OLED_SH1108_XDATA(x) GPIO_Write(OLED_SH1108_XDATA_GPIO_PORT, x)) j9 ^$ u5 ~/ p% }" R
- //#define OLED_SH1108_XDATA(x) GPIOC->ODR=(GPIOC->ODR & 0xff00) | (x & 0x00FF)/ {" o6 g8 ?) Y& t/ b
-
* Z1 O/ r: n: a. L. a - #define OLED_SH1108_SCL_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, OLED_SH1108_D0_PIN) 7 q# S* }% Z, F2 D1 [- c
- #define OLED_SH1108_SCL_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, OLED_SH1108_D0_PIN)
, P: T: Q0 X6 I0 A - #define OLED_SH1108_SI_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, OLED_SH1108_D1_PIN) & O0 { {" s% L4 e3 f! U) I6 {
- #define OLED_SH1108_SI_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, OLED_SH1108_D1_PIN)
U- ]% ?7 q( ]* t% U - $ [' O$ e' ^- v9 H0 Z
- #define OLED_SH1108_D2_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_2) ( y; G( W8 c" F$ L# _- L5 ]: a
- #define OLED_SH1108_D2_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_2)
/ t* K. c' d% o1 u/ S7 s. G% l - 6 `" }7 T3 Z' ]5 n' m
- #define OLED_SH1108_D3_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_3)
8 r. g6 k0 v. E - #define OLED_SH1108_D3_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_3)" Z9 X$ b; I R! Q. K
- / J: k. }( J9 R) b
- #define OLED_SH1108_D4_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_4) . X n; u* d/ t" s( M/ m
- #define OLED_SH1108_D4_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_4)
1 H. I; i: y( F0 D - ( \2 V* {/ j" j, `# B
- #define OLED_SH1108_D5_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_5) 7 P; Y. K3 W" b4 f; Y
- #define OLED_SH1108_D5_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_5)
+ h' T+ t) I ^* ]0 g! | -
1 ^& @) Z0 F: S. X! K, H - #define OLED_SH1108_D6_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_6) ; e) {6 F7 @$ Z; V8 r5 J2 j! v
- #define OLED_SH1108_D6_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_6)1 D: H' _7 y9 W" @8 P
- 5 K3 r G. @% N- F; W, B
- #define OLED_SH1108_D7_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_7)
( r5 v$ J7 W$ U: F6 v7 @. s - #define OLED_SH1108_D7_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_7)
复制代码 % L! w+ k. q1 F: i6 T7 O. a
这里为了速度将PC口单独连接到OLED的数据线上,这样可以加快操作OLED的读写速度。0 ]7 e5 {, e; W6 v; Z' O, e
* U, v( }9 M# r测试main函数,实现了OLED显示汉字和字符串,部分图案显示没有测试- /******************************************************************************
6 |$ o- L5 W$ I" E4 P0 C - * 函数名称: main()
/ [% x& Y+ q: z! Q& v - * 功能描述: OLED测试5 h( [7 @) U. T6 ]5 a
- * 输入参数: 无. y+ T+ q$ Y9 E, A6 I
- * 输出参数: 无4 x& r1 ?) m' v. V
- * 返 回 值: 无; p6 A5 z, }: b# t9 m( ~. b
- * 其它说明: ` l" C9 z% M
- * 修改日期 版本号 修改人 修改内容7 d% O: K( `2 i' E" ?' |3 v9 H
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5 ~" }0 C, N- k* { - * 2013/02/22 V1.0.0.0
- Q6 W" ^9 q% Y$ c$ N! H - ******************************************************************************/
6 e/ {- q9 H9 X- k - INT32S main (void)
+ H4 U j3 O- {, x' ?. O - {( g( C% A, i+ M2 j- l- J9 k* u$ Z
- BSP_Init(); // 系统初始化 ) ?, [. c: d/ T1 Q* W; P
- oled_sh1108_init_program();
" U: l# n/ l" A - OLED_ShowChinese(1, 20, 4, 1);//主: `: ^3 N! X3 A* p2 s4 [
- OLED_ShowChinese(93, 20, 5, 1);//副# j' L' I) _( ?8 j) K3 ~6 z. E
- while(1)
4 |" H* w3 ]. F- g- D& M$ a& w" Y% N - { / H% c1 W' Y& [$ [& ~
- sprintf((char*)oled_display_buf," ");
% c6 l4 ~3 G9 a4 A - oled_sh1108_show_string(61, 5, oled_display_buf, 12);
6 A: |' A0 t; q5 H& f - sprintf((char*)oled_display_buf,"%4.4d-%2.2d-%2.2d", 2022, 1, 1);: g3 x9 a+ N: J$ u6 ?* X
- oled_sh1108_show_string(1, 5, oled_display_buf, 12);
& a* j' G- Z- X" \, K - sprintf((char*)oled_display_buf,"%2.2d:%2.2d:%2.2d", 10, 10, 10);
; c& Y, o1 ~# Q - oled_sh1108_show_string(105, 5, oled_display_buf, 12); ' m) `5 s" M( c
- oled_sh1108_refresh_gram();
7 ?% j% x2 m/ O - }: K( k1 A" L* ?4 E N+ z
- 9 n6 @5 i5 T0 Q3 ]' R8 z" W
- return (0);' d* F7 }1 y: g4 f: z0 O
- }
复制代码
6 \5 I1 \9 g7 P/ X+ W6 Y6 `; C
3 J2 [' ^- J0 ^; T+ H. J; [STM32内部缓存定义,每次更改该数据,一定时间,或者及时将该数据刷新
y9 |: a( I% `. b) }, j- /* OLED的显存1 R- T# G; ^6 c. u
- * 存放格式如下.; m" P }, _, @7 \* _% h
- * [0]0 1 2 3 ... 127 ( a" {1 l% V3 Z6 M
- * [1]0 1 2 3 ... 127 0 Q* X. ~6 Z' P
- * [2]0 1 2 3 ... 127
+ `+ s9 {2 u3 |* d0 j$ Q3 I' T - *) y* l, R; }; C: t3 p
- * [19]0 1 2 3 ... 127
, v9 F! T7 x8 a - */2 ?% L1 S! G" w
- static unsigned char OLED_GRAM[128][20];
复制代码 * p2 W# r- d& w$ o- s) u$ p/ {
刷新缓存到OLED,该函数实现将缓存数据刷新到OLED8 H& d- \" ], p
- /******************************************************************************
; @. h. | U/ v$ t - * 函数名称: oled_sh1108_all_screen()+ `$ }4 ^" }; I- [
- * 功能描述: 更新显存到LCD
) P' B0 t) ^6 D! G& Q( @ - * 输入参数: 无- D/ u% k9 \# g! N* Q/ s' ^
- * 输出参数: 无
6 N2 y; w. i3 T& u' }3 P; D. t - * 返 回 值: 无& @2 b+ V" B a& d
- * 其它说明:
/ e8 `3 D( c$ C4 @/ Q - * 修改日期 版本号 修改人 修改内容
3 k2 P+ y' F. s5 x& z- x - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
( r, K; I& e& G7 m - * 2013/02/22 V1.0.0.0
; U. a& o6 ~% N9 t7 @+ r1 q - ******************************************************************************/
3 M: q% U K% P/ T; n' { - void oled_sh1108_refresh_gram(void)7 W' F3 A$ M) N5 I/ K
- {. V; L* |0 |% m! z3 U2 n8 V4 O
- unsigned char i, j; r9 n3 {3 g4 O M. J
- // for(i = 0 ; i < 8; i++) : Z" u9 K* R5 [) H& E4 p. W
- // { 4 K) q8 d$ h1 |" @
- // OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
7 S# b1 X$ V1 f% c3 t, p6 f2 \ - // OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址6 f; x1 r1 B6 j& X; L
- // OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
7 L/ b6 M# `# G - // for(n=0;n<128;n++)3 j2 N5 t3 ]$ @: E
- // OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA); ( j* C6 O5 p3 b0 b: x
- // }
8 f$ c t$ h f9 I( \ - for(i = 0; i < 20; i++)
7 ^# ~2 _, m% S# q - {9 ^; [; { Z' e. k
- oled_sh1108_write_c(0xb0);
& k' P( @. R% ?0 ~* W: u - oled_sh1108_write_c(0x00 + i);" C* H& L& V0 e" J) `/ }5 f
- 5 s7 L) W; b% d
- oled_sh1108_write_c(0x00);
7 u6 q4 X) O, C5 W- d) T, } - oled_sh1108_write_c(0x11);
" b: _* r8 ?2 j) J - for(j = 0; j < 128; j++)& o- H1 t3 F: a# |
- {7 i# A1 }: p; |9 T) X
- oled_sh1108_write_d(OLED_GRAM[j][i]);! s9 X: n# t( Z5 X, y
- }
m6 Y/ R7 R- ~ - }
* ~' ~- q6 I3 q& ^* |/ y7 M - }
复制代码
; ]) y! t* v; [. F————————————————6 y, ]& k y( H4 o# a" q0 S
版权声明:大牛攻城狮
7 H. K7 t* x* e: _+ r. V/ J( E
8 r, o$ `. g- y- U3 d4 R
, G) {3 M8 ^. T& \. Z; k+ d |