IIC协议(使用OLED小屏幕)-51和32版本

一.51单片机版本

1. 简介

IIC属于半双工同步通信方式

1.1 构成

IIC串行总线一般有两根信号线,一根是双向的数据线SDA另一根是时钟线SCL,其时钟信号是由主控
器件产生。所有接到IIC总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线
的SCL上。对于并联在一条总线上的每个IC都有唯一的地址。
在这里插入图片描述

1.2 IIC协议

IC总线在传输数据的过程中一共有三种类型信号,分别为:开始信号、结束信号和应答信号。

  • 起始信号
  • 终止信号
    在这里插入图片描述
    起始信号看下降沿终止信号看上升沿
    注意:两者都是在SCL(时钟信号)的高电平时操作
void IIC_Start()
{
	scl = 0;//防止雪花
	sda = 1;
	scl = 1;
	_nop_();//5us
	sda = 0;
	_nop_();
}

void IIC_Stop()
{
	sda = 0;
	scl = 1;
	_nop_();
	sda = 1;
	_nop_();
}
  • 应答信号
    发送器每发送一个字节(8个bit),就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。
    应答信号为低电平时,规定为有效应答位(ACK,简称应答位),表示接收器已经成功地接收了该字
    节;
    应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。
    在这里插入图片描述
char IIC_ACK()
{
	char flag;
	//下面的sda按照应答“/0”来书写
	sda = 1;// 就在时钟脉冲9期间释放数据线
	_nop_();
	scl = 1;
	_nop_();
	flag = sda;//接收信号(应答or非应答)
	_nop_();
	scl = 0;
	_nop_();
	
	return flag;
}
  • 数据发送的时序
  • 在这里插入图片描述
    注意:SDA翻转仅仅在SCL低电平SCL高电平时就是在传输数据
    在这里插入图片描述
void IIC_Send_Byte(char dataSend)
{
	int i;
	for(i=0;i<8;i++){
		scl = 0;// scl拉低,让sda做好准备 
		sda = dataSend & 0x80;// 1000 0000获得dataSend最高位,给sda
		_nop_();// 发送数据建立时间
		scl = 1;// scl拉高开始发送
		_nop_();//数据发送时间
		scl = 0;// 发送完毕拉低
		_nop_();//数据发送时间
		dataSend = dataSend << 1;// 左移
	}
}

1.3 OLED写命令

1.3.1 Device Address
b7b6b5b4b3b2b1b0
0111100R/W
1.3.2 IIC bus data format

在这里插入图片描述

上述格式:
1. start()
  The slave address is following the start condition for recognition use. 
  The slave address is either “b0111100” or “b0111101” by changing the SA0 to LOW or HIGH
  The write mode is established by setting the R/W# bit to logic “0”.
  slava address---从机地址    0111100 x(0111 1000写    0111 1001读)
2. 写入从机地址   b0111 1000    0x78
3.ACK
  a. If the Co bit is set as logic “0”, the transmission of the following information will contain data bytes only.
  Co = 0---为数据字节(Data byte)   
  b. If the D/C# bit is set to logic “0”, it defines the following data byte as a command. 
      If the D/C# bit is set to logic “1”, it defines the following data byte as a data which will be stored at the GDDRAM. 
  D/C# = 0---写命令   D/C# = 1---写数据 
4. control byte:(0)(0)000000写入命令   (0)(1)000000写入数据
5. ACK
6. 写入指令/数据
7. ACK
8. stop()
void Oled_Write_Cmd(char dataCmd)
{
//	1.start()
	IIC_Start();
//	2.写入   b0111 1000    0x78
	IIC_Send_Byte(0x78);
//	3.ACK
	IIC_ACK();
//	4.control byte:(0)(0)000000写入命令   (0)(1)000000写入数据
	IIC_Send_Byte(0x00);
//	5.ACK
	IIC_ACK();
	//6.写入指令/数据
	IIC_Send_Byte(dataCmd);
	//7.ACK
	IIC_ACK();
	//8.stop()
	IIC_Stop();
}

void Oled_Write_Data(char dataData)
{
//	1.start()
	IIC_Start();
//	2.写入   b0111 1000    0x78
	IIC_Send_Byte(0x78);
//	3.ACK
	IIC_ACK();
//	4.control byte:(0)(0)000000写入命令   (0)(1)000000写入数据
	IIC_Send_Byte(0x40);
//	5.ACK
	IIC_ACK();
	//6.写入指令/数据
	IIC_Send_Byte(dataData);
	//7.ACK
	IIC_ACK();
	//8.stop()
	IIC_Stop();
}

1.4 OLED显示一个点

OLED由 128 x 64 小灯管组成
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
问题是如何选择PAGE???

1.4.1 页地址模式

在这里插入图片描述

1.4.2 水平地址模式

在这里插入图片描述

1.4.3 垂直地址模式(很少使用)

在这里插入图片描述

1.4.4 选择页模式

在这里插入图片描述

页寻址模式:
	1.发送cmd:0x20;进入设置存储器地址模式
	2.发送cmd:0x02;默认页模式

在这里插入图片描述
看第二行:选择PAGE0: 1011 0000 PAGE1: 1011 0001 …

#include <reg52.h>
#include <intrins.h>

sbit scl = P1^1;
sbit sda = P1^3;

void IIC_Start()
{
	scl = 0;//防止雪花
	sda = 1;
	scl = 1;
	_nop_();
	sda = 0;
	_nop_();
}

void IIC_Stop()
{
	scl = 1;
	sda = 0;
	_nop_();
	sda = 1;
	_nop_();
}

char IIC_ACK()
{
	char flag;
	//下面的sda按照应答“/0”来书写
	sda = 1;// 就在时钟脉冲9期间释放数据线
	_nop_();
	scl = 1;
	_nop_();
	flag = sda;
	_nop_();
	scl = 0;
	_nop_();
	
	return flag;
}

void IIC_Send_Byte(char dataSend)
{
	int i;
	for(i=0;i<8;i++){
		scl = 0;// scl拉低,让sda做好准备 
		sda = dataSend & 0x80;// 1000 0000获得dataSend最高位,给sda
		_nop_();// 发送数据建立时间
		scl = 1;// scl拉高开始发送
		_nop_();//数据发送时间
		scl = 0;// 发送完毕拉低
		_nop_();//数据发送时间
		dataSend = dataSend << 1;// 左移
	}
}

void Oled_Write_Cmd(char dataCmd)
{
//	1.start()
	IIC_Start();
//	2.写入   b0111 1000    0x78
	IIC_Send_Byte(0x78);
//	3.ACK
	IIC_ACK();
//	4.control byte:(0)(0)000000写入命令   (0)(1)000000写入数据
	IIC_Send_Byte(0x00);
//	5.ACK
	IIC_ACK();
	//6.写入指令/数据
	IIC_Send_Byte(dataCmd);
	//7.ACK
	IIC_ACK();
	//8.stop()
	IIC_Stop();
}

void Oled_Write_Data(char dataData)
{
//	1.start()
	IIC_Start();
//	2.写入   b0111 1000    0x78
	IIC_Send_Byte(0x78);
//	3.ACK
	IIC_ACK();
//	4.control byte:(0)(0)000000写入命令   (0)(1)000000写入数据
	IIC_Send_Byte(0x40);
//	5.ACK
	IIC_ACK();
	//6.写入指令/数据
	IIC_Send_Byte(dataData);
	//7.ACK
	IIC_ACK();
	//8.stop()
	IIC_Stop();
}

void Oled_Init(void){
	Oled_Write_Cmd(0xAE);//--display off
	Oled_Write_Cmd(0x00);//---set low column address
	Oled_Write_Cmd(0x10);//---set high column address
	Oled_Write_Cmd(0x40);//--set start line address
	Oled_Write_Cmd(0xB0);//--set page address
	Oled_Write_Cmd(0x81); // contract control
	Oled_Write_Cmd(0xFF);//--128
	Oled_Write_Cmd(0xA1);//set segment remap
	Oled_Write_Cmd(0xA6);//--normal / reverse
	Oled_Write_Cmd(0xA8);//--set multiplex ratio(1 to 64)
	Oled_Write_Cmd(0x3F);//--1/32 duty
	Oled_Write_Cmd(0xC8);//Com scan direction
	Oled_Write_Cmd(0xD3);//-set display offset
	Oled_Write_Cmd(0x00);//
	Oled_Write_Cmd(0xD5);//set osc division
	Oled_Write_Cmd(0x80);//
	Oled_Write_Cmd(0xD8);//set area color mode off
	Oled_Write_Cmd(0x05);//
	Oled_Write_Cmd(0xD9);//Set Pre-Charge Period
	Oled_Write_Cmd(0xF1);//
	Oled_Write_Cmd(0xDA);//set com pin configuartion
	Oled_Write_Cmd(0x12);//
	Oled_Write_Cmd(0xDB);//set Vcomh
	Oled_Write_Cmd(0x30);//
	Oled_Write_Cmd(0x8D);//set charge pump enable
	Oled_Write_Cmd(0x14);//
	Oled_Write_Cmd(0xAF);//--turn on oled panel
}

int main()
{
	//1. OLED初始化
	Oled_Init();
	//2. 选择一个位置
		//2.1 确认页寻址模式
	Oled_Write_Cmd(0x20);
	Oled_Write_Cmd(0x02);
		//2.2 选则PAGE0   1011 0000
	Oled_Write_Cmd(0xB0);
	//3. 显示一个点
	Oled_Write_Data(0x08);
	while(1);
	return 0;
}

当在运行程序时,当我们选择不同的PAGE时会发现,列地址是累加的

那么我们设置列的位置 若在其列的最后一位128的时候显示应

Oled_Write_Cmd(0x0f);
Oled_Write_Cmd(0x17);
//主函数内部
	//1. OLED初始化
	Oled_Init();
	//2. 选择一个位置
		//2.1 确认页寻址模式
	Oled_Write_Cmd(0x20);
	Oled_Write_Cmd(0x02);
		//2.2 选则PAGE0   1011 0000
	Oled_Write_Cmd(0xB0);
	//3. 显示一个点
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	//PAGE6最后一列显示一个点
	Oled_Write_Cmd(0xB6);
	Oled_Write_Cmd(0x0f);
	Oled_Write_Cmd(0x17);
	Oled_Write_Data(0x08);
	while(1);
	return 0;

1.5 清屏函数

void Oled_Clear()
{
	unsigned char i,j;
	for(i=0;i<8;i++){
		Oled_Write_Cmd(0xB0 + i);//	page0-page7
		//每个page从0列-127列
		Oled_Write_Cmd(0x00);
		Oled_Write_Cmd(0x10);
		//0列到127列,依次写入0,每写入数据,列地址自动偏移
		for(j=0;j<128;j++){
			Oled_Write_Data(0);
		}
	}
}

1.6 OLED显示一个字符A

这里我们借助一个字模软件:
链接:https://pan.baidu.com/s/1pt8Tlmd8IY-TemTJ85ttwg?pwd=3qw8

/*--  文字:  A  --*/
//拆分成两个PAGE
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
char A1[8] = {0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00};
char A2[8] = {0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20};

int main()
{
	int i;
	//1. OLED初始化
	Oled_Init();
	//2. 选择一个位置
		//2.1 确认页寻址模式
	Oled_Write_Cmd(0x20);
	Oled_Write_Cmd(0x02);
	led_Clear();
		//2.2 选则PAGE0   1011 0000
	Oled_Write_Cmd(0xB0);
	Oled_Write_Cmd(0x00);//从第0列开始
	Oled_Write_Cmd(0x10);
	for(i=0;i<8;i++){
		Oled_Write_Data(A1[i]);
	}
	Oled_Write_Cmd(0xB1);//PAGE1
	Oled_Write_Cmd(0x00);//从第零列开始
	Oled_Write_Cmd(0x10);
	for(i=0;i<8;i++){
		Oled_Write_Data(A2[i]);
	}
	while(1);
	return 0;
}

1.7 OLED显示“加油”

/*--  文字:  加  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
code char j1[16] = {0x10,0x10,0x10,0xFF,0x10,0x10,0xF0,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x00,0x00};
code char j2[16] = {0x80,0x40,0x30,0x0F,0x40,0x80,0x7F,0x00,0x00,0x7F,0x20,0x20,0x20,0x7F,0x00,0x00};

/*--  文字:  油  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
code char y1[16] = {0x10,0x60,0x02,0x8C,0x00,0xF0,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0xF0,0x00,0x00};
code char y2[16] = {0x04,0x04,0x7E,0x01,0x00,0xFF,0x42,0x42,0x42,0x7F,0x42,0x42,0x42,0xFF,0x00,0x00};

int main()
{
	unsigned char i;
	//1. OLED初始化
	Oled_Init();
	//2. 选择一个位置
		//2.1 确认页寻址模式
	Oled_Write_Cmd(0x20);
	Oled_Write_Cmd(0x02);
	led_Clear();
		//2.2 选则PAGE0   1011 0000
	Oled_Write_Cmd(0xB0);
	Oled_Write_Cmd(0x00);//从第0列开始
	Oled_Write_Cmd(0x10);
	for(i=0;i<16;i++){
		Oled_Write_Data(j1[i]);
	}
	for(i=0;i<16;i++){
		Oled_Write_Data(y1[i]);
	}
	
	Oled_Write_Cmd(0xB1);//PAGE1
	Oled_Write_Cmd(0x00);//从第0列开始
	Oled_Write_Cmd(0x10);
	for(i=0;i<16;i++){
		Oled_Write_Data(j2[i]);
	}
	for(i=0;i<16;i++){
		Oled_Write_Data(y2[i]);
	}
	while(1);
	return 0;
}

1.8 OLED显示一张图片

在这里插入图片描述

code unsigned char bmpImager[]={
	/*--  调入了一幅图像:C:\Users\15425\Desktop\无标题.bmp  --*/
/*--  宽度x高度=128x64  --128*8位   */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0xC0,0xC0,0xC0,0xE0,0xE0,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x7E,0xFF,0xFF,0xC7,0x83,0x81,0x81,0x80,0x82,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xE0,0xF0,0xF0,
0x78,0x7C,0x3D,0x1F,0x0F,0x03,0x1B,0x7F,0xFB,0xF3,0xC3,0x81,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x20,0x70,0x70,0x78,0x78,0x38,0x3C,0x1E,0x1F,0x0F,0x27,0x73,0x73,0x71,0xF0,0xF0,
0xF0,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x71,0xF3,0x73,0x77,0x77,0x7F,0x77,
0x07,0x0F,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,
0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x7F,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x0E,0x0E,0x0E,0x0E,0x0E,0x0F,0x0F,
0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x1F,0x1C,0x1C,0x1C,0x1C,0x18,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

void Oled_Show_Image(unsigned char *bmpImager)
{
	unsigned char i;
	unsigned int j;
	
	for(i=0;i<8;i++){
		Oled_Write_Cmd(0xB0 + i);//	page0-page7
		//每个page从0列
		Oled_Write_Cmd(0x00);
		Oled_Write_Cmd(0x10);
		//0列到127列,依次写入0,每写入数据,列地址自动偏移
		for(j=128 * i;j<128 * (i+1);j++){
			Oled_Write_Data(bmpImager[j]);
		}
	}
}

int main()
{
	//1. OLED初始化
	Oled_Init();
	//2. 选择一个位置
		//2.1 确认页寻址模式
	Oled_Write_Cmd(0x20);
	Oled_Write_Cmd(0x02);
	Oled_Clear();
	Oled_Show_Image(bmpImager);
	while(1);
	return 0;
}

二. 32版本

2.1 使用的库函数

HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c,
									uint16_t DevAddress,
									uint16_t MemAddress,
									uint16_t MemAddSize,
									uint8_t *pData,
									uint16_t Size,
									uint32_t Timeout)
参数一:I2C_HandleTypeDef *hi2c,I2C设备句柄
参数二:uint16_t DevAddress,目标器件的地址,七位地址必须左对齐    ----0x78
参数三:uint16_t MemAddress,目标器件的目标寄存器地址  ---- (0)(0)000000写入命令    (0)(1)000000写入数据
参数四:uint16_t MemAddSize,目标器件内部寄存器地址数据长度
参数五:uint8_t *pData,待写的数据首地址
参数六:uint16_t Size,待写的数据长度
参数七:uint32_t Timeout,超时时间
返回值:HAL_StatusTypeDef,HAL状态(OK,busy,ERROR,TIMEOUT)
									

2.2 配置

在这里插入图片描述

2.3 写指令和写数据等相关代码

void Oled_Write_Cmd(uint8_t dataCmd)
{
    /*
    HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c,
                                          uint16_t DevAddress, 
                                          uint16_t MemAddress, 
                                          uint16_t MemAddSize, 
                                          uint8_t *pData, 
                                          uint16_t Size, 
                                          uint32_t Timeout)
    */
    HAL_I2C_Mem_Write(&hi2c1 , 0x78 , 0x00 , I2C_MEMADD_SIZE_8BIT , &dataCmd , 1 , 0xff);
}

void Oled_Write_Data(uint8_t dataData)
{
    HAL_I2C_Mem_Write(&hi2c1 , 0x78 , 0x40 , I2C_MEMADD_SIZE_8BIT , &dataData , 1 , 0xff);
}

void Oled_Init(void){
	Oled_Write_Cmd(0xAE);//--display off
	Oled_Write_Cmd(0x00);//---set low column address
	Oled_Write_Cmd(0x10);//---set high column address
	Oled_Write_Cmd(0x40);//--set start line address
	Oled_Write_Cmd(0xB0);//--set page address
	Oled_Write_Cmd(0x81); // contract control
	Oled_Write_Cmd(0xFF);//--128
	Oled_Write_Cmd(0xA1);//set segment remap
	Oled_Write_Cmd(0xA6);//--normal / reverse
	Oled_Write_Cmd(0xA8);//--set multiplex ratio(1 to 64)
	Oled_Write_Cmd(0x3F);//--1/32 duty
	Oled_Write_Cmd(0xC8);//Com scan direction
	Oled_Write_Cmd(0xD3);//-set display offset
	Oled_Write_Cmd(0x00);//
	Oled_Write_Cmd(0xD5);//set osc division
	Oled_Write_Cmd(0x80);//
	Oled_Write_Cmd(0xD8);//set area color mode off
	Oled_Write_Cmd(0x05);//
	Oled_Write_Cmd(0xD9);//Set Pre-Charge Period
	Oled_Write_Cmd(0xF1);//
	Oled_Write_Cmd(0xDA);//set com pin configuartion
	Oled_Write_Cmd(0x12);//
	Oled_Write_Cmd(0xDB);//set Vcomh
	Oled_Write_Cmd(0x30);//
	Oled_Write_Cmd(0x8D);//set charge pump enable
	Oled_Write_Cmd(0x14);//
	Oled_Write_Cmd(0xAF);//--turn on oled panel
}

void Oled_Clear()
{
	unsigned char i,j;
	for(i=0;i<8;i++){
		Oled_Write_Cmd(0xB0 + i);//	page0-page7
		//每个page从0列
		Oled_Write_Cmd(0x00);
		Oled_Write_Cmd(0x10);
		//0列到127列,依次写入0,每写入数据,列地址自动偏移
		for(j=0;j<128;j++){
			Oled_Write_Data(0);
		}
	}
}

2.4 主函数程序

  /* USER CODE BEGIN 2 */
    	//1. OLED初始化
	Oled_Init();
    Oled_Clear();
	//2. 选择一个位置
		//2.1 确认页寻址模式
	Oled_Write_Cmd(0x20);
	Oled_Write_Cmd(0x02);
		//2.2 选则PAGE0   1011 0000
	Oled_Write_Cmd(0xB0);
	//3. 显示一个点
	Oled_Write_Data(0x08);
  /* USER CODE END 2 */

其余跟C语言一样!!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小强子!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值