C51单片机IIC协议的应用

总述:

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

1.起始信号

C51单片机IIC协议的应用_第1张图片

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

2.终止信号

C51单片机IIC协议的应用_第2张图片

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

3.应答信号

发送器每发送一个字节( 8 bit ),就在时钟脉冲 9 期间释放数据线,由接收器反馈一个应答信号。 应答信号为低电平时,规定为有效应答位(ACK ,简称应答位),表示接收器已经成功地接收了该字 节;
C51单片机IIC协议的应用_第3张图片
char IIC_ACK()
{
char flag;//????为什么这个位置要用char
sda = 1;//就在时钟脉冲9期间释放数据线
_nop_();
scl = 1;
_nop_();
flag = sda;
_nop_();
scl = 0;
_nop_();
return flag;

}

3.IIC协议发送一个字节封装。

C51单片机IIC协议的应用_第4张图片

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;//????搞不懂为什么dataSend << 1就是左移
}
}

2.OLED写命令,可以参考ssd1306手册和叁议电子oled说明书。

C51单片机IIC协议的应用_第5张图片

3.OLED寻址模式:页地址模式、水平地址模式、垂直地址模式。;页地址模式和水平地址模式用的比较多。

页地址模式:

C51单片机IIC协议的应用_第6张图片

写入0x08b00001000),显示如下

C51单片机IIC协议的应用_第7张图片

C51单片机IIC协议的应用_第8张图片

首先进行OLED初始化,初始化的代码是怎么来的呢?

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_Write_Cmd(char dataCmd)
{
// 1. start()
IIC_Start();
// 2. 写入从机地址 b0111 1000 0x78
IIC_Send_Byte(0x78); //???这个0x78是怎么得出来的
// 3. ACK
IIC_ACK();
// 4. cotrol 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_Clear()
{
unsigned char i,j; //-128 --- 127
for(i=0;i<8;i++){
Oled_Write_Cmd(0xB0 + i);//page0--page7 ??为什么是0xB0,为什么要叫i
//每个page从0列
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0x10);
//0到127列,依次写入0,每写入数据,列地址自动偏移
for(j = 0;j<128;j++){
Oled_Write_Data(0);
}
}
}

4.利用OLED来显示文字。



void main()
{
		unsigned char  i;
		//1. OLED初始化
		Oled_Init();
		//2. 选择一个位置
		//2.1 确认页寻址模式
		Oled_Write_Cmd(0x20);
		Oled_Write_Cmd(0x02);
		Oled_Clear();
		//2.2 选择PAGE0   1011 0000
		//								0xB0
		Oled_Write_Cmd(0xB0);
		Oled_Write_Cmd(0x00);
		Oled_Write_Cmd(0x10);
	
		for(i=0;i<16;i++){
			
				Oled_Write_Data(l1[i]);
		}
		for(i=0;i<16;i++){
			
				Oled_Write_Data(p1[i]);
		}
		for(i=0;i<16;i++){
			
				Oled_Write_Data(j1[i]);
		}
		for(i=0;i<16;i++){
			
				Oled_Write_Data(s1[i]);
		}
		for(i=0;i<16;i++){
			
				Oled_Write_Data(g1[i]);
		}
		
		
		Oled_Write_Cmd(0xB1);
		Oled_Write_Cmd(0x00);
		Oled_Write_Cmd(0x10);
		for(i=0;i<16;i++){
			
				Oled_Write_Data(l2[i]);
		}
		for(i=0;i<16;i++){
			
				Oled_Write_Data(p2[i]);
		}
		for(i=0;i<16;i++){
			
				Oled_Write_Data(j2[i]);
		}
		for(i=0;i<16;i++){
			
				Oled_Write_Data(s2[i]);
		}
		for(i=0;i<16;i++){
			
				Oled_Write_Data(g2[i]);
		}
		while(1);
}

5.利用OLED来传入图片信息

void Oled_Show_Image(unsigned char *image)
{
	unsigned char i; //-128 --- 127
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(image[j]);
		}
	}
}

你可能感兴趣的:(单片机,嵌入式硬件)