51单片机I2C通信协议

一.I2C介绍

I2C(Inter-Intergrated Circuit)通信协议是由飞利浦公司开发的一种串行总线,用于连接芯片和其它电路,能够实现简单、低成本的数字通信。51单片机作为一种常用的嵌入式系统芯片,通常采用I2C协议与外部设备通讯。

二.I2C的组成及特点

1.I2C协议使用两条线,即数据线(SDA)和时钟线(SCL),由主机控制总线的时序,从而实现设备之间的数据传输。

2.I2C协议具有以下特点:

(1)双向传输:数据可以在主机和从设备之间双向传输。

(2)多主机共享:多个主机可以共享总线。

(3)从设备寻址:主机可以向多个从设备发送数据,每个设备有一个唯一的地址。

(4)数据传输速率:I2C的数据传输速率通常较慢,最高速率为400kbps。

三、I2C总线传输协议 

1.数据位的有效性规定

只有SCL信号为低电平期间,SDA状态才允许变化,当SCL为高电平期间,数据线上的数据必须保持稳定 。

2.起始信号和停止信号

SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。 

3.I2C字节的接收与应答

每传输一个字节,后面跟随一个应答位。通过将 SDA 线拉低,来允许接收端回应发送端。ACK 为 一个低电平信号,当时钟信号为高时, SDA 保持低电平则表明接收端已成功接收到发送端的数据。
当主机作为发送器件时,如果从机上产生无响应信号(NACK) ,主机可以产生停止信号来退出数据传输,或者产生重复起始信号开始新一轮的数据传输。当主机作为接收器件时,发生无响应信号(NACK) ,从机释放 SDA 线,使主机产生停止信号或重复起始信号。
每一个字节必须保证是8位长度。数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。 

4.总线的寻址

I2C协议通过7位的寻址字节。D7-D1位组成从机的地址;D0位是数据传输的方向位,为“0”时表示主机向从机写数据,为“1”时表示由从机读取数据。

I2C总线的7位寻址过程如下:

  1. 发送起始信号:主设备向总线发送起始信号。

  2. 发送从设备地址:主设备将7位从设备地址和读/写位发送到总线上,地址格式为“11110XX”,其中“XX”表示从设备的地址。

  3. 等待从设备响应:主设备等待从设备对地址的响应。

  4. 发送读/写位:主设备向总线发送读/写位,用于指示数据传输的方向。

  5. 等待从设备响应:主设备等待从设备对读/写位的响应。

  6. 发送数据:如果是写操作,主设备向总线发送要写入从设备的数据;如果是读操作,主设备不需要发送数据,而是等待从设备发送数据。

  7. 结束传输:主设备向总线发送停止信号,结束本次数据传输。

四.I2C程序代码

I2C起始信号代码

sbit I2C_SCL=P2^1;
sbit I2C_SDA=P2^0;

void I2C_start(void)//产生I2C起始信号
{
	I2C_SDA=1;
	delay_10us(1);
	I2C_SCL=1;
	delay_10us(1);
	I2C_SDA=0;
	delay_10us(1);//当SCL为高电平时,SDA由高变为低
	I2C_SCL=0;
	delay_10us(1);//准备发送或接收数据
}

I2C停止信号代码

void I2C_stop(void)//I2C停止信号
{
	I2C_SDA=0;
	delay_10us(1);
	I2C_SCL=1;
	delay_10us(1);
	I2C_SDA=1;//当SCL为高电平时,SDA由低变为高
	delay_10us(1);
}

 I2C发送一个字节

void I2C_sendbyte(unsigned char byte)//I2C发送一个字节
{
	unsigned char i;
	I2C_SCL=0;
	for(i=0;i<8;i++)  //循环8次
	{
		I2C_SDA=byte&(0x80>>i);//(高位到低位)依次右移取出每一位放在SDA线上
		I2C_SCL=1;
		delay_10us(1);  
		I2C_SCL=0;
		delay_10us(1);  
		
	}
}

 I2C接收一个字节

unsigned char I2C_receivebyte(void)//I2C接收一个字节
{
	unsigned char i,byte=0x00;
	I2C_SDA=1;
	for(i=0;i<8;i++)
	{
	I2C_SCL=1;	
	if(I2C_SDA)
	{
		byte|=(0x80>>i);//把byte最高位置1
	}
	I2C_SCL=0;
	delay_10us(1);
}
return byte;
}

 I2C发送应答

void I2C_sendack(unsigned char ack)//I2C发送应答(0为应答,1为非应答)
{
	I2C_SDA=ack;
	I2C_SCL=1;
	delay_10us(1);
	I2C_SCL=0;
	delay_10us(1);
}

I2C接收应答

unsigned char I2C_receiveack(void)//I2C接收应答(0为应答,1为非应答)
{
	unsigned char ack;
	I2C_SDA=1;//释放SDA(主机SDA)
	delay_10us(1);
	I2C_SCL=1;//拉高SCL读取数据位
	delay_10us(1);
	ack=I2C_SDA;//从机SDA
	I2C_SCL=0;
	delay_10us(1);
	return ack;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值