I2C通讯协议——使用攻略
I2C通讯协议——使用攻略
1、基本介绍
调I2C时序,主要在调数据写入write_I2C和数据读取read_I2C的机制。I2C主要实现数据的传输,使主机和从机的相互响应。它有一种数据传送机制。总结起来为:起始信号,终止信号、应答信号,读字节,写字节,数据读取和数据写入。
I2C基本架构:
Start_I2C
Stop_I2C
readack 读取应答信号
sendack and sendnack 输出应答或非应答
sendbyte
readbyte
write_I2C
read_I2C
2、数据是如何传输的
SDA和SCL变化情况:
所有数据传输均起始于一个start,终于一个stop.
Start_I2C定义:SCL为高时,SDA从高到低转换;
Stop_I2C定义:SCL为高时,SDA从低到高转换;
数据有效性:SCL为高时,SDA的数据必须稳定;
只有SCL变低时,SDA的状态才能跳变。
3、数据读取和写入的示例:
Write_I2C:start->slave address+0+ACK+数据包(byte+ack+…+byten+Nack)+stop
Read_I2C:start->slave address+1+ACK+数据包(byte+ack+…+byten+Nack)+stop
注意:关于slave address是7位的一个字节,write是0位,read是1位;
示例:slave address为50H(1010000)
则写地址在其后加一位0,即变成(10100000),为A0
读地址在其后加一位1,即变成(10100001),为A1;
具体为: write_I2C
{
Start_I2C;
sendbyte();//传送地址与写入标记
readack;
sendbyte();//传送字节
readack;
Stop_I2C;
}
read_I2C
{
Start_I2C;
sendbyte();//传送地址与读取标记
readack;
readbyte();//读取字节
sendack and sendnack
Stop_I2C;
}
4、应用示例
Define address:根据芯片规格书定义读写地址
设置端口:SDA/SCL/INT
缓存buffer: 主控端的写入和读取资料缓存
(1) I2C的起始位
void I2C_sendStart() //开始位
{
SDA=1; /发送起始条件的数据信号/
SCL=1;
SDA=0; /发送起始信号/
Delay_us(1);
SCL=0;
}
(2)I2C的结束位
Void sendstop()
{
SCL=0;
SDA=0; /发送结束条件的数据信号/
SCL=1;
while(SCL!=1) { };
Delay_us(1);
SDA=1; Delay_us(1);
}
(3)读取I2C的应答标志位
Unsigned char readACK() //读取应答信号
{
SCL=0;
SDA=1; /此处为释放SDA 总线,由从从机发出低电平应答/
nop();
SCL=1;
nop();
if(SDA)
return 1; //no ACK
else
return 0; //ACK
}
(4)主控端送出应答信号
void sendACK() //输出应答信号
{
SCL=0;
SDA=0;
nop();
SCL=1;
}
void sendNOACK() //输出无应答信号
{
SCL=0;
SDA=1;
nop();
SCL=1;
}
(5)主控端写入一个字节到从机
void sendByte(uchar dat) //写一个字节
{
uchar i;
for(i=0;i<8;i++)
{
SCL=0; /*钳住I2C 总线,准备发送数据 */
if(dat&0x80)
SDA=1;
else
SDA=0;
nop();
nop();
SCL=1;
dat<<=1;
}
}
(6)主控端对从机读取一个字节
uchar readByte() //读一个字节
{
uchar i, dat=0;
for(i=0;i<8;i++)
{
SCL=0;
SDA=1;
nop();
dat<<=1;
SCL=1;
if(SDA==1)
dat|=0x01;
}
return dat;
}
(7)主控端数据写入
bit writeIIC(uchar addrW, uchar *writeData, uchar length)
{
uchar i;
bit ACK;
sendStart();
sendByte(addrW); //传送地址与写入标记
ACK = readACK();
if (ACK)
{
sendStop(); //地址不正确或装置未连接,送出停止信号
return ACK;
}
for(i = 0; i<length; i++)
{
sendByte(writeData[i]);
ACK = readACK();
if (ACK)
{
sendStop(); //未接收到ACK,送出停止信号
return ACK;
}
}
sendStop(); //资料写入完成,送出停止信号
return ACK;
}
(8)主控端对从机数据读取
bit readIIC(uchar addrR, uchar *readData, uchar length)
{
uchar i;
bit ACK;
sendStart();
sendByte(addrR); //传送地址与读取标记
ACK = readACK();
if (ACK)
{
sendStop(); //地址不正确或装置未连接,送出停止信号
return ACK;
}
for(i = 0; i<length; i++)
{
readData[i] = readByte();
if(i<length-1)
sendACK();
else
sendNOACK(); //读取最后一笔资料,送出No ACK
}
sendStop(); //资料读取完成,送出停止信号
return ACK;
}
(9)调用数据写入和读取
writeIIC(address_W, &Write_Buffer,4);
readIIC(address_R, &Read_Buffer, 5);