OLED显示屏(0.96寸 IIC协议)

目录

一、OLED概述

二、OLED引脚说明

三、IIC简要说明

1.起始条件

2. 发送从设备地址

3. 数据传输

写操作

读操作

4. 停止条件

四、示例代码

1.codetab.h

2.oled_i2c.h

3.oled_i2c.c

4.main.c


一、OLED概述

        0.96 寸 OLED 显示屏是一种高度集成的微型显示模块,以其紧凑尺寸、高对比度和低功耗特性,成为嵌入式系统、可穿戴设备及小型电子项目的理想选择。

二、OLED引脚说明

引脚说明
VCC电源正,一般接3.3V或5V均可
GND电源负,接地
SCL时钟线,接自己定义的IIC接口的时钟引脚(SCL)
SDA数据线,接自己定义的IIC接口的数据引脚(SDA)

          连接示例:以STM32F103C8T6单片机的I2C1为例,接口是PB6 (SCL) 和 PB7(SDA),                                         将VCC接到任意3.3V接口,GND接任意地,SCL接到PB6,SDA接到SDA。

三、IIC简要说明

        I2C(Inter - Integrated Circuit),又称 IIC,是一种串行通信协议,其通讯流程如下。

1.起始条件

         I2C 总线由两条线组成:串行数据线(SDA)和串行时钟线(SCL)。在进行数据传输之前,主设备需要发送起始条件。

        当 SCL 为高电平时,SDA 由高电平变为低电平,此时表示起始条件已发送,意味着数据传输即将开始。

2. 发送从设备地址

        起始条件发送后,主设备会发送从设备的 7 位或 10 位地址,同时还会发送一位读写位(R/W)。

        若读写位为 0,表示主设备要向从设备写入数据;若读写位为 1,表示主设备要从从设备读取数据。

        从设备接收到地址后,会将接收到的地址与自己的地址进行比较。如果匹配,从设备会在第 9 个时钟周期(ACK 周期)拉低 SDA 线,发送一个应答信号(ACK),表示已准备好进行数据传输。

3. 数据传输

写操作

        主设备在从设备应答后,开始向从设备发送数据字节。每发送一个字节,主设备会释放 SDA 线,等待从设备在第 9 个时钟周期发送应答信号。

        从设备发送 ACK 表示已成功接收数据,主设备可以继续发送下一个字节;若从设备发送非应答信号(NACK),则表示数据接收失败或操作完成。

读操作

        主设备发送从设备地址和读信号后,从设备开始向主设备发送数据字节。每发送一个字节,主设备需要在第 9 个时钟周期发送应答信号。

        主设备发送 ACK 表示希望继续接收数据,从设备会继续发送下一个字节;若主设备发送 NACK,则表示数据接收完成。

4. 停止条件

        当数据传输完成后,主设备需要发送停止条件来结束本次通信。

        当 SCL 为高电平时,SDA 由低电平变为高电平,此时表示停止条件已发送,数据传输结束。

四、示例代码

1.codetab.h

 说明:此为oled库,用于显示文字等,可用字模软件生成想要的字库等去修改。

 字模软件获取链接:
 链接: https://pan.baidu.com/s/1yLbT8btyu1GmaB3AruNGew?pwd=2imt

#ifndef __CODETAB_H
#define __CODETAB_H 	  

typedef struct
{
	char name[3];
	char dat[32];
}chinese;

//常用ASCII表
//偏移量32
//ASCII字符集
//偏移量32
//大小:12*6
/************************************6*8的点阵************************************/
const unsigned char F6x8[][6] =		
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// #
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $
0x00, 0x62, 0x64, 0x08, 0x13, 0x23,// %
0x00, 0x36, 0x49, 0x55, 0x22, 0x50,// &
0x00, 0x00, 0x05, 0x03, 0x00, 0x00,// '
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,// (
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,// )
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,// *
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,// +
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,// ,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08,// -
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,// .
0x00, 0x20, 0x10, 0x08, 0x04, 0x02,// /
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 2
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,// 3
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,// 4
0x00, 0x27, 0x45, 0x45, 0x45, 0x39,// 5
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
0x00, 0x01, 0x71, 0x09, 0x05, 0x03,// 7
0x00, 0x36, 0x49, 0x49, 0x49, 0x36,// 8
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,// 9
0x00, 0x00, 0x36, 0x36, 0x00, 0x00,// :
0x00, 0x00, 0x56, 0x36, 0x00, 0x00,// ;
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,// <
0x00, 0x14, 0x14, 0x14, 0x14, 0x14,// =
0x00, 0x00, 0x41, 0x22, 0x14, 0x08,// >
0x00, 0x02, 0x01, 0x51, 0x09, 0x06,// ?
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,// @
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,// A
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,// B
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,// C
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,// D
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,// E
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,// F
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,// G
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,// H
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,// I
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,// J
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,// K
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,// L
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,// M
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,// N
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,// O
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,// P
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,// R
0x00, 0x46, 0x49, 0x49, 0x49, 0x31,// S
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,// T
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,// U
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,// V
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,// W
0x00, 0x63, 0x14, 0x08, 0x14, 0x63,// X
0x00, 0x07, 0x08, 0x70, 0x08, 0x07,// Y
0x00, 0x61, 0x51, 0x49, 0x45, 0x43,// Z
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// [
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,// 55
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,// ]
0x00, 0x04, 0x02, 0x01, 0x02, 0x04,// ^
0x00, 0x40, 0x40, 0x40, 0x40, 0x40,// _
0x00, 0x00, 0x01, 0x02, 0x04, 0x00,// '
0x00, 0x20, 0x54, 0x54, 0x54, 0x78,// a
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,// b
0x00, 0x38, 0x44, 0x44, 0x44, 0x20,// c
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,// d
0x00, 0x38, 0x54, 0x54, 0x54, 0x18,// e
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,// f
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,// g
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,// h
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,// i
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,// j
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,// k
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,// l
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,// m
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,// n
0x00, 0x38, 0x44, 0x44, 0x44, 0x38,// o
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,// p
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,// q
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,// r
0x00, 0x48, 0x54, 0x54, 0x54, 0x20,// s
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,// t
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,// u
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,// v
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,// w
0x00, 0x44, 0x28, 0x10, 0x28, 0x44,// x
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,// y
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z
0x14, 0x14, 0x14, 0x14, 0x14, 0x14,// horiz lines
};
/****************************************8*16的点阵************************************/
const unsigned char F8X16[]=	  
{
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0
  0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1
  0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2
  0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3
  0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4
  0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5
  0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6
  0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 7
  0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8
  0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9
  0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10
  0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14
  0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15
  0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16
  0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17
  0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18
  0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19
  0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20
  0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21
  0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22
  0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23
  0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24
  0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25
  0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26
  0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27
  0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28
  0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29
  0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30
  0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31
  0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32
  0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33
  0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34
  0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35
  0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36
  0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37
  0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38
  0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39
  0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40
  0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41
  0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42
  0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43
  0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44
  0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45
  0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46
  0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47
  0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48
  0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49
  0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50
  0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51
  0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52
  0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53
  0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54
  0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55
  0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56
  0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57
  0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58
  0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59
  0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60
  0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61
  0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63
  0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 64
  0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65
  0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66
  0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67
  0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68
  0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69
  0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70
  0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71
  0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72
  0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73
  0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74
  0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75
  0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76
  0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77
  0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78
  0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79
  0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80
  0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81
  0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82
  0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83
  0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84
  0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85
  0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86
  0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87
  0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88
  0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89
  0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90
  0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91
  0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92
  0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93
  0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
};

chinese Hzk[]={
"空",{/* 空[0xBFD5]   16x16 */
0x10,0x0C,0x84,0x44,0x24,0x34,0x05,0x06,0x04,0x14,0x24,0x64,0xC4,0x14,0x0C,0x00,
0x40,0x40,0x42,0x42,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0x42,0x60,0x40,0x00,
},"气",{/* 气[0xC6F8]   16x16 */
0x40,0x20,0x58,0x47,0x54,0x54,0x54,0x54,0x54,0x54,0xD4,0x14,0x06,0x04,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x40,0x80,0x70,0x00,
},"温",{/* 温[0xCEC2]   16x16 */
0x10,0x22,0x64,0x0C,0x80,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFF,0x02,0x00,0x00,
0x04,0x04,0xFE,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,
},"度",{/* 度[0xB6C8]   16x16 */
0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0xA5,0xA6,0xA4,0xFC,0x24,0x34,0x26,0x04,0x00,
0x40,0x20,0x9F,0x80,0x42,0x42,0x26,0x2A,0x12,0x2A,0x26,0x42,0x40,0xC0,0x40,0x00,
},"上",{/* 上[0xC9CF]   16x16 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x20,0x20,0x20,0x30,0x20,0x00,0x00,0x00,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x60,0x40,0x00,
},"限",{/* 限[0xCFDE]   16x16 */
0x00,0xFE,0x02,0x22,0xDA,0x06,0x00,0xFE,0x92,0x92,0x92,0x92,0xFF,0x02,0x00,0x00,
0x00,0xFF,0x08,0x10,0x08,0x07,0x00,0xFF,0x42,0x24,0x08,0x14,0x22,0x61,0x20,0x00,
},"下",{/* 下[0xCFC2]   16x16 */
0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x02,0x22,0x42,0x82,0x82,0x02,0x03,0x02,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
},"湿",{/* 湿[0xCAAA]   16x16 */
0x10,0x22,0x64,0x0C,0x80,0xFE,0x92,0x92,0x92,0x92,0x92,0x92,0xFF,0x02,0x00,0x00,
0x04,0x04,0xFE,0x41,0x44,0x48,0x50,0x7F,0x40,0x40,0x7F,0x50,0x48,0x64,0x40,0x00,
},"光",{/* 光[0xB9E2]   16x16 */
0x40,0x40,0x42,0x44,0x58,0xC0,0x40,0x7F,0x40,0xC0,0x50,0x48,0x46,0x64,0x40,0x00,
0x00,0x80,0x40,0x20,0x18,0x07,0x00,0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x70,0x00,
},"强",{/* 强[0xC7BF]   16x16 */
0x02,0xE2,0x22,0x22,0x7F,0x02,0x80,0xBE,0x92,0x92,0xF2,0x92,0x92,0xBF,0x82,0x00,
0x20,0x43,0x82,0x42,0x3E,0x00,0x4F,0x44,0x44,0x44,0x7F,0x44,0x44,0x64,0xCF,0x00,
},"土",{/* 土[0xCDC1]   16x16 */
0x00,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x40,0x40,0x40,0x40,0x60,0x40,0x00,0x00,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x60,0x40,0x00,
},"壤",{/* 壤[0xC8C0]   16x16 */
0x10,0x10,0xFF,0x10,0x10,0x82,0xBA,0xEA,0xBA,0x83,0xBA,0xEA,0xBA,0x83,0x02,0x00,
0x08,0x18,0x0F,0x04,0x4C,0x48,0x2A,0xFF,0x8A,0x1A,0x2A,0x2F,0x5A,0xC8,0x48,0x00,
},"二",{/* 二[0xB6FE]   16x16 */
0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x0C,0x08,0x00,0x00,0x00,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x10,0x00,
},"氧",{/* 氧[0xD1F5]   16x16 */
0x20,0x10,0x2C,0x23,0x6A,0xAA,0x2A,0xAA,0x6A,0x2A,0x2A,0x2A,0xEA,0x02,0x00,0x00,
0x00,0x10,0x11,0x15,0x15,0x15,0xFF,0x15,0x15,0x15,0x11,0x10,0x3F,0x40,0x30,0x00,
},"化",{/* 化[0xBBAF]   16x16 */
0x80,0x40,0x20,0xF8,0x07,0x00,0x00,0x00,0xFF,0x40,0x20,0x10,0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0xFF,0x00,0x04,0x02,0x01,0x3F,0x40,0x40,0x40,0x40,0x40,0x70,0x00,
},"碳",{/* 碳[0xCCBC]   16x16 */
0x04,0x84,0xE4,0x9C,0x86,0x84,0x40,0x5C,0xF0,0x50,0x5F,0x50,0x50,0x5C,0x40,0x00,
0x01,0x00,0x7F,0x20,0x20,0x7F,0x88,0x46,0x25,0x18,0x07,0x18,0x64,0xC2,0x40,0x00,
},"风",{/* 风[0xB7E7]   16x16 */
0x00,0x00,0xFE,0x02,0x0A,0x12,0x62,0x82,0x62,0x1A,0x02,0xFF,0x02,0x00,0x00,0x00,
0x80,0x40,0x3F,0x20,0x10,0x08,0x06,0x01,0x06,0x18,0x00,0x3F,0x40,0x80,0xE0,0x00,
},"扇",{/* 扇[0xC9C8]   16x16 */
0x00,0x00,0xFC,0x24,0x24,0x24,0x25,0x26,0x24,0x24,0x24,0x24,0x3E,0x84,0x00,0x00,
0x40,0x20,0x1F,0x21,0x15,0x49,0x81,0x7F,0x00,0x21,0x15,0x49,0x81,0x7F,0x01,0x00,
},"报",{/* 报[0xB1A8]   16x16 */
0x10,0x10,0x10,0xFF,0x90,0x50,0x00,0xFE,0x82,0x82,0x92,0xA2,0x9F,0x02,0x00,0x00,
0x02,0x42,0x81,0x7F,0x00,0x00,0x00,0xFF,0x22,0x14,0x08,0x16,0x21,0x60,0x20,0x00,
},"警",{/* 警[0xBEAF]   16x16 */
0x80,0x92,0x8A,0xBF,0xAA,0xBB,0xCA,0xFA,0x84,0xA7,0xAA,0x92,0xAE,0xE2,0xA0,0x00,
0x00,0x00,0x00,0xEA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xEA,0x00,0x00,0x00,0x00,
},"水",{/* 水[0xCBAE]   16x16 */
0x00,0x20,0x20,0x20,0x20,0xE0,0x00,0xFF,0xC0,0x40,0x20,0x10,0x18,0x00,0x00,0x00,
0x20,0x10,0x08,0x04,0x03,0x40,0x80,0x7F,0x00,0x01,0x02,0x04,0x08,0x18,0x08,0x00,
},"泵",{/* 泵[0xB1C3]   16x16 */
0x42,0x42,0x22,0x12,0xFA,0x96,0x92,0x92,0x92,0x92,0x92,0xFA,0x12,0x03,0x02,0x00,
0x00,0x44,0x44,0x24,0x15,0x0C,0x80,0xFF,0x04,0x08,0x14,0x22,0x23,0x60,0x20,0x00,
},"增",{/* 增[0xD4F6]   16x16 */
0x20,0x20,0xFF,0x20,0x20,0xF0,0x11,0x52,0x14,0xF0,0x14,0x52,0x11,0xF8,0x10,0x00,
0x08,0x18,0x0F,0x04,0x04,0x01,0xFD,0x55,0x55,0x55,0x55,0x55,0xFF,0x05,0x00,0x00,
},"降",{/* 降[0xBDB5]   16x16 */
0x00,0xFE,0x02,0x22,0xDA,0x06,0x88,0x44,0x57,0xA4,0x54,0x4C,0x84,0x80,0x80,0x00,
0x00,0xFF,0x08,0x10,0x08,0x07,0x10,0x1E,0x12,0xFF,0x12,0x12,0x18,0x11,0x00,0x00,
},"控",{/* 控[0xBFD8]   16x16 */
0x10,0x10,0x10,0xFF,0x90,0x50,0x0C,0x44,0x24,0x15,0x06,0x14,0x24,0x54,0x0C,0x00,
0x02,0x42,0x81,0x7F,0x00,0x40,0x42,0x42,0x42,0x42,0x7E,0x42,0x43,0x62,0x40,0x00,
},"制",{/* 制[0xD6C6]   16x16 */
0x40,0x60,0x5E,0x48,0x48,0xFF,0x48,0x4C,0x68,0x40,0xF8,0x00,0x00,0xFF,0x00,0x00,
0x00,0x00,0x3F,0x01,0x01,0xFF,0x11,0x21,0x1F,0x00,0x07,0x40,0x80,0x7F,0x00,0x00,
},"火",{/* 火[0xBBF0]   16x16 */
0x00,0x00,0x80,0x70,0x00,0x00,0x00,0xFF,0x00,0x80,0x40,0x20,0x30,0x00,0x00,0x00,
0x00,0x81,0x40,0x20,0x10,0x0C,0x03,0x00,0x03,0x0C,0x10,0x20,0x40,0xC0,0x40,0x00,
},"自",{/* 自[0xD7D4]   16x16 */
0x00,0x00,0x00,0xF8,0x48,0x4C,0x4A,0x49,0x48,0x48,0x48,0xFC,0x08,0x00,0x00,0x00,
0x00,0x00,0x00,0xFF,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0xFF,0x00,0x00,0x00,0x00,
},"动",{/* 动[0xB6AF]   16x16 */
0x20,0x24,0x24,0xE4,0x26,0x34,0x20,0x10,0x10,0xFF,0x10,0x10,0x10,0xF8,0x10,0x00,
0x08,0x1C,0x0B,0x08,0x08,0x8A,0x4C,0x30,0x0C,0x03,0x40,0x80,0x40,0x3F,0x00,0x00,
},"模",{/* 模[0xC4A3]   16x16 */
0x10,0x10,0xD0,0xFF,0x94,0x14,0xE4,0xBF,0xA4,0xA4,0xA4,0xBF,0xF4,0x26,0x04,0x00,
0x04,0x03,0x00,0xFF,0x08,0x89,0x8B,0x4A,0x2A,0x1E,0x2A,0x2A,0x4B,0xC8,0x48,0x00,
},"式",{/* 式[0xCABD]   16x16 */
0x10,0x10,0x90,0x90,0x90,0x90,0x90,0x10,0xFF,0x10,0x12,0x14,0x10,0x18,0x10,0x00,
0x00,0x20,0x60,0x20,0x1F,0x10,0x10,0x08,0x01,0x06,0x18,0x20,0x40,0x80,0x70,0x00,
},"手",{/* 手[0xCAD6]   16x16 */
0x00,0x04,0x24,0x24,0x24,0x24,0x24,0xFC,0x22,0x22,0x22,0x33,0x22,0x00,0x00,0x00,
0x02,0x02,0x02,0x02,0x02,0x42,0x82,0x7F,0x02,0x02,0x02,0x02,0x02,0x03,0x02,0x00,
},"焰",{/* 焰[0xD1E6]   16x16 */
0x80,0x70,0x00,0xFF,0x10,0x08,0xD0,0x48,0x27,0x04,0x44,0x54,0x4C,0xE4,0x40,0x00,
0x40,0x20,0x18,0x07,0x08,0x30,0xFF,0x44,0x44,0x40,0x44,0x44,0x44,0xFF,0x00,0x00,
},"℃",{/* ℃[0xA1E6]   16x16 */
0x00,0x06,0x09,0x09,0xE6,0xF0,0x18,0x08,0x08,0x08,0x18,0x30,0x78,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x07,0x0F,0x18,0x30,0x20,0x20,0x20,0x10,0x08,0x00,0x00,0x00,
},"检",{/* 检[0xBCEC]   16x16 */
0x10,0x10,0xD0,0xFF,0x10,0x50,0x20,0x50,0x4C,0x43,0x4C,0x50,0x20,0x60,0x20,0x00,
0x04,0x03,0x00,0xFF,0x41,0x42,0x42,0x5C,0x40,0x5F,0x40,0x50,0x4E,0x64,0x40,0x00,
},"测",{/* 测[0xB2E2]   16x16 */
0x10,0x22,0x6C,0x00,0x80,0xFC,0x04,0xF4,0x04,0xFE,0x04,0xF8,0x00,0xFE,0x00,0x00,
0x04,0x04,0xFE,0x01,0x40,0x27,0x10,0x0F,0x10,0x67,0x00,0x47,0x80,0x7F,0x00,0x00,
},"到",{/* 到[0xB5BD]   16x16 */
0x00,0x62,0x52,0x4A,0xC6,0x42,0x52,0x63,0xC2,0x00,0xF8,0x00,0x00,0xFF,0x00,0x00,
0x40,0x42,0x42,0x42,0x7F,0x22,0x23,0x22,0x20,0x00,0x0F,0x40,0x80,0x7F,0x00,0x00,
},"没",{/* 没[0xC3BB]   16x16 */
0x10,0x21,0x62,0x06,0x00,0x40,0xA0,0x9E,0x82,0x82,0x82,0x9F,0xA2,0x20,0x20,0x00,
0x04,0x04,0xFE,0x01,0x80,0x80,0x41,0x46,0x28,0x10,0x28,0x46,0xC1,0x40,0x40,0x00,
},"有",{/* 有[0xD3D0]   16x16 */
0x04,0x04,0x04,0x84,0xE4,0x3C,0x27,0x24,0x24,0x24,0x24,0xF4,0x24,0x06,0x04,0x00,
0x04,0x02,0x01,0x00,0xFF,0x09,0x09,0x09,0x09,0x49,0x89,0x7F,0x00,0x00,0x00,0x00,
},"照",{/* 照[0xD5D5]   16x16 */
0x00,0xFE,0x42,0x42,0x42,0xFE,0x00,0x42,0xB2,0x8E,0x82,0xA2,0xC2,0xBF,0x02,0x00,
0x80,0x4F,0x68,0x08,0x08,0x2F,0xC0,0x00,0x2F,0xC8,0x08,0x08,0x28,0x4F,0xC0,0x00,
},"值",{/* 值[0xD6B5]   16x16 */
0x80,0x40,0x20,0xF8,0x07,0x04,0xE4,0xA4,0xA4,0xBF,0xA4,0xA4,0xF6,0x24,0x00,0x00,
0x00,0x00,0x00,0xFF,0x40,0x40,0x7F,0x4A,0x4A,0x4A,0x4A,0x4A,0x7F,0x40,0x40,0x00,
},
}; 

#endif


2.oled_i2c.h

/**
 * 0.96寸OLED
 */
// 头文件保护,防止头文件被重复包含
#ifndef __OLED_I2C_H
#define __OLED_I2C_H			  	 
// 包含STM32F10x系列的标准库头文件
#include "stm32f10x.h"
// 包含标准库头文件
#include "stdlib.h"	    	
// 定义OLED的模式
#define OLED_MODE 0
// 定义一个大小为8的值
#define SIZE 8
// 定义X轴低电平设置的寄存器值
#define XLevelL		0x00
// 定义X轴高电平设置的寄存器值
#define XLevelH		0x10
// 定义OLED显示屏的最大列数
#define Max_Column	128
// 定义OLED显示屏的最大行数
#define Max_Row		64
// 定义OLED显示屏的亮度值,这里设置为最大亮度
#define	Brightness	0xFF 
// 定义X轴的宽度,即显示屏的横向像素数
#define X_WIDTH 	128
// 定义Y轴的宽度,即显示屏的纵向像素数
#define Y_WIDTH 	64	    						  

//-----------------SCL-----------------------
// 定义OLED的SCL(时钟线)所连接的GPIO端口为GPIOB
#define OLED_GPIO_PORT_SCL        GPIOB
// 定义SCL所连接的GPIO端口的时钟使能位,用于开启GPIOB的时钟
#define OLED_GPIO_PORT_CLK_SCL    RCC_APB2Periph_GPIOB
// 定义SCL所连接的GPIO引脚为GPIOB的第6引脚
#define OLED_PIN_SCL            GPIO_Pin_6
//-----------------SDA-----------------------
// 定义OLED的SDA(数据线)所连接的GPIO端口为GPIOB
#define OLED_GPIO_PORT_SDA        GPIOB
// 定义SDA所连接的GPIO端口的时钟使能位,用于开启GPIOB的时钟
#define OLED_GPIO_PORT_CLK_SDA    RCC_APB2Periph_GPIOB
// 定义SDA所连接的GPIO引脚为GPIOB的第7引脚
#define OLED_PIN_SDA            GPIO_Pin_7

// 定义SCL和SDA引脚的组合,方便后续操作
#define OLED_PINS             (OLED_PIN_SCL | OLED_PIN_SDA)

// 定义一个宏,用于将SCL引脚置为低电平
#define OLED_SCLK_Clr() GPIO_ResetBits(OLED_GPIO_PORT_SCL,OLED_PIN_SCL)//SCL
// 定义一个宏,用于将SCL引脚置为高电平
#define OLED_SCLK_Set() GPIO_SetBits(OLED_GPIO_PORT_SCL,OLED_PIN_SCL)

// 定义一个宏,用于将SDA引脚置为低电平
#define OLED_SDIN_Clr() GPIO_ResetBits(OLED_GPIO_PORT_SDA,OLED_PIN_SDA)//SDA
// 定义一个宏,用于将SDA引脚置为高电平
#define OLED_SDIN_Set() GPIO_SetBits(OLED_GPIO_PORT_SDA,OLED_PIN_SDA)

// 定义一个宏,表示写入的是命令
#define OLED_CMD  0	//写命令
// 定义一个宏,表示写入的是数据
#define OLED_DATA 1	//写数据

//OLED控制用函数

// 向OLED写入一个字节的数据,可以是命令或数据
void OLED_WR_Byte(unsigned dat,unsigned cmd);  
// 打开OLED显示屏
void OLED_Display_On(void);
// 关闭OLED显示屏
void OLED_Display_Off(void);	   							   		    
// 初始化OLED显示屏
void OLED_Init(void);
// 清空OLED显示屏的显示内容
void OLED_Clear(void);
// 在指定坐标(x, y)处绘制一个点,t表示点的状态(点亮或熄灭)
void OLED_DrawPoint(u8 x,u8 y,u8 t);
// 在指定区域(x1, y1)到(x2, y2)内填充指定状态的点
void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot);
// 在指定坐标(x, y)处显示一个字符,Char_Size表示字符的大小
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size);
// 在指定坐标(x, y)处显示一个数字,num为要显示的数字,len为数字的长度,size为数字的大小
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size);
// 在指定坐标(x, y)处显示一个字符串,p为字符串指针,Char_Size表示字符的大小
void OLED_ShowString(u8 x,u8 y, u8 *p,u8 Char_Size);	 
// 设置OLED显示屏的显示位置
void OLED_Set_Pos(unsigned char x, unsigned char y);
// 在指定坐标(x, y)处显示一个中文字符,no为中文字符的编号
void OLED_ShowCHinese(u8 x,u8 y,u8 no);
// 在指定区域(x0, y0)到(x1, y1)内显示一幅位图,BMP为位图数据数组
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]);
// 延时函数,延时时间为Del_50ms个50ms
void Delay_50ms(unsigned int Del_50ms);
// 延时函数,延时时间为Del_1ms个1ms
void Delay_1ms(unsigned int Del_1ms);
// 用指定的数据填充整个显示屏
void fill_picture(unsigned char fill_Data);
// 显示一幅图片,具体图片内容需结合代码实现
void Picture(void);
// I2C通信的起始信号函数
void IIC_Start(void);
// I2C通信的停止信号函数
void IIC_Stop(void);
// 向I2C总线写入一个命令
void Write_IIC_Command(unsigned char IIC_Command);
// 向I2C总线写入一个数据
void Write_IIC_Data(unsigned char IIC_Data);
// 向I2C总线写入一个字节
void Write_IIC_Byte(unsigned char IIC_Byte);
// 在指定坐标(x, y)处显示一段文本,str为文本指针,flag表示显示标志
void OLED_ShowText(u8 x,u8 y,u8* str,u8 flag);
// 等待I2C总线的应答信号
void IIC_Wait_Ack(void);
// 结束头文件保护
#endif

3.oled_i2c.c

#include "oled_i2c.h"
#include "stdlib.h"
#include "codetab.h"  	 // 包含字符编码表(如ASCII字符的字模数据)
#include "delay.h"        // 包含延时函数(用于I2C时序和OLED初始化)
#include "string.h"       // 包含字符串操作函数(用于文本处理)

// OLED显存定义(64行×128列,按页存储,每页8行)
// 显存结构:8个页(0~7),每页128列,对应OLED的64行(0~63行,每页8行)
// [页0] 行0~7  [页1] 行8~15  ...  [页7] 行56~63
// 每个页内的列地址范围:0~127

/**********************************************
 * I2C 通信底层时序函数(软件模拟I2C)
 **********************************************/

/**
 * @brief 产生I2C起始信号
 * @note 时序:当SCL为高电平时,SDA由高变低,开始数据传输
 */
void IIC_Start(void)
{
    OLED_SCLK_Set();  // 先拉高时钟线
    OLED_SDIN_Set();  // 拉高数据线(确保起始前SDA为高)
    OLED_SDIN_Clr();  // 在SCL高电平时拉低SDA,产生起始信号
    OLED_SCLK_Clr();  // 拉低时钟线,准备发送数据
}

/**
 * @brief 产生I2C停止信号
 * @note 时序:当SCL为高电平时,SDA由低变高,结束数据传输
 */
void IIC_Stop(void)
{
    OLED_SCLK_Set();  // 拉高时钟线
    OLED_SDIN_Clr();  // 先拉低数据线(确保停止前SDA为低)
    OLED_SDIN_Set();  // 在SCL高电平时拉高SDA,产生停止信号
}

/**
 * @brief 等待从设备应答
 * @note 标准I2C应检测SDA状态,此处仅模拟时序(拉低SCL等待)
 */
void IIC_Wait_Ack(void)
{
    OLED_SCLK_Set();  // 拉高时钟线,从设备在此时返回应答信号
    OLED_SCLK_Clr();  // 拉低时钟线,结束应答等待(实际应用需添加SDA检测)
}

/**
 * @brief 向I2C总线发送一个字节数据(高位先行)
 * @param [in] IIC_Byte 待发送的字节数据
 */
void Write_IIC_Byte(unsigned char IIC_Byte)
{
    unsigned char i;
    unsigned char m, da;
    da = IIC_Byte;          // 暂存数据
    OLED_SCLK_Clr();       // 拉低时钟线,准备开始位传输
    
    for (i = 0; i < 8; i++) {         // 逐位发送8位数据
        m = da;
        m = m & 0x80;                  // 提取最高位(第7位)
        if (m == 0x80) OLED_SDIN_Set(); // 最高位为1时,置高SDA
        else OLED_SDIN_Clr();          // 最高位为0时,置低SDA
        
        da = da << 1;                  // 左移一位,准备下一位
        OLED_SCLK_Set();               // 拉高时钟线,锁存数据
        OLED_SCLK_Clr();               // 拉低时钟线,准备下一位传输
    }
}

/**
 * @brief 向OLED发送I2C命令(含从机地址0x78)
 * @param [in] IIC_Command 待发送的命令字节
 */
void Write_IIC_Command(unsigned char IIC_Command)
{
    IIC_Start();                  // 发送起始信号
    Write_IIC_Byte(0x78);         // 从机地址(0x78:7位地址,最低位0表示写操作)
    IIC_Wait_Ack();               // 等待应答
    Write_IIC_Byte(0x00);         // 命令标识(D/C#=0,区分命令和数据)
    IIC_Wait_Ack();               // 等待应答
    Write_IIC_Byte(IIC_Command);  // 发送具体命令
    IIC_Wait_Ack();               // 等待应答
    IIC_Stop();                   // 发送停止信号
}

/**
 * @brief 向OLED发送I2C数据(含从机地址0x78)
 * @param [in] IIC_Data 待发送的数据字节
 */
void Write_IIC_Data(unsigned char IIC_Data)
{
    IIC_Start();                  // 发送起始信号
    Write_IIC_Byte(0x78);         // 从机地址(0x78:7位地址,最低位0表示写操作)
    IIC_Wait_Ack();               // 等待应答
    Write_IIC_Byte(0x40);         // 数据标识(D/C#=1,区分命令和数据)
    IIC_Wait_Ack();               // 等待应答
    Write_IIC_Byte(IIC_Data);     // 发送具体数据
    IIC_Wait_Ack();               // 等待应答
    IIC_Stop();                   // 发送停止信号
}

/**
 * @brief 向OLED写入字节(区分命令和数据)
 * @param [in] dat 待写入的字节
 * @param [in] cmd 标志位:0=命令,1=数据
 */
void OLED_WR_Byte(unsigned dat, unsigned cmd)
{
    if (cmd) {
        Write_IIC_Data(dat);      // 写入数据
    } else {
        Write_IIC_Command(dat);   // 写入命令
    }
}

/**********************************************
 * 延时函数(基于循环计数,与硬件时钟相关)
 **********************************************/

/**
 * @brief 50ms级延时函数(非精确,依赖CPU频率)
 * @param [in] Del_50ms 延时倍数(1倍≈50ms)
 */
void Delay_50ms(unsigned int Del_50ms)
{
    unsigned int m;
    for (; Del_50ms > 0; Del_50ms--)
        for (m = 6245; m > 0; m--); // 循环计数实现延时
}

/**
 * @brief 1ms级延时函数(非精确,依赖CPU频率)
 * @param [in] Del_1ms 延时倍数(1倍≈1ms)
 */
void Delay_1ms(unsigned int Del_1ms)
{
    unsigned char j;
    while (Del_1ms--) {
        for (j = 0; j < 123; j++); // 循环计数实现延时
    }
}

/**********************************************
 * OLED 显示控制函数
 **********************************************/

/**
 * @brief 设置OLED显示位置(页和列地址)
 * @param [in] x 列坐标(0~127)
 * @param [in] y 页地址(0~7,对应行0~63,每页8行)
 */
void OLED_Set_Pos(unsigned char x, unsigned char y) 
{
    OLED_WR_Byte(0xb0 + y, OLED_CMD);       // 设置页地址(0xB0~0xB7对应页0~7)
    OLED_WR_Byte(((x & 0xf0) >> 4) | 0x10, OLED_CMD); // 设置列高4位(0x10~0x1F)
    OLED_WR_Byte(x & 0x0f, OLED_CMD);        // 设置列低4位(0x00~0x0F)
}

/**
 * @brief 开启OLED显示(启用DC-DC电源,打开面板)
 */
void OLED_Display_On(void)
{
    OLED_WR_Byte(0X8D, OLED_CMD);  // 发送DC-DC控制命令
    OLED_WR_Byte(0X14, OLED_CMD);  // 启用DC-DC电源(提升驱动电压)
    OLED_WR_Byte(0XAF, OLED_CMD);  // 打开OLED显示(正常工作模式)
}

/**
 * @brief 关闭OLED显示(禁用DC-DC电源,关闭面板)
 */
void OLED_Display_Off(void)
{
    OLED_WR_Byte(0X8D, OLED_CMD);  // 发送DC-DC控制命令
    OLED_WR_Byte(0X10, OLED_CMD);  // 禁用DC-DC电源(降低功耗)
    OLED_WR_Byte(0XAE, OLED_CMD);  // 关闭OLED显示(待机模式)
}

/**
 * @brief 清空OLED屏幕(填充0x00,显示全黑)
 */
void OLED_Clear(void)  
{  
    u8 i, n;
    // 遍历所有页(0~7)
    for (i = 0; i < 8; i++) {  
        OLED_WR_Byte(0xb0 + i, OLED_CMD);    // 设置当前页地址
        OLED_WR_Byte(0x00, OLED_CMD);         // 设置列低地址(0x00)
        OLED_WR_Byte(0x10, OLED_CMD);         // 设置列高地址(0x10,即0x10|0=0x10)
        // 向当前页所有列写入0(清空数据)
        for (n = 0; n < 128; n++) OLED_WR_Byte(0, OLED_DATA); 
    }
}

/**
 * @brief 清除指定行(单页操作,0~7对应行0~63)
 * @param [in] y 页号(0~7)
 */
void OLED_Clear_Row(u8 y)
{
    u8 n;
    OLED_Set_Pos(0, y);           // 设置起始位置为当前页的第0列
    // 向当前页所有列写入0(清空该行对应页的数据)
    for (n = 0; n < 128; n++) OLED_WR_Byte(0, OLED_DATA); 
}

/**
 * @brief 全屏点亮(测试用,填充0xFF)
 */
void OLED_On(void)  
{  
    u8 i, n;
    // 遍历所有页,写入0xFF(点亮所有像素)
    for (i = 0; i < 8; i++) {  
        OLED_WR_Byte(0xb0 + i, OLED_CMD);    // 设置页地址
        OLED_WR_Byte(0x00, OLED_CMD);         // 列低地址
        OLED_WR_Byte(0x10, OLED_CMD);         // 列高地址
        for (n = 0; n < 128; n++) OLED_WR_Byte(1, OLED_DATA); 
    }
}

/**
 * @brief 在指定位置显示单个ASCII字符(8×16像素)
 * @param [in] x 列起始坐标(0~127)
 * @param [in] y 页起始地址(0~7,对应行0~63)
 * @param [in] chr 要显示的ASCII字符(' '~'~',共95个字符)
 * @param [in] flag 反白标志:非0时反白显示(取反显示)
 */
void OLED_ShowChar(u8 x, u8 y, u8 chr, u8 flag)
{      	
    unsigned char c = 0, i = 0;
    c = chr - ' ';                // 计算字符偏移量(' '的ASCII为32,偏移后0~94)
    if (x > Max_Column - 1) {     // 超出列范围时换行(列最大127)
        x = 0;
        y = y + 2;                // 每个字符占2页(8×16像素,16行=2页)
    }
    OLED_Set_Pos(x, y);           // 设置上半部分(页y,对应行8*y~8*y+7)
    for (i = 0; i < 8; i++) {     // 写入上8行数据
        if (flag) 
            OLED_WR_Byte(~F8X16[c * 16 + i], OLED_DATA);  // 反白:取反显示
        else 
            OLED_WR_Byte(F8X16[c * 16 + i], OLED_DATA);   // 正常显示
    }
    OLED_Set_Pos(x, y + 1);       // 设置下半部分(页y+1,对应行8*(y+1)~8*(y+1)+7)
    for (i = 0; i < 8; i++) {     // 写入下8行数据
        if (flag) 
            OLED_WR_Byte(~F8X16[c * 16 + i + 8], OLED_DATA);  // 反白
        else 
            OLED_WR_Byte(F8X16[c * 16 + i + 8], OLED_DATA);   // 正常
    }
}

/**
 * @brief 在指定位置显示单个16×16像素汉字(需字库支持)
 * @param [in] x 列起始坐标(0~127)
 * @param [in] y 页起始地址(0~7)
 * @param [in] str 汉字的GBK编码(2字节,如"中"的编码为0xD6D0)
 * @param [in] flag 反白标志:非0时反白显示
 */
void OLED_ShowCHineseWord(u8 x, u8 y, u8* str, u8 flag)
{
    u8 t = 0;
    u16 index;
    // 在字库中查找对应的汉字数据
    for (index = 0; index < sizeof(Hzk) / 35; index++) { // Hzk为汉字字库结构体数组
        // 对比汉字的区码和位码(GBK编码前两字节)
        if (Hzk[index].name[0] == str[0] && Hzk[index].name[1] == str[1]) {
            OLED_Set_Pos(x, y);           // 设置上半部分显示位置(页y)
            for (t = 0; t < 16; t++) {    // 写入前16字节(上8行)
                if (flag) 
                    OLED_WR_Byte(~Hzk[index].dat[t], OLED_DATA);  // 反白
                else 
                    OLED_WR_Byte(Hzk[index].dat[t], OLED_DATA);   // 正常
            }
            OLED_Set_Pos(x, y + 1);       // 设置下半部分显示位置(页y+1)
            for (t = 0; t < 16; t++) {    // 写入后16字节(下8行)
                if (flag) 
                    OLED_WR_Byte(~Hzk[index].dat[t + 16], OLED_DATA);  // 反白
                else 
                    OLED_WR_Byte(Hzk[index].dat[t + 16], OLED_DATA);   // 正常
            }
            break; // 找到后退出循环
        } 
    } 
}

/**
 * @brief 在指定位置显示中英文字符串(自动区分中英文)
 * @param [in] x 列起始坐标(0~127)
 * @param [in] y 页起始地址(0~7)
 * @param [in] str 字符串指针(支持ASCII字符和GBK汉字)
 * @param [in] flag 反白标志:非0时反白显示
 */
void OLED_ShowText(u8 x, u8 y, u8* str, u8 flag)
{
    u8 tempstr[3] = {0}; // 临时存储汉字的2字节编码
    while (*str != '\0') { // 遍历字符串直到结束符
        if (*str & 0x80) { // 检测到高位为1,判断为汉字(GBK编码)
            tempstr[0] = *str++; // 读取第一个字节(区码)
            tempstr[1] = *str++; // 读取第二个字节(位码)
            OLED_ShowCHineseWord(x, y, tempstr, flag); // 显示汉字
            x += 16; // 汉字占16列,列坐标后移16
            // 判断下一个字符是否为汉字,调整换行逻辑
            if (*str & 0x80) { 
                if (x >= 112) { y += 2; x = 0; } // 剩余空间不足16列时换行(2页)
            } else {
                if (x >= 120) { y += 2; x = 0; } // 英文剩余空间不足8列时换行
            }
        } else { // ASCII字符(高位为0)
            OLED_ShowChar(x, y, *str++, flag); // 显示单个字符
            x += 8; // 英文占8列,列坐标后移8
            // 判断下一个字符是否为汉字,调整换行逻辑
            if (*str & 0x80) { 
                if (x >= 112) { y += 2; x = 0; } // 剩余空间不足16列时换行
            } else {
                if (x >= 120) { y += 2; x = 0; } // 剩余空间不足8列时换行
            }
        }
    }
}

/**
 * @brief 显示字符串(兼容旧接口,固定8×16字符大小)
 * @param [in] x 列起始坐标(0~127)
 * @param [in] y 页起始地址(0~7)
 * @param [in] chr 字符串指针(仅ASCII字符,' '~'~')
 * @param [in] size1 字符大小(固定为16,此处可能未使用)
 */
void OLED_ShowString(u8 x, u8 y, u8 *chr, u8 size1)
{
    while ((*chr >= ' ') && (*chr <= '~')) { // 过滤非法字符(只显示可打印ASCII)
        OLED_ShowChar(x, y, *chr, size1);     // 显示单个字符
        x += size1 / 2;                        // 字符宽度8,size1=16时右移8列
        if (x > 128 - size1) {                 // 超出屏幕宽度时换行
            x = 0;
            y += 2;                            // 每个字符占2页(16行)
        }
        chr++; // 指针后移
    }
}

/**
 * @brief 在指定区域显示位图(128×64像素以内)
 * @param [in] x0 左上角列坐标(0~127)
 * @param [in] y0 左上角页地址(0~7)
 * @param [in] x1 右下角列坐标(0~127,x1 > x0)
 * @param [in] y1 右下角页地址(0~7,y1 > y0)
 * @param [in] BMP[] 位图数据(按页存储,每个字节对应一列8行)
 */
void OLED_DrawBMP(unsigned char x0, unsigned char y0, 
                  unsigned char x1, unsigned char y1, 
                  unsigned char BMP[])
{  
    unsigned int j = 0;
    unsigned char x, y;
    // 计算目标区域的页范围(y1可能不是8的整数倍,需向上取整)
    if (y1 % 8 == 0) y = y1 / 8;      
    else y = y1 / 8 + 1;
    // 遍历所有页
    for (y = y0; y < y1; y++) {
        OLED_Set_Pos(x0, y);           // 设置当前页的起始列
        // 遍历当前页的所有列
        for (x = x0; x < x1; x++) {    
            OLED_WR_Byte(BMP[j++], OLED_DATA); // 写入位图数据(按列顺序)
        }
    }
}

/**********************************************
 * OLED 初始化函数(配置GPIO和显示参数)
 **********************************************/
void OLED_Init(void)
{ 	
    GPIO_InitTypeDef  GPIO_InitStructure; // GPIO初始化结构体
    
    // 使能SCL和SDA引脚的时钟(GPIOB)
    RCC_APB2PeriphClockCmd(OLED_GPIO_PORT_CLK_SCL, ENABLE);
    RCC_APB2PeriphClockCmd(OLED_GPIO_PORT_CLK_SDA, ENABLE);
    
    // 配置SCL引脚:推挽输出,50MHz速度
    GPIO_InitStructure.GPIO_Pin = OLED_PIN_SCL;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(OLED_GPIO_PORT_SCL, &GPIO_InitStructure);
    
    // 配置SDA引脚:推挽输出,50MHz速度
    GPIO_InitStructure.GPIO_Pin = OLED_PIN_SDA;
    GPIO_Init(OLED_GPIO_PORT_SDA, &GPIO_InitStructure);
    
    // 初始化I2C引脚为高电平(空闲状态)
    GPIO_SetBits(OLED_GPIO_PORT_SCL, OLED_PIN_SCL);
    GPIO_SetBits(OLED_GPIO_PORT_SDA, OLED_PIN_SDA);
    
    delay_ms(200); // 延时等待OLED稳定
    
    OLED_WR_Byte(0xAE, OLED_CMD); // 关闭显示(初始化第一步)
    OLED_WR_Byte(0x00, OLED_CMD); // 设置低列地址(0x00~0x0F)
    OLED_WR_Byte(0x10, OLED_CMD); // 设置高列地址(0x10~0x1F,实际列=0x10|低4位)
    OLED_WR_Byte(0x40, OLED_CMD); // 设置显示起始行(0x40对应行0,范围0x40~0x7F)
    OLED_WR_Byte(0xB0, OLED_CMD); // 设置页地址(0xB0~0xB7对应页0~7)
    OLED_WR_Byte(0x81, OLED_CMD); // 对比度控制命令
    OLED_WR_Byte(0xFF, OLED_CMD); // 设置最大对比度(0x00~0xFF)
    OLED_WR_Byte(0xA6, OLED_CMD); // 正常显示模式(非反显)
    OLED_WR_Byte(0xA8, OLED_CMD); // 设置复用率(占空比,0x3F对应1/64)
    OLED_WR_Byte(0x3F, OLED_CMD); // 复用率为1/64(最大64行)
    OLED_WR_Byte(0xC8, OLED_CMD); // 行扫描顺序:从上到下(0xC0为从下到上)
    OLED_WR_Byte(0xA1, OLED_CMD); // 列扫描顺序:从左到右(0xA0为从右到左)
    OLED_WR_Byte(0xD3, OLED_CMD); // 显示偏移命令
    OLED_WR_Byte(0x00, OLED_CMD); // 偏移量0(范围0x00~0x3F)
    OLED_WR_Byte(0xD5, OLED_CMD); // 振荡器分频命令
    OLED_WR_Byte(0x80, OLED_CMD); // 分频比1:1(0x00~0xFF,影响显示频率)
    OLED_WR_Byte(0xD8, OLED_CMD); // 区域颜色模式命令(此处关闭)
    OLED_WR_Byte(0x05, OLED_CMD); // 关闭区域颜色模式
    OLED_WR_Byte(0xD9, OLED_CMD); // 预充电周期命令
    OLED_WR_Byte(0xF1, OLED_CMD); // 预充电周期设置(0xF1为优化值)
    OLED_WR_Byte(0xDA, OLED_CMD); // COM引脚配置命令
    OLED_WR_Byte(0x12, OLED_CMD); // COM引脚硬件配置(适合0.96寸屏)
    OLED_WR_Byte(0xDB, OLED_CMD); // VCOMH电压命令
    OLED_WR_Byte(0x30, OLED_CMD); // VCOMH电压设置(防止闪烁)
    OLED_WR_Byte(0x8D, OLED_CMD); // 电荷泵控制命令
    OLED_WR_Byte(0x14, OLED_CMD); // 启用电荷泵(提供高压电源)
    OLED_WR_Byte(0xAF, OLED_CMD); // 开启OLED显示(初始化完成)
}

4.main.c

#include "stm32f10x.h"    //根据自己的芯片自行更改
#include "oled_i2c.h"

//此函数为自定义的OLED显示函数,大家可根据自己需要自行定义
void updateOLEDDisplay(void) 
{
    int display_speed;
    char speed_str[10];

    // 在屏幕第 0 行第 0 列开始显示 "Angle:" 字符串,字体大小为 1
    OLED_ShowText(0, 0, (unsigned char *)"Angle:", 1);

    // 在 OLED 屏幕的指定位置显示转速数值
    // 使用 sprintf 函数将速度值转换为字符串
    sprintf(speed_str, "%d", display_speed);
    // 在屏幕第 3 行第 50 列开始显示转换后的速度字符串,字体大小为 1
    OLED_ShowText(50, 3, (unsigned char *)speed_str, 1);
}

int main(void)
{
    // 初始化 OLED 显示屏,配置 OLED 显示屏的通信接口和显示参数
    OLED_Init();
    // 清空 OLED 显示内容,清除屏幕上之前的显示信息
    OLED_Clear();	
    // 在 OLED 显示硬件初始化成功信息
    OLED_ShowText(0,6,"success!",0); 
    // 延时 500 微秒,等待一段时间以便观察初始化成功信息
    delay_us(500);
    // 再次清空 OLED 显示内容,为后续显示电机状态信息做准备
    OLED_Clear();	

    while(1)
    {
        //调用显示封装函数
        updateOLEDDisplay();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值