i2c总线的基本操作(关于I2C总线的详解和实现)
i2c总线的基本操作(关于I2C总线的详解和实现)I2C的起始信号和结束信号I2C采用的是主从通信方式,所以在通信之前,由主设备发送一个起始信号,开始数据的传送,并且在结束通信时,也必须由主设备发送一个结束信号,表示通信结束。3、 I2C是8位的双向数据传输,通信是高位在前,地位在后。4、 传输速率标准模式下100Kbit/s,快速模式下 400Kbit/s 高速模式下可达3.4Mbit/s5、 I2C发送从机地址,地址有7位,紧跟着的第8位,是代表方向为。0表示写,1表示读。
I2C总线是两条线,一条串行数据(SDA),一条串行时钟(SCL),两根线能与总线上的设备实现通信,每个器件都有唯一的地址,而且都可以作为一个发送器一个接收器(根据器件功能决定)。
I2C特点:
1、 只需要两根线就可以实现数据传输:一条串行数据(SDA),一条串行时钟(SCL)。
2、 每个连接到总线上的器件都有一个唯一的地址。
3、 I2C是8位的双向数据传输,通信是高位在前,地位在后。
4、 传输速率标准模式下100Kbit/s,快速模式下 400Kbit/s 高速模式下可达3.4Mbit/s
5、 I2C发送从机地址,地址有7位,紧跟着的第8位,是代表方向为。0表示写,1表示读。
I2C采用的是主从通信方式,所以在通信之前,由主设备发送一个起始信号,开始数据的传送,并且在结束通信时,也必须由主设备发送一个结束信号,表示通信结束。
I2C的起始信号和结束信号
起始信号: (SCL)时钟线为高电平时,(SDA)数据线由高电平向低电平跳变,表示起始信号。
下面是51单片机对应的代码部分
起始信号代码
void I2C_Start(void)
{
I2C_SDA=1;
I2C_SCL=1;
I2C_Delay();
I2C_SDA=0;
I2C_Delay();
I2C_SCL=0;
}
结束信号代码
void I2C_Stop(void)
{
I2C_SDA=0;
I2C_SCL=0;
I2C_Delay();
I2C_SCL=1;
I2C_Delay();
I2C_SDA=1;
}
I2C应答信号
主设备每次发送完一个8bit数据,后面会在第9位等待从机一个应答信号,这时候我们会释放SDA数据线,拉高电平,当从机应答SDA会被拉低,若从机没有应答,SDA还是高电平,这样会引起主机(stop)结束本次流程。
主机发送数据给从机,主机等待从机应答,收到从机应答代表数据传输完成,下面是等待从机应答的代码
Unsigned char I2C_WaitSlave_Ack()
{
unsigned char cnt=0;
I2C_SDA=1;
I2C_Delay();
I2C_SCL=1;
While(I2C_SDA)//等待从机应答
{
cnt ;
if(cnt>=200)//如果等待从机应答计数200次还没应答终止本次数据传输
{
I2C_Stop();
return 1;
}
}
I2C_SCL=0;
Return 0;
}
当我们发送数据给从机需要等待从机应答,同样的从机把我们需要的数据发给我们的时候主机也需要给从机一个应答,代表我们收到它传给我们的数据了,如果不应答代表我们结束了本次数据的传输。
下面用代码来实现这个过程
主机不应答代码
Void I2C_Master_NAck()
{
I2C_SDA=1;
I2C_Delay();
I2C_SCL=1;
I2C_Delay();
I2C_SCL=0;
}
主机应答代码
void I2C_Master_Ack()
{
I2C_SDA=0;
I2C_Delay();
I2C_SCL=1;
I2C_Delay();
I2C_SCL=0;
}
I2C位数据传输
I2C数据传输: 若SCL是高电平时,SDA保持当前稳定状态,那么SDA上传输一个Bit数据。
I2C数据改变:SCL是为低电平时,SDA才可以改变传输的bit数据,当SCL由低电平变为高电平时,SDA上的Bit数据就不能改变了,当SCL再变为低电平时,SDA就是一个有效的Bit数据了。
如果SCL高电平时 SDA电平发生了跳变,就有可能产生一个起始信号或者是结束信号。
发送数据给从机
Void I2C_Send_data(unsigned char dat)
{
Unsigned char i=0;
For(i=0;i<8;i )
{
I2C_SDA=(dat&0x80)>>7;
dat<<=1;
I2C_Delay();
I2C_SCL=1;
I2C_Delay();
I2C_SCL=0;
}
}
读取从机的数据,当从机把数据发给我们时,如果我们还想从 从机哪里读取数据就要给从机一个应答,如果不应答代表这次数据传输结束,下面代码最后加了一个条件语句就是实现这个功能的。
Void I2C_Read_Data(bit ack)
{
unsigned char dat=0;
Unsigned char i=0;
I2C_SDA=1;
For(i=0;i<8;i )
{
I2C_Delay();
I2C_SCL=1;
if(I2C_SDA)
dat=((dat<<1)|0x01);
else
dat<<=1;
I2C_Delay();
I2C_SCL=0;
}
If(ack)
I2C_Master_Ack();//应答
Else
I2C_Master_NAck();//不应答
Return dat;
}
喜欢的朋友支持关注和点赞