IIC通信需要一根时钟线(SCL)和一根数据线(SDA)。IIC协议中数据传输的单位是字节,也就是8位。但是要用到9个时钟:前面8个时钟用来传输8数据,第9个时钟用来传输回应信号。传输时,先传输最高位(MSB)。数据位有8位,1-7位为数据,8为读写位,9为应位;SDA上传输的数据必须在SCL为高电平期间保持稳定,SDA上的数据只能在SCL为低电平期间变化
1、起始信号
SCL为高电平时,SDA山高电平向低电平跳变,开始传送数据
void I2C_Start(void)
{
SCL_H;
SDA_H;
I2C_Delay(100);
SDA_L;
I2C_Delay(100);
}
2、结束信号
SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据
void I2C_Stop(void)
{
SDA_L;
SCL_H;
I2C_Delay(100);
SDA_H;
I2C_Delay(100);
}
3、应答信号
接收器在接收到8位数据后,在第9个时钟周期,拉低SDA
/*产生一个应答*/
void I2C_ACK(void)
{
SCL_L;
SDA_L;
I2C_Delay(100);
SCL_H;
I2C_Delay(100);
}
/*获取应答*/
uint8_t I2C_GetAck(void)
{
int i = 0;
SDA_H;
SCL_L;
I2C_Delay(100);
SCL_H;
if(SDA_IN != 0)
{
i++;
if(i == 1000)
{
SCL_L;
return -1;
}
}
I2C_Delay(100);
SCL_L;
return 0;
}
4、非应答信号
接收器在接收到8位数据后,在第9个时钟周期,没被拉低SDA
void I2C_NACK(void)
{
SCL_L;
SDA_H;
I2C_Delay(100);
SCL_H;
I2C_Delay(100);
}
5、写操作
* 主芯片要发出一个start信号
* 然后发出一个设备地址(用来确定是往哪一个芯片写数据),方向(读/写,0表示写,1表示读)
* 从设备回应(用来确定这个设备是否存在),然后就可以传输数据
* 主设备发送一个字节数据给从设备,并等待回应
* 每传输一字节数据,接收方要有一个回应信号(确定数据是否接受完成),然后再传输下一个数据。
* 数据发送完之后,主芯片就会发送一个停止信号。
下图:白色背景表示"主→从",灰色背景表示"从→主"
void I2C_WriteByte(uint8_t data)
{
uint8_t i = 0;
for(i=0;i<8;i++)
{
SCL_L;
I2C_Delay(100);
if(data & 0x80)
{
SDA_H;
}
else
{
SDA_L;
}
data <<=1;
SCL_L;
I2C_Delay(100);
}
I2C_GetAck();
}
6、读操作
* 主芯片要发出一个start信号
* 然后发出一个设备地址(用来确定是往哪一个芯片写数据),方向(读/写,0表示写,1表示读)
* 从设备回应(用来确定这个设备是否存在),然后就可以传输数据
* 从设备发送一个字节数据给主设备,并等待回应
* 每传输一字节数据,接收方要有一个回应信号(确定数据是否接受完成),然后再传输下一个数据。
* 数据发送完之后,主芯片就会发送一个停止信号。
下图:白色背景表示"主→从",灰色背景表示"从→主"
uint8_t I2C_ReadByte(uint8_t ack)
{
uint8_t i = 0;
uint8_t data = 0;
SDA_H;
for(i=0;i<8;i++)
{
SCL_L;
I2C_Delay(100);
SCL_H;
I2C_Delay(100);
data <<=1;
if(SDA_IN == 1)
{
data++;
}else
{
data = data;
}
}
if(ack == 0)
{
I2C_ACK();
}
else if(ack == 1)
{
I2C_NACK();
}
return data;
}