IIC,inter ic bus,两线制串行总线标准,由一根串行数据线SDA和一根串行时钟线SCL组成,可以在一条总线上连接多个外设,主机通过器件地址识别从机。
发送数据之前,需要有一个启动信号start,
IIC总线上的主机在启动信号之后发送一个或多个字节的数据,字节的高位在前,低位在后。
主机每发送完一个字节(包括地址数据和普通数据)就要等待从机返回一个应答信号。
应答信号是在从机接收到主机发送的一个字节后在下一次时钟到来时,SDA信号线上给出一个低电平。主机必须等待从机回应一个应答信号,如果没有收到应答信号,则主机必须发送停止信号或者再次重新启动。
发送完一字节数据,主机如果还想继续发送数据,则可以继续发送数据。如果想向其他器件发送数据,则可以再次发送地址,其后通讯流程同上。
数据传输信号
数据传输:SCL为高电平时,SDA线若保持稳定,那么SDA上是在传输数据bit;
若SDA发生跳变,则用来表示一个会话的开始或结束(后面讲)
数据改变:SCL为低电平时,SDA线才能改变传输的bit,此时SDA数据无效,SCL为高时数据有效。
开始和结束信号
开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
应答信号
Master每发送完8bit数据后等待Slave的ACK。
即在第9个clock,若从IC发ACK,SDA会被拉低。
若没有ACK,SDA会被置高,这会引起Master发生RESTART或STOP流程,如下所示:
关于SDA和SCL,当SCL位高电平时,SDA上的数据才有效,SCL位低电平时SDA的数据被忽略。
关于IIC总线的器件地址
总线上的主机在发送数据前先发送要与之通讯的从机的器件地址,主机通过对这个地址的呼叫来确定对总线上拥有该地址的器件进行数据交换。
进行IIC通信时发送启动信号后发送的一字节地址数据,地址数据时规范的。
7 - 1位地址,第7位是地址的最高位,第0位表示数据的传送方向,
= 0 ,表示写,数据从主机到从机
= 1,表示读,数据从从机到主机。
有一个特殊的地址叫广播地址,如果使用该地址进行通讯,则总线上所有的器件均能收到。广播地址全0.
IIC最多能接设备数 2^7-1 = 127 个。
IIC速度:低速100kbit/s,高速400kbit/s,最高1Mbit/s。
关于IIC总线的冲突仲裁
由于总线上挂载了多个器件,所以有可能同一时刻多个器件争取总线控制权。注意,总线上挂接的器件都有权利成为主机。
起始信号
//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
停止信号
//产生IIC停止信号
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL=1;
IIC_SDA=1;//发送I2C总线结束信号
delay_us(4);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
有效应答
//产生ACK应答
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
无效应答
//不产生ACK应答
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
发送单字节
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2); //对TEA5767这三个延时都是必须的
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
接收单字节
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
if (!ack)
IIC_NAck();//发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}