之前有项目使用维信诺一款OLED 核心控制器为SH1108,一直埋头搞项目,没有实际做点记录查看SH1108数据手册,感觉这个图很好,把SH1108描述的很形象,这里贴出来
- Y/ S$ d/ b- O k& k) a
: y5 f& o7 `1 C* ]9 |硬件部分
1 h- S1 {2 N1 J% Q
/ V8 Q; E, K! D# ~9 y: Q7 I
2 f2 ]6 }: v# ^+ ]) q) P6 B R! r+ s1 Y; t
项目选择是用8080接口,采用IO模拟的方式进行SH1108通信1 k# B4 A3 t5 x+ U" _' t
) Q8 j6 w& A6 u9 X$ n9 ]0 {9 H
, `9 v. v" @9 S
1 m/ ~: t0 m2 H6 k. A- D' J
3 H) J5 y% e( u9 T
" B: [9 C0 u3 E5 x项目使用的OLED屏屏为128 COM× 160 SEG,该屏幕有128 个column与20 个Page,每Page有8 Seg即一共160 Seg。/ D" X5 b4 E0 m) E% B- i
6 w/ e/ b9 ^+ ^. R) R- iOLED和STM32的硬件连接,STM32使用外部晶振25Mhz,倍频到72Mhz。
8 g& V- n) J# l( L( h2 q4 U _! n3 v; l# n& t! O
. \! z! X9 I9 D* o$ n& U1 T) U( H2 S( x z2 m9 H6 ^8 H. C1 j
. T) g& S$ D9 v& X8 t6 x( t8 I8 W% W
软件部分/ l+ c4 G( q0 H7 m. p, A
关于stm32和OLED的管脚定义如下所列- //------------OLED ------------------------------------------------------------------- X- W, [* O! Q' M+ q8 H8 J' G
- #define OLED_SH1108_CS_PIN GPIO_Pin_1 /* PB.1 -------> OLED_CS */0 L r L/ {( W" w d( ?+ M' a
- #define OLED_SH1108_CS_GPIO_PORT GPIOB /* GPIOB */7 v2 J+ G4 T5 J/ N
- #define OLED_SH1108_CS_GPIO_CLK RCC_APB2Periph_GPIOB, U( ]: h2 Q" I. j; D
- : Z( o. j$ i. P$ q+ O% }& k' c
- #define OLED_SH1108_DC_PIN GPIO_Pin_13 /* PB.13 -------> OLED_A0 */6 L8 m \/ t9 [
- #define OLED_SH1108_DC_GPIO_PORT GPIOB /* GPIOB */
( P0 X5 J6 z2 [. }' J! f - #define OLED_SH1108_DC_GPIO_CLK RCC_APB2Periph_GPIOB
) ?6 c: g4 a n9 e( {/ T! x1 k -
2 k8 Y' x' M; L) n$ H - #define OLED_SH1108_WR_PIN GPIO_Pin_14 /* PB.14 -------> OLED_WR */
' y3 U# e+ k8 J* Q" d - #define OLED_SH1108_WR_GPIO_PORT GPIOB /* GPIOB */
. ?4 [2 u0 s. z0 J5 j( b - #define OLED_SH1108_WR_GPIO_CLK RCC_APB2Periph_GPIOB! W6 L) W5 m6 T/ [
-
5 K" w0 c( l4 W7 |$ h - #define OLED_SH1108_RD_PIN GPIO_Pin_15 /* PB.15 -------> OLED_RD */
- c+ C t$ y6 {: W - #define OLED_SH1108_RD_GPIO_PORT GPIOB /* GPIOB */) c" l) H" p/ T4 M7 Q
- #define OLED_SH1108_RD_GPIO_CLK RCC_APB2Periph_GPIOB$ O$ X4 [" h$ R5 Z
- 9 i7 ~" r: b- _% T
- #define OLED_SH1108_RES_PIN GPIO_Pin_12 /* PB.12 -------> OLED_RES */: q- J L1 s2 v+ p+ N
- #define OLED_SH1108_RES_GPIO_PORT GPIOB /* GPIOB */
; t: Y+ D- ?+ `5 f. Z' P1 ?3 l - #define OLED_SH1108_RES_GPIO_CLK RCC_APB2Periph_GPIOB" f l* q! w6 c) a; o5 w
- : j: F, j9 g6 T/ F# H
- #define OLED_SH1108_D0_PIN GPIO_Pin_0 /* PC.0 -------> OLED_D0 */2 a" [2 K% P$ H0 s
- #define OLED_SH1108_D0_GPIO_PORT GPIOC /* GPIOC */
. T- `/ Q, z' }! a- K, w/ n - #define OLED_SH1108_D0_GPIO_CLK RCC_APB2Periph_GPIOC
9 j- X+ |/ q. J% o# D -
; p ^9 J5 t4 y( E6 ?1 ^ - #define OLED_SH1108_D1_PIN GPIO_Pin_1 /* PC.1 -------> OLED_D1 */
8 q/ C' {3 f% \% T, y6 E6 p! a7 [, q) k - #define OLED_SH1108_D1_GPIO_PORT GPIOC /* GPIOC */0 y8 a/ w* O Q) L
- #define OLED_SH1108_D1_GPIO_CLK RCC_APB2Periph_GPIOC7 S! S8 a/ Z1 Q
-
$ f* r3 w2 C& Q( ^ - #define OLED_SH1108_D2_PIN GPIO_Pin_2 /* PC.2 -------> OLED_D2 */
8 |6 M# e3 _# S6 |" Z - $ b4 Z3 y/ _3 v
- #define OLED_SH1108_D3_PIN GPIO_Pin_3 /* PC.3 -------> OLED_D3 */
2 B; p! s: a9 ]; c -
9 V3 q, H4 f* I& Y3 U$ U$ n - #define OLED_SH1108_D4_PIN GPIO_Pin_4 /* PC.4 -------> OLED_D4 */4 ]; v% \% @/ U3 V
- 5 L" _: D+ E3 Z3 N4 [/ ~
- #define OLED_SH1108_D5_PIN GPIO_Pin_5 /* PC.5 -------> OLED_D5 */! n; z2 a& S; V- y
-
7 n- J. v% ^1 F: B. A - #define OLED_SH1108_D6_PIN GPIO_Pin_6 /* PC.6 -------> OLED_D6 */7 ?- W6 I# P5 j T6 Y( u) v
- + e! Q8 `, z7 }
- #define OLED_SH1108_D7_PIN GPIO_Pin_7 /* PC.7 -------> OLED_D7 */- R; P" t6 p: ?
- $ \. R) \' n6 G: T% N
- #define OLED_SH1108_XDATA_GPIO_PORT GPIOC /* GPIOC */
( O3 p1 x9 }1 j& x - #define OLED_SH1108_XDATA_GPIO_CLK RCC_APB2Periph_GPIOC
0 N/ B4 S: @+ U" R - $ P: v+ \% o o, q8 H8 ]4 f
- #define OLED_SH1108_RES_LOW() GPIO_ResetBits(OLED_SH1108_RES_GPIO_PORT, OLED_SH1108_RES_PIN)
# F+ t$ U# N S - #define OLED_SH1108_RES_HIGH() GPIO_SetBits(OLED_SH1108_RES_GPIO_PORT, OLED_SH1108_RES_PIN)5 Q3 i2 o) a0 f1 d( A
-
1 O. L4 E/ }: T& C$ Y" ` - #define OLED_SH1108_CS_LOW() GPIO_ResetBits(OLED_SH1108_CS_GPIO_PORT, OLED_SH1108_CS_PIN) + F1 s* o9 [. r1 }$ n& [6 C
- #define OLED_SH1108_CS_HIGH() GPIO_SetBits(OLED_SH1108_CS_GPIO_PORT, OLED_SH1108_CS_PIN)
/ R* p' J# I, d1 r! A -
% Z: H; k0 o5 C' z. h3 b) ] - #define OLED_SH1108_DC_LOW() GPIO_ResetBits(OLED_SH1108_DC_GPIO_PORT, OLED_SH1108_DC_PIN)
$ P6 @+ a: n! e0 y3 P - #define OLED_SH1108_DC_HIGH() GPIO_SetBits(OLED_SH1108_DC_GPIO_PORT, OLED_SH1108_DC_PIN)
# ^$ l2 R6 o/ Y -
7 V/ o2 Z8 ]3 z* j9 a% M! s - #define OLED_SH1108_WR_LOW() GPIO_ResetBits(OLED_SH1108_WR_GPIO_PORT, OLED_SH1108_WR_PIN) ; d) z1 M4 g( N) v( [1 c
- #define OLED_SH1108_WR_HIGH() GPIO_SetBits(OLED_SH1108_WR_GPIO_PORT, OLED_SH1108_WR_PIN)& ]# ], I- | c j& c
-
% `4 ?! l3 G7 ]6 ~/ ]& I" ~ - #define OLED_SH1108_RD_LOW() GPIO_ResetBits(OLED_SH1108_RD_GPIO_PORT, OLED_SH1108_RD_PIN)
2 ~+ B4 Q! j( b. e - #define OLED_SH1108_RD_HIGH() GPIO_SetBits(OLED_SH1108_RD_GPIO_PORT, OLED_SH1108_RD_PIN)
7 A# I i& x) e! u8 V6 q -
% I6 l* I8 U' n4 o( ]" v - #define OLED_SH1108_XDATA(x) GPIO_Write(OLED_SH1108_XDATA_GPIO_PORT, x)
* `, E+ S2 A9 A0 y! ?% w" e$ G - //#define OLED_SH1108_XDATA(x) GPIOC->ODR=(GPIOC->ODR & 0xff00) | (x & 0x00FF)7 N1 a U+ h% f) f1 c2 L
-
! L/ k" _: b9 n8 f8 E8 z0 J0 H/ B - #define OLED_SH1108_SCL_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, OLED_SH1108_D0_PIN) & W9 [ N: l1 V+ O
- #define OLED_SH1108_SCL_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, OLED_SH1108_D0_PIN)
2 V2 z. V$ z. t3 G3 C9 b. f. h - #define OLED_SH1108_SI_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, OLED_SH1108_D1_PIN) ' V, F- S9 v: ^
- #define OLED_SH1108_SI_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, OLED_SH1108_D1_PIN)
5 l( }; A+ v3 L( G -
, T. D6 [5 c- o. K- d - #define OLED_SH1108_D2_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_2)
# A" x g% |+ p5 Y& _ - #define OLED_SH1108_D2_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_2)
+ [- r) R: H* E4 N2 O - / F0 h3 G5 T- l. T, o
- #define OLED_SH1108_D3_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_3) 0 m/ m! Q* m3 e& r! n
- #define OLED_SH1108_D3_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_3)
) d$ |7 E. S' q& O - 4 D9 `6 ~$ l$ I3 X
- #define OLED_SH1108_D4_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_4) " r8 m, @: Y- O9 |
- #define OLED_SH1108_D4_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_4)
3 d P+ o9 r! F: k -
: _& z. k* h: ]$ j2 M. u+ i - #define OLED_SH1108_D5_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_5)
1 Z: `. Q! O0 g7 P% ~ - #define OLED_SH1108_D5_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_5)2 y r* Q. m6 A J& r3 V8 j, A
-
, B* |7 i, N% Y5 A5 v7 G" d6 A - #define OLED_SH1108_D6_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_6)
9 F- ]4 v1 M% `* K5 G& Z. Y5 M2 G - #define OLED_SH1108_D6_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_6): R+ X' Z8 ]7 j" s) b9 ]
-
" F' U2 m- K- a4 m7 E - #define OLED_SH1108_D7_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_7)
6 H: v2 b2 M( L# | - #define OLED_SH1108_D7_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_7)
复制代码
6 Q# c" @8 _! O. j% M+ f. E这里为了速度将PC口单独连接到OLED的数据线上,这样可以加快操作OLED的读写速度。0 ]) C" B4 J3 w9 t5 a
y) I Y: |( P( ~9 w7 O
测试main函数,实现了OLED显示汉字和字符串,部分图案显示没有测试- /******************************************************************************. y' W4 @5 y; j2 @/ F
- * 函数名称: main(); P e. b1 Q( o) h9 C5 M
- * 功能描述: OLED测试 H, l' s$ L1 b- I5 j; v* f; r7 ?$ V
- * 输入参数: 无
5 v7 N4 V6 V0 O9 q* y - * 输出参数: 无
$ G* V& y' }& w6 d+ h - * 返 回 值: 无
/ |5 O! B3 O) O: q3 I) W8 J - * 其它说明: p3 Z; a& N2 C' _$ V
- * 修改日期 版本号 修改人 修改内容7 ^3 h$ N% u3 i
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* L8 O6 j2 c$ S7 ^4 v4 V n - * 2013/02/22 V1.0.0.0
( k k, p( ?! G T - ******************************************************************************/
* B1 u0 N+ X& O9 R1 M, F% Z - INT32S main (void)
+ J: V. [# W' S2 u1 O) o) t& [ n - {) F) W3 h) r6 Y5 T+ X6 [
- BSP_Init(); // 系统初始化
. P J- g9 B; Q# E - oled_sh1108_init_program();
- B7 F! u. x( ?0 C - OLED_ShowChinese(1, 20, 4, 1);//主
7 I6 H8 o6 ~6 K1 ^1 U1 f1 H | - OLED_ShowChinese(93, 20, 5, 1);//副# }! {" }+ C9 R; {9 ^5 t& A7 `
- while(1)
, @/ a# [( ~5 G7 k - {
% ?& U2 X! k6 p) P - sprintf((char*)oled_display_buf," ");
* Z: R4 [; p/ ?- A: S! l; A - oled_sh1108_show_string(61, 5, oled_display_buf, 12); / j, r! |+ ^% K/ B* O1 X2 U7 B) [2 c' l
- sprintf((char*)oled_display_buf,"%4.4d-%2.2d-%2.2d", 2022, 1, 1);7 T& ~: i" g! T% r, o. e
- oled_sh1108_show_string(1, 5, oled_display_buf, 12); {7 M# n7 G, H) a X
- sprintf((char*)oled_display_buf,"%2.2d:%2.2d:%2.2d", 10, 10, 10);
' W: R0 n. d( a f - oled_sh1108_show_string(105, 5, oled_display_buf, 12);
$ M9 _; c/ S1 [: p5 F - oled_sh1108_refresh_gram();# o8 d+ |5 r( ?+ n. h4 j4 u
- }
7 P! P2 |; ?% v% j$ V8 v -
6 e- E. V$ L' ?+ A% A9 ~ - return (0);! u3 o/ [/ F6 X) ^# J7 ?8 x& L
- }
复制代码
0 L9 q% @! t% v; Q- |8 e+ [ D9 L4 s# Y$ ?
STM32内部缓存定义,每次更改该数据,一定时间,或者及时将该数据刷新
- B3 W# Z0 ]4 {& E' c4 v8 }- /* OLED的显存2 _6 T, `& D+ ^/ R, k1 q
- * 存放格式如下.
3 @. X/ M, R0 G5 }1 ] - * [0]0 1 2 3 ... 127
0 n0 k3 G2 E# C% X; C - * [1]0 1 2 3 ... 127 * g) E0 R- Y. P) @( i
- * [2]0 1 2 3 ... 127
* v% x$ B* m: {& p) a - *# L" s+ q! r3 |' R1 |9 O
- * [19]0 1 2 3 ... 127
[/ Q+ i) |9 ?! D - */
6 D; f, L+ M5 [: z: L4 p# c - static unsigned char OLED_GRAM[128][20];
复制代码 ! I0 V8 y8 X5 `( R" C! u3 g
刷新缓存到OLED,该函数实现将缓存数据刷新到OLED
+ v- L9 b. v x1 [: h- /******************************************************************************
6 @1 p, R* ^! w4 S, U0 X! P+ k Y* I - * 函数名称: oled_sh1108_all_screen()
) Y: w* w* @! G+ o4 B9 |- |( Y' t- R - * 功能描述: 更新显存到LCD
" ]2 O* u" J) b8 U$ V& l6 _ - * 输入参数: 无
2 h$ k; g! t8 U0 c% V - * 输出参数: 无
( ]+ L! I! o* N; x; P! E - * 返 回 值: 无1 Q# Z, z) N% M; x& M9 m# x
- * 其它说明: 2 q3 Q6 R9 Q- T6 y
- * 修改日期 版本号 修改人 修改内容
/ e* v# D; E9 r& S- b3 I - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
" R0 g& H2 E1 a - * 2013/02/22 V1.0.0.0 0 W; p! k$ p! R# ]4 {3 p
- ******************************************************************************/
0 H; h/ A9 k# W7 T7 T. D4 c( B - void oled_sh1108_refresh_gram(void)
2 ^7 t" w4 ^3 L/ O% J5 I - {
! o; K7 t, \/ C5 t+ X- _) X0 r2 A - unsigned char i, j;
% `* y8 L5 f& n4 U$ F7 [8 R - // for(i = 0 ; i < 8; i++)
3 @7 X) c' a4 J/ ?- W( d; | - // { 2 N! F& q1 D) i' c9 \, S8 P! l
- // OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
" X8 ^5 [/ u& g3 r( d } - // OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
9 n( l6 Q! Q8 m# R0 M - // OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址 6 F' v) r3 O% e% U; n+ Q6 F" U
- // for(n=0;n<128;n++)) u7 H, t4 @0 }3 q* V
- // OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA); , I0 ~1 p% b5 k4 v/ A7 @% ?8 V
- // }
/ _5 a0 _0 M5 E6 y - for(i = 0; i < 20; i++)
5 ^ I$ c$ u/ G/ U - {; W! p) i& `2 v
- oled_sh1108_write_c(0xb0);
$ p* x: c, b' n' F: `9 W7 Y9 P - oled_sh1108_write_c(0x00 + i);! x1 g/ n& |0 Q5 ^ C
- 6 e4 J9 o3 R6 s
- oled_sh1108_write_c(0x00);- y) i$ H1 ~! m4 y
- oled_sh1108_write_c(0x11);
4 d: Y3 A9 }5 @" R0 _3 [ - for(j = 0; j < 128; j++)" l) j( u# ]+ _- {1 o
- {
0 Q( R6 d) e6 ~ t1 }) b - oled_sh1108_write_d(OLED_GRAM[j][i]);1 k$ a( \+ L& v. U
- }+ e& I$ U3 ^/ {" T9 V9 G( y3 [6 {
- }
1 g( @, N: q: J; N4 {; t5 `' l$ `7 l - }
复制代码
' E0 L+ ^9 x' V5 J' x———————————————— Q* k- r. P8 _* x' z( B" l
版权声明:大牛攻城狮
z; M- }) O* o H2 F. r8 a7 e2 r! S4 x( g. }. L" Y# ^" A7 ~
* t& H7 i# S' x+ S7 B9 x6 r
|