一、IIC总线通信1、简介:
IIC 即Inter-Integrated Circuit(集成电路总线),I2C总线是PHLIPS公司推出的一种串行总线, I2C总线只有两根双向信号线。一根是
数据线SDA,另一根是
时钟线SCL。
每个接到I2C总线上的器件都有唯一的地址。主机与其它器件间的数据传送可以是由主机发送数据到其它器件,这时主机即为发送器。由总线上接收数据的器件则为接收器。
2、常用的串行扩展总线有:(1)、I2C (Inter IC BUS)总线
(2)、单总线(1-WIRE BUS)
(3)、SPI(Serial Peripheral Interface)总线等。
3、IIC总线电路接法
I2C总线通过上拉电阻接正电源。当总线空闲时,两根线均为高电平。
4、IIC总线通信协议(1)起始和终止信号
SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号; SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。(2)应答和非应答
IIC 总线协议规定,每传送一个字节数据后,都要有一个应答信号以确定数据传送是否被对方收到。应答信号由
接受设备产生,在
SCL为高电平期间,接受设备将SDA拉低为低电平,表示数据传输正确,产生应答。
(3)数据传送数据位的有效性规定
I2C总线进行数据传送时,时钟信号为
高电平期间,数据线上的数据必须保持稳定,只有在
时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
5、IIC通信基本函数(1)起止信号
i2c_Start()
{
SDA = 1; //SCL为高电平时,SDA 出现一个下跳沿表示I2C总线启动
SCL = 1;
i2c_Delay();
SDA = 0;
i2c_Delay();
SCL = 0; // 启动后将SCL点平拉低
i2c_Delay();
}
(2)终止信号
void i2c_Stop()
{
SDA = 0; //当SC高电平时,SDA出现一个上升沿表示I2C总线停止
SCL = 1;
i2c_Delay();
SDA = 1;
i2c_Delay();
}
(3)发送数据
void i2c_SendByte(unsigned char Byte)
{
unsigned char i = 0;
for (i = 0; i < 8; i++)
{
if(Byte & 0x80) //IIC规定下发送高位数据
{
SDA = 1;
}
else
SDA = 0;
SCL = 1; //在SCL为高电平期间写入数据
i2c_Delay();
SCL = 0;
Byte <<= 1;
if (i == 7)
SDA = 1; //在发送完数据后将SDA拉高
i2c_Delay();
}
}
(4)接收数据
unsigned char i2c_ReadByte()
{
unsigned char i = 0;
unsigned char value = 0;
for (i = 0; i < 8; i++)
{
value <<= 1; //先读取高位
SCL = 1; //SCL 为高电平时读取数据
i2c_Delay();
if(SDA)
{
value++;
}
SCL = 0;
i2c_Delay();
}
return value;
}
(5)发送应答信号
void char i2c_Ack()
{
SDA = 0; //SCL为高电平时间SDA拉低表示应答
i2c_Delay();
SCL = 1;
i2c_Delay();
SCL = 0;
i2c_Delay();
SDA = 1;
i2c_Delay();
}
(6)发送非应答信号
void i2c_NAck()
{
SDA = 1; //SCL高电平期间SDA拉高表示非应答
i2c_Delay();
SCL = 1;
i2c_Delay();
SCL = 0;
i2c_Delay();
}
(7)等待应答
unsigned char i2c_WaitAck()
{
unsigned char ret;
SDA = 1;
i2c_Delay();
SCL = 1; //把SCL拉高读取SDA的点平高低,低电平表示应答
i2c_Delay();
if(SDA == 1)
{
ret = 1;
}
else
ret = 0;
SCL = 0;
i2c_Delay();
return ret;
}
(8)检查IIC设备总线
unsigned char i2c_CheckDevice(unsigned char _Address)
{
unsigned char UcAck;
if (SDA == 1 && SCL == 1)
{
i2c_Start();
i2c_SendByte(_Address|I2C_WR); //发送地址
ucAck = i2c_WaitAck(); //等待接收应答
i2c_Stop(); //停止信号
return ucAck;
}
return 1;
}