IIC协议初识及OLED写入指令、数据和显示的代码实现

news2025/2/24 3:56:48

目录

一、IIC协议概述

二、IIC协议起始和终止信号 

三、应答信号

四、数据发送的时序

五、OLED写入指令和数据

六、OLED显示一个点的思路

七、OLED显示一个点的代码

八、OLED列地址

九、OLED显示图片


一、IIC协议概述

1、IIC概述

IIC(集成电路总线)是由飞利浦公司发明的通讯总线,用于连接微控制器及其外围设备,IIC属于半双工同步通信方式

IIC的数据线只有一根,就是SDA,同一时间不管发送还是接收,只能有一个方向进行操作

2、特点

(1)简单性和有效性

IIC的最大传输速率是10kbps(面试考点)

串口的最大传输速率是20kbps

(2)多主控

其中任何能够进行发送和接收的设备都可以成为主总线,一个主控能够控制信号的传输和时钟频率,当然,在任何时间点上只能有一个主控

3、构成

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

二、IIC协议起始和终止信号 

1、IIC屏幕

2、IIC屏幕与C51单片机的连接方式

IIC        单片机

GND     GND

VCC      5V

SCL      能正常收发数据的引脚(如P0^1)

SDA      能正常收发数据的引脚(如P0^3)

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

(1)起始信号、终止信号

起始、终止信号时序逻辑分析

起始信号:SDA信号从高电平下降到低电平

终止信号:SDA信号从低电平上升到高电平

起始信号时序逻辑分析                                       终止信号时序逻辑分析

SCL = 1;                                                             SCL = 1; 

SDA = 1;                                                             SDA = 0;

延时4.7μs                                                           延时4μs

SDA = 0;                                                             SDA = 1;

延时4μs                                                              延时4.7μs

三、应答信号

发送器每发送一个字节(8个bit),就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号

应答信号为低电平时,规定为有效应答位(ACK,简称应答位),表示接收器已经成功地接收了该字节

应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功

应答信号时序逻辑分析及函数封装 

char IIC_ACK(){

    char flag;
    sda = 1;   //释放数据线
    _nop_();
    scl = 1;   //高电平的状态
    _nop_();
    flag = sda;  //读取应答信号,若读取的信号为低电平时,说明是有效应答信号
    _nop_();
    scl = 0;   //低电平的状态
    _nop_();
    
    return flag;
}

四、数据发送的时序

当SCL = 1(高电平)时,进行数据传送,并且这时数据不允许翻转

当SCL = 0(低电平)时,数据允许翻转

发送字节的函数封装

void IIC_Send_Byte(char dataSend){  //发送字节的函数

	int i;
	for(i=0;i<8;i++){           //发送的一个字节等于8个bit,所以要循环8次
		scl = 0;                //scl拉低,让sda做好数据准备
		sda = dataSend & 0x80;  //0x80 = 1000 0000 获得dataSend的最高位,给sda
		_nop_();                //发送数据建立时间  
		scl = 1;                //scl拉高进行数据传输
		_nop_();                //数据发送的时间
		scl = 0;                //数据发送完毕,scl拉低
		_nop_();
		dataSend = dataSend << 1;    //每发送完一个数据,dataSend的数据就向左移动一位
	}
}

五、OLED写入指令和数据

写命令/数据的代码

1、start()

2、写入 b0111 1000 0x78

3、ACK

4、Control byte:(0)(0) 000000写入命令     (0)(1) 000000写入数据

5、ACK

6、写入指令/数据

7、ACK

8、stop

六、OLED显示一个点的思路

1、如何显示一个点

有三种方式:分别为页地址模式、水平地址模式和垂直地址模式,可以通过下表格进行配置

下面重点说一下页地址模式:

页地址模式也是默认配置的地址模式

选择页地址模式的配置命令:

1、发送cmd:0x20;

2、发送cmd:0x02;

 2、详细的思路如下:

1、初始化

2、显示位置

    Oled_Write_Cmd(0x20);  //选择一个位置,确认页寻址地址
    Oled_Write_Cmd(0x02);  //选择一个位置,确认页寻址地址
    Oled_Write_Cmd(0xB0);  //选择PAGE0

3、显示内容

    Oled_Write_Data(0x08);  //显示一个点

3、编写初始化OLED函数

void Oled_Init(void){     //初始化OLED函数
 
	Oled_Write_Cmd(0xAE);
	Oled_Write_Cmd(0x00);
	Oled_Write_Cmd(0x10);
	Oled_Write_Cmd(0x40);
	Oled_Write_Cmd(0xB0);
	Oled_Write_Cmd(0x81);
	Oled_Write_Cmd(0xFF);
	Oled_Write_Cmd(0xA1);
	Oled_Write_Cmd(0xA6);
	Oled_Write_Cmd(0xA8);
	Oled_Write_Cmd(0x3F);
	Oled_Write_Cmd(0xC8);
	Oled_Write_Cmd(0xD3);
	Oled_Write_Cmd(0x00);
	Oled_Write_Cmd(0xD5);
	Oled_Write_Cmd(0x80);
	Oled_Write_Cmd(0xD8);
	Oled_Write_Cmd(0x05);
	Oled_Write_Cmd(0xD9);
	Oled_Write_Cmd(0xF1);
	Oled_Write_Cmd(0xDA);
	Oled_Write_Cmd(0x12);
	Oled_Write_Cmd(0xDB);
	Oled_Write_Cmd(0x30);
	Oled_Write_Cmd(0x8D);
	Oled_Write_Cmd(0x14);
	Oled_Write_Cmd(0xAF);
}

七、OLED显示一个点的代码

1、清屏函数代码

void Oled_Clear()       //清屏函数
{
	int 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);
		//一共有128列,0~127
		for(j=0;j<128;j++)
		{
			Oled_Write_Data(0);
 
		}
	}
}

2、 OLED显示一个点的代码

#include "reg52.h"
#include "intrins.h"

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

void IIC_Start(){   //起始信号函数

	scl = 0;   //防止雪花
	scl = 1;
	sda = 1;
	_nop_();   //延时5μs
	sda = 0;
	_nop_();
}

void IIC_Stop(){    //终止信号函数
	
	scl = 0;   //防止雪花
	scl = 1;
	sda = 0;
	_nop_();
	sda = 1;
	_nop_();
	
}
char IIC_ACK(){     //应答信号函数

	char flag;
	sda = 1;   //释放数据线
	_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++){         //发送的一个字节等于8个bit,所以要循环8次
		scl = 0;                //scl拉低,让sda做好数据准备
		sda = dataSend & 0x80;  //0x80 = 1000 0000 获得dataSend的最高位,给sda
		_nop_();                //发送数据建立时间  
		scl = 1;                //scl拉高进行数据传输
		_nop_();                //数据发送的时间
		scl = 0;                //数据发送完毕,scl拉低
		_nop_();
		dataSend = dataSend << 1;    //每发送完一个数据,dataSend的数据就向左移动一位
	}
}
	
void Oled_Write_Cmd(char dataCmd){   //OLED写入指令函数

	IIC_Start();             //开始信号函数
	IIC_Send_Byte(0x78);     //写入从机地址
	IIC_ACK();               //应答信号函数
	IIC_Send_Byte(0x00);     //发送一个写命令的信号
	IIC_ACK();               //应答信号函数
	IIC_Send_Byte(dataCmd);  //开始写入指令
	IIC_ACK();
	IIC_Stop();              //终止信号函数
	
}

void Oled_Write_Data(char dataData){   //OLED写入数据函数

	IIC_Start();             //开始信号函数
	IIC_Send_Byte(0x78);     //写入从机地址
	IIC_ACK();               //应答信号函数
	IIC_Send_Byte(0x40);     //发送一个写数据的信号
	IIC_ACK();               //应答信号函数
	IIC_Send_Byte(dataData);  //开始写入数据
	IIC_ACK();
	IIC_Stop();              //终止信号函数
}

void Oled_Init(void){     //初始化OLED函数
 
	Oled_Write_Cmd(0xAE);
	Oled_Write_Cmd(0x00);
	Oled_Write_Cmd(0x10);
	Oled_Write_Cmd(0x40);
	Oled_Write_Cmd(0xB0);
	Oled_Write_Cmd(0x81);
	Oled_Write_Cmd(0xFF);
	Oled_Write_Cmd(0xA1);
	Oled_Write_Cmd(0xA6);
	Oled_Write_Cmd(0xA8);
	Oled_Write_Cmd(0x3F);
	Oled_Write_Cmd(0xC8);
	Oled_Write_Cmd(0xD3);
	Oled_Write_Cmd(0x00);
	Oled_Write_Cmd(0xD5);
	Oled_Write_Cmd(0x80);
	Oled_Write_Cmd(0xD8);
	Oled_Write_Cmd(0x05);
	Oled_Write_Cmd(0xD9);
	Oled_Write_Cmd(0xF1);
	Oled_Write_Cmd(0xDA);
	Oled_Write_Cmd(0x12);
	Oled_Write_Cmd(0xDB);
	Oled_Write_Cmd(0x30);
	Oled_Write_Cmd(0x8D);
	Oled_Write_Cmd(0x14);
	Oled_Write_Cmd(0xAF);
}

void Oled_Clear()       //清屏代码
{
	int 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);
		//一共有128列,0~127
		for(j=0;j<128;j++)
		{
			Oled_Write_Data(0);
		}
	}
}
void main()
{
	Oled_Clear();
	Oled_Init();            //初始化OLED
	Oled_Write_Cmd(0x20);   //选择一个位置,确认页寻址地址
	Oled_Write_Cmd(0x02);
	Oled_Write_Cmd(0xB0);   //选择PAGE0,可以配置8次,分别是B0-B7
	Oled_Write_Data(0x08);  //显示一个点

	while(1);              //防止程序退出
}

执行结果:

 

八、OLED列地址

1、指定列的初始地址

Oled_Write_Cmd(0x00);   
Oled_Write_Cmd(0x10);

2、编写代码——实现多行的点都从头开始显示

#include "reg52.h"
#include "intrins.h"

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

void IIC_Start(){   //起始信号函数

	scl = 0;   //防止雪花
	scl = 1;
	sda = 1;
	_nop_();   //延时5μs
	sda = 0;
	_nop_();
}

void IIC_Stop(){    //终止信号函数
	
	scl = 0;   //防止雪花
	scl = 1;
	sda = 0;
	_nop_();
	sda = 1;
	_nop_();
	
}

char IIC_ACK(){     //应答信号函数

	char flag;
	sda = 1;   //释放数据线
	_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++){         //发送的一个字节等于8个bit,所以要循环8次
		scl = 0;                //scl拉低,让sda做好数据准备
		sda = dataSend & 0x80;  //0x80 = 1000 0000 获得dataSend的最高位,给sda
		_nop_();                //发送数据建立时间  
		scl = 1;                //scl拉高进行数据传输
		_nop_();                //数据发送的时间
		scl = 0;                //数据发送完毕,scl拉低
		_nop_();
		dataSend = dataSend << 1;    //每发送完一个数据,dataSend的数据就向左移动一位
	}
}
	
void Oled_Write_Cmd(char dataCmd){   //OLED写入指令函数

	IIC_Start();             //开始信号函数
	IIC_Send_Byte(0x78);     //写入从机地址
	IIC_ACK();               //应答信号函数
	IIC_Send_Byte(0x00);     //发送一个写命令的信号
	IIC_ACK();               //应答信号函数
	IIC_Send_Byte(dataCmd);  //开始写入指令
	IIC_ACK();
	
	IIC_Stop();              //终止信号函数
	
}

void Oled_Write_Data(char dataData){   //OLED写入数据函数

	IIC_Start();             //开始信号函数
	IIC_Send_Byte(0x78);     //写入从机地址
	IIC_ACK();               //应答信号函数
	IIC_Send_Byte(0x40);     //发送一个写数据的信号
	IIC_ACK();               //应答信号函数
	IIC_Send_Byte(dataData);  //开始写入数据
	IIC_ACK();
	IIC_Stop();              //终止信号函数
	
}

void Oled_Init(void){     //初始化OLED函数
 
	Oled_Write_Cmd(0xAE);
	Oled_Write_Cmd(0x00);
	Oled_Write_Cmd(0x10);
	Oled_Write_Cmd(0x40);
	Oled_Write_Cmd(0xB0);
	Oled_Write_Cmd(0x81);
	Oled_Write_Cmd(0xFF);
	Oled_Write_Cmd(0xA1);
	Oled_Write_Cmd(0xA6);
	Oled_Write_Cmd(0xA8);
	Oled_Write_Cmd(0x3F);
	Oled_Write_Cmd(0xC8);
	Oled_Write_Cmd(0xD3);
	Oled_Write_Cmd(0x00);
	Oled_Write_Cmd(0xD5);
	Oled_Write_Cmd(0x80);
	Oled_Write_Cmd(0xD8);
	Oled_Write_Cmd(0x05);
	Oled_Write_Cmd(0xD9);
	Oled_Write_Cmd(0xF1);
	Oled_Write_Cmd(0xDA);
	Oled_Write_Cmd(0x12);
	Oled_Write_Cmd(0xDB);
	Oled_Write_Cmd(0x30);
	Oled_Write_Cmd(0x8D);
	Oled_Write_Cmd(0x14);
	Oled_Write_Cmd(0xAF);
}

void Oled_Clear()       //清屏函数
{
	int 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);
		//一共有128列,0~127
		for(j=0;j<128;j++)
		{
			Oled_Write_Data(0);
 
		}
	}
}

void main()
{
	Oled_Clear();           //调用清屏函数
	Oled_Init();            //初始化OLED
	Oled_Write_Cmd(0x20);   //选择一个位置,确认页寻址地址
	Oled_Write_Cmd(0x02);
	Oled_Write_Cmd(0xB0);   //选择PAGE0,可以配置8次,分别是B0-B7
	Oled_Write_Data(0x08);  //显示一个点
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	
	Oled_Write_Cmd(0xB5);
	Oled_Write_Cmd(0x00);   //指定列的初始地址
	Oled_Write_Cmd(0x10);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	
	Oled_Write_Cmd(0xB6);
	Oled_Write_Cmd(0x00);   //指定列的初始值
	Oled_Write_Cmd(0x10);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	Oled_Write_Data(0x08);
	
	Oled_Write_Cmd(0x0f);
	Oled_Write_Cmd(0x17);
	Oled_Write_Data(0x08);
	
	while(1);              //防止程序退出
	
}

3、执行结果:

九、OLED显示图片

1、先用画图板画一张图片,图片要求如下:

图片的像素要求:128x64

保存的图片格式为:单色位图(bmp)格式

 

 2、打开字模软件——点阵液晶取模.EXE

3、进行字体设置:点击参数设置,然后点击文字输入区字体选择

4、设置其他选项:勾选纵向取模、字节倒序、保留、任何时候都加0

 5、回到基本操作界面,点击打开图像图标,把画图板画的那张图片打开放进去

 6、获取图像的参数数据:在取模方式中,选择C51格式,查看下方生成了此图片的点阵图

 7、把上述的图片点阵图数据复制到代码中,用一个函数封装起来,总体代码如下:

#include "reg52.h"
#include "intrins.h"

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

void IIC_Start(){   //起始信号函数

	scl = 0;   //防止雪花
	scl = 1;
	sda = 1;
	_nop_();   //延时5μs
	sda = 0;
	_nop_();
}

void IIC_Stop(){    //终止信号函数
	
	scl = 0;   //防止雪花
	scl = 1;
	sda = 0;
	_nop_();
	sda = 1;
	_nop_();
	
}

char IIC_ACK(){     //应答信号函数

	char flag;
	sda = 1;   //释放数据线
	_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++){         //发送的一个字节等于8个bit,所以要循环8次
		scl = 0;                //scl拉低,让sda做好数据准备
		sda = dataSend & 0x80;  //0x80 = 1000 0000 获得dataSend的最高位,给sda
		_nop_();                //发送数据建立时间  
		scl = 1;                //scl拉高进行数据传输
		_nop_();                //数据发送的时间
		scl = 0;                //数据发送完毕,scl拉低
		_nop_();
		dataSend = dataSend << 1;    //每发送完一个数据,dataSend的数据就向左移动一位
	}
}
	
void Oled_Write_Cmd(char dataCmd){   //OLED写入指令函数

	IIC_Start();             //开始信号函数
	IIC_Send_Byte(0x78);     //写入从机地址
	IIC_ACK();               //应答信号函数
	IIC_Send_Byte(0x00);     //发送一个写命令的信号
	IIC_ACK();               //应答信号函数
	IIC_Send_Byte(dataCmd);  //开始写入指令
	IIC_ACK();
	
	IIC_Stop();              //终止信号函数
	
}

void Oled_Write_Data(char dataData){   //OLED写入数据函数

	IIC_Start();             //开始信号函数
	IIC_Send_Byte(0x78);     //写入从机地址
	IIC_ACK();               //应答信号函数
	IIC_Send_Byte(0x40);     //发送一个写数据的信号
	IIC_ACK();               //应答信号函数
	IIC_Send_Byte(dataData);  //开始写入数据
	IIC_ACK();
	IIC_Stop();              //终止信号函数
	
}

void Oled_Init(void){     //初始化OLED函数
 
	Oled_Write_Cmd(0xAE);
	Oled_Write_Cmd(0x00);
	Oled_Write_Cmd(0x10);
	Oled_Write_Cmd(0x40);
	Oled_Write_Cmd(0xB0);
	Oled_Write_Cmd(0x81);
	Oled_Write_Cmd(0xFF);
	Oled_Write_Cmd(0xA1);
	Oled_Write_Cmd(0xA6);
	Oled_Write_Cmd(0xA8);
	Oled_Write_Cmd(0x3F);
	Oled_Write_Cmd(0xC8);
	Oled_Write_Cmd(0xD3);
	Oled_Write_Cmd(0x00);
	Oled_Write_Cmd(0xD5);
	Oled_Write_Cmd(0x80);
	Oled_Write_Cmd(0xD8);
	Oled_Write_Cmd(0x05);
	Oled_Write_Cmd(0xD9);
	Oled_Write_Cmd(0xF1);
	Oled_Write_Cmd(0xDA);
	Oled_Write_Cmd(0x12);
	Oled_Write_Cmd(0xDB);
	Oled_Write_Cmd(0x30);
	Oled_Write_Cmd(0x8D);
	Oled_Write_Cmd(0x14);
	Oled_Write_Cmd(0xAF);
}

void Oled_Clear()       //清屏函数
{
	int 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);
		//一共有128列,0~127
		for(j=0;j<128;j++)
		{
			Oled_Write_Data(0);
 
		}
	}
}

/*--  宽度x高度=128x64  --*/

code unsigned char bmpImager[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0xFC,0xFC,0xF8,0x00,0x80,0x80,0x80,0x80,0x80,
0x00,0x00,0x00,0xF0,0xF0,0xF8,0x78,0x7C,0x3C,0x3C,0x1C,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x80,0xC0,0xE0,0xE0,0xF0,0xF8,0xF8,0x7C,
0x3C,0x3C,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x1E,0x1E,0x1E,0x0E,0x0F,0xBF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0x7B,0x03,
0x00,0x00,0xFF,0xFF,0xFF,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0x00,0x00,0x00,0x80,
0xF0,0xF8,0xFC,0x3E,0x1E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x1E,0x1C,0x3C,0x78,0x70,
0xF0,0xE0,0xC0,0x80,0x00,0x80,0xE0,0xF0,0xF8,0x78,0x3C,0x3E,0x1E,0x0F,0x0F,0x07,
0x07,0x0F,0x1E,0x3C,0xF8,0xF0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x38,0x7C,0x3C,0x3E,0x1F,0x1F,0x0F,0x07,0x07,0x0F,0x0F,0x0F,0x0E,0x0E,0x0E,
0x0E,0x0E,0x0E,0x0E,0x8E,0x8E,0x8E,0xFE,0xFE,0xFE,0xFE,0x8E,0x8E,0x8E,0x0E,0x0E,
0x0E,0x0E,0x0E,0x0E,0x0E,0x0F,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x80,0x9C,0xDC,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0x3F,
0xE7,0xE0,0xFF,0xFF,0xFF,0x01,0x01,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,
0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x03,0x07,0x0F,0x1F,0x1F,0x0F,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xE1,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,0x07,0xFF,0xFF,0xFF,0x1F,0x07,0xFF,0xFF,0xFF,0x03,0x03,0x03,0x03,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x07,0x07,0x07,0x07,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x1F,0xFF,0xFF,0xFC,
0x00,0x73,0x7F,0x7F,0x7F,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x07,
0x7F,0xFF,0xFC,0xC0,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,
0x80,0xE0,0xF8,0xFF,0x7F,0x1F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0E,0x0F,0x0F,0x0F,0x07,0x07,0x07,
0x07,0x07,0x07,0x07,0x07,0x07,0x07,0xFF,0xFF,0xFF,0x07,0x07,0x07,0x07,0x07,0x07,
0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0xE0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xC7,0xC7,0x87,0x80,0x80,0x80,0x00,0x00,0x00,
0x00,0x00,0x01,0x07,0x1F,0x7F,0x7C,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF8,0x7C,0x3E,0x3F,
0x0F,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xF8,0xF8,0xFC,0x3C,0x3E,0x1F,0x1F,0x0F,0xE0,0xE0,0xE0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0xF0,0x70,0xFF,0xFF,0xFF,0xE0,0xE0,0xE0,0x80,
0x80,0x1C,0xBE,0xFE,0xFE,0xFF,0xFF,0x9F,0xE7,0xFF,0xFF,0xFF,0xBF,0x80,0x80,0x80,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x0F,0x1F,0x7E,0xFE,0xF0,0xE0,
0xC0,0xC0,0xE0,0xF0,0xF0,0xF8,0x7C,0x3E,0x1F,0x0F,0x07,0x01,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x77,0x7F,0x7F,0x7F,0x70,0x70,0x70,0x70,0xFF,0xFF,0xFF,0x70,0x70,0x70,0x70,
0xF0,0xF0,0xF0,0xE0,0x40,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x3F,0x00,0xFF,0xFF,0xFF,0x03,0x03,0x07,0x87,
0xE7,0xFE,0xFF,0xFF,0x1F,0x0F,0x07,0x0F,0x1F,0x3F,0xFF,0xFF,0xFB,0xE3,0xE3,0x83,
0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0xC0,0xC0,0xC0,0xE0,
0xF0,0xF8,0xF8,0x78,0x38,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
0x00,0x38,0x79,0xF8,0xF8,0xF0,0xE0,0xE0,0xC0,0xC0,0x80,0x80,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,0x07,0x07,0x07,0x00,0x00,0x00,0x03,
0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x07,0x07,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x03,0x03,0x01,
0x01,0x01,0x00,0x00,0x0E,0x1E,0x1E,0x3E,0xFC,0xFF,0xFF,0x7F,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x03,0x03,0x03,0x07,0x07,0x07,0x0F,0x0F,0x0F,
0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};


void Oled_Show_Image(unsigned char *image)      
{
	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);
		//一共有128列,0~127
		for(j=128 * i;j<(128*(i+1));j++)
		{
			Oled_Write_Data(image[j]);
		}
	}
}
	
void main()
{
	
	Oled_Clear();           //调用清屏函数
	Oled_Init();            //初始化OLED
	Oled_Write_Cmd(0x20);   //选择一个位置,确认页寻址地址
	Oled_Write_Cmd(0x02);
	//Oled_Write_Cmd(0xB0);   //选择PAGE0,可以配置8次,分别是B0-B7
	
	Oled_Show_Image(bmpImager);

	while(1);              //防止程序退出
	
}

执行结果:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/156387.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UI设计师与UE设计师有什么区别?

设计在我们的生活中扮演着重要的角色&#xff0c;但是面对越来越多的专业术语和相近的岗位职责&#xff0c;人们总是困惑&#xff1a;明明是差不多的岗位&#xff0c;为什么要整那么多的词&#xff1f;其实&#xff0c;在它们神似的外表下&#xff0c;潜藏着巨大的差异&#xf…

虹科分享 | 实时操作系统INtime RTOS第7版功能更新介绍

INtime简介 INtime是专为基于PC的嵌入式解决方案而设计的可扩展实时操作系统&#xff0c;功能包括动态控制多个主机上多个节点&#xff08;核心&#xff09;上的进程&#xff0c;以及系统所有节点之间的丰富进程间通信&#xff0c;可应用于多核x86兼容处理器的非对称多处理(AM…

【阶段三】Python机器学习17篇:机器学习项目实战:随机森林回归模型

本篇的思维导图: 项目实战(随机森林回归模型) 项目背景 作为国家的支柱产业,房地产的稳定发展关乎国际民生。近几年,房地产价格飞速上涨,连创新高。在这种情况下研究房价的影响因素,具有重要的理论和现实意义。弄清影响房价的主要经济因素,探究我国房地产投资是…

calc()方法的使用

calc实现css中动态计算 环境 根据元素高度的变化,动态控制padding值 <marquee:name"up index"behavior"scroll"scrolldelay"30"direction"up"v-else-if"item.scrollPocition 3 ? true : false":style"{--positi…

核心乐理---五线谱基础

音符 音符的长度 音符的长度都是相对的定义 一般来说讲全音符设为一拍&#xff0c;但如果将二分音符设为一拍的话&#xff0c;全音符就是两拍 附点音符 可以在音符后跟上一个小点来改变音符的长度&#xff0c;如果一个音符后面跟了n个原点&#xff0c;它的长度就会变为原来的…

【学习记录】阿里云服务器+宝塔

环境&#xff1a;阿里云服务器&#xff0c;linux Centos系统 一、安装宝塔 参考链接&#xff1a;阿里云 ECS 服务器入门使用宝塔安装使用 1、进入云服务器控制台&#xff0c;打开远程连接 2、初次使用&#xff0c;可重置登录密码和连接密码 这是远程连接时需要输入的密码 这…

测试开发基础 | 计算机网络篇(二):物理层与数据链路层

计算机网络知识是自动化测试等技术基础&#xff0c;也是测试面试必考题目。霍格沃兹测试学院特别策划了本系列文章&#xff0c;将带大家一步步夯实计算机网络的基础知识。一、物理层由于物理层知识在互联网软件研发工作中用到的并不多&#xff0c;所以可以仅做一个简单的了解。…

Prompt: No !!!

Prompt is Not Good. Prompt 这个方法实际上并不是很好 Prompt 可以是in-context learning的一种。prompt-based learning has taken NLP by storm!! prompt-based的方法在NLP中引起风暴。但&#xff0c;Prompt-based的方法实际上不太行&#xff1a; 1. Inefficiency: The pro…

基于python的企业编码生成系统 (完整的代码+项目说明)

《企业编码生成系统》程序使用说明 在PyCharm中运行《企业编码生成系统》即可进入如图1所示的系统主界面。在该界面中可以选择要使用功能对应的菜单进行不同的操作。在选择功能菜单时&#xff0c;只需要输入对应的数字即可。 图1 系统主界面 具体的操作步骤如下&#xff1a;…

匿名内部类的理解(java + Android)

是不是有同学跟我一样学了知识&#xff0c;不使用&#xff0c;一段时间就忘了&#xff1f; 今天说说java的匿名内部类这个东西&#xff0c;今天就因为这个东西被程序媛欺负了&#xff0c;我心里难受啊。 匿名内部类的官方说法特别不容易理解&#xff0c;是从"有没有名字…

全网惟一面向软件测试人员的Python基础教程-在Python中如何把列表当成队列来进行使用?

全网惟一面向软件测试人员的Python基础教程 起点&#xff1a;《python软件测试实战宝典》介绍 第一章 为什么软件测试人员要学习Python 第二章 学Python之前要搞懂的道理 第三章 你知道Python代码是怎样运行的吗&#xff1f; 第四章 Python数据类型中有那些故事呢&#xff1f;…

Linux的SOCKET编程详解(转载)

Linux的SOCKET编程详解1. 网络中进程之间如何通信进 程通信的概念最初来源于单机系统。由于每个进程都在自己的地址范围内运行&#xff0c;为保证两个相互通信的进程之间既互不干扰又协调一致工作&#xff0c;操作系统为进程通信提供了相应设施&#xff0c;如UNIX BSD有&#x…

大漠插件最新版7.2302

工具名称:大漠插件最新版7.2302工具简介:/大漠插件v7.2302更新时间2023年1月9日更新内容1. 驱动支持win10(19045)和win11(22621)2. 综合工具增加功能,在定义文字输入框激活时,按下alt会输入最后一次输入的文字/【插件特色】1. 文字识别 领域&#xff0c;目前插件界&#xff0c;…

B. Gardener and the Array(贪心)

传送门题意&#xff1a;给你n个数&#xff0c;问你是否存在不同的两个子区间&#xff0c;使这两个子区间的或结果相同。注&#xff1a;因为数据范围太大&#xff0c;所以每个数都由他的二进制数表示&#xff1a;每一行第一个数m表示有几个二进制数&#xff0c;后面m个数代表2的…

陪诊小程序开发,谁更需要陪诊服务

我们去过医院的都很清楚&#xff0c;医院的看病流程是很繁琐&#xff0c;医院不仅大&#xff0c;科室还划分的又细又多。对于一些在外打拼整天忙的顾不得看病就医的打工人&#xff0c;还有一些跟随子女去异地生活养老就医的老年人&#xff0c;还有一些没人陪伴独居生活的年轻人…

89、【栈与队列】leetcode ——101. 对称二叉树:先序递归与非递归+层次遍历(C++版本)

题目描述 原题链接&#xff1a;101. 对称二叉树 解题思路 一、先序遍历 1、递归 设置两个指针进行遍历对比&#xff0c;分别指向互相对称位置&#xff1a;左子树的左孩子与右子树的右孩子互对称&#xff0c;左子树的右孩子与右子树的左孩子互对称。 每次遍历前先判定对称位…

【源码解析】Springboot整合ElasticSearch客户端的源码解析

Springboot整合ElasticSearch客户端的源码解析 ElasticSearch版本 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId><version>2.2.5.RELEASE</version>&…

[蓝桥杯 2022 国 A] 环境治理(C++,Floyd,二分法)

题目描述 LQ 国拥有 nnn 个城市&#xff0c;从 000 到 n−1n - 1n−1 编号&#xff0c;这 nnn 个城市两两之间都有且仅有一条双向道路连接&#xff0c;这意味着任意两个城市之间都是可达的。每条道路都有一个属性 DDD&#xff0c;表示这条道路的灰尘度。当从一个城市 A 前往另…

linux 中用rancher k8s 部署springboot项目

前期条件: linux--》ECS服务器: rancher集群: 操作流程: 1、制作简单springboot项目使用docker生成镜像项目端口:8080并写一个测试controller

Go 1.19.3 interface原理简析

interface 接口&#xff0c;分为有方法签名的接口和空接口 interface{fn()…} 有方法签名的接口&#xff0c;底层运行时结构 iface iface src/runtime/runtime2.go type iface struct {tab *itab // 接口类型itab, i-table的缩写data unsafe.Pointer // 接口值指针…