IIC总线协议介绍
1、IIC介绍:
Inter Integrated Circuit,同步、串行、半双工通信总线。
2、IIC总线结构图
① 由时钟线SCL和数据线SDA组成,并且都接上拉电阻,确保总线空闲状态为高电平。
②总线支持多设备连接,允许多主机存在,每个设备都有唯一地址。
③连接到总线上的数目受总线的最大电容400pf限制。
④数据传输速率:标准模式100k bit/s,快速模式400k bit/s,高速模式3.4M bit/s
3、信号
开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
应答信号:主机或丛机接收到信号之后,返回应答信号,为低电平。
接收到信号为ack,没有接收到信号为nack。
SCL和SDA有上拉电阻,空闲状态默认为高电平。
4、程序
起始信号
void iic_start(void)
{ /* SCL为高电平期间, SDA从高电平往低电平跳变*/
IIC_SDA ( 1 );
IIC_SCL ( 1 );
iic_delay( ); /*延时时间由丛机决定*/
IIC_SDA ( 0 );
iic_delay( );
IIC_SCL ( 0 ); /* 钳住总线, 准备发送/接收数据 */
iic_delay( );
}
停止信号
void iic_stop(void)
{ /* SCL为高电平期间, SDA从低电平往高电平跳变*/
IIC_SDA ( 0 );
iic_delay( );
IIC_SCL ( 1 );
iic_delay( );
IIC_SDA ( 1 ); /* 发送总线停止信号*/
iic_delay( );
}
检测应答信号
uint8_t iic_wait_ack (void) /* return 1:fail 0:succeed*/
{
IIC_SDA (1); /* 主机释放SDA线,将控制权交给丛机,
丛机发送SDA为0为应答,不操作则为非应答(SDA为高电平)*/
iic_delay( );
IIC_SCL (1); /* 从机返回ACK,SCL为高电平,SDA才有效*/
iic_delay( );
if ( IIC_READ_SDA ) /* SCL高电平读取SDA状态*/
{
iic_stop(); /* 非应答,SDA高电平表示从机nack */
return 1;
}
IIC_SCL(0); /* 应答,SCL低电平表示结束ACK检查 */
iic_delay( );
return 0;
}
发送应答信号
void iic_ack(void)
{
IIC_SCL (0);
iic_delay( );
IIC_SDA (0); /* 数据线为低电平,表示应答 */
iic_delay( );
IIC_SCL (1);
iic_delay( );
}
发送非应答信号
void iic_nack(void)
{
IIC_SCL (0);
iic_delay( );
IIC_SDA (1); /* 数据线为高电平,表示非应答 */
iic_delay( );
IIC_SCL (1);
iic_delay( );
}
发送1字节数据
void iic_send_byte(uint8_t data)
{
for (uint8_t t = 0; t < 8; t++)
{ /* 高位先发 */
IIC_SDA((data & 0x80) >> 7);
iic_delay( );
IIC_SCL ( 1 );
iic_delay( );
IIC_SCL ( 0 );
data <<= 1; /* 左移1位,发送次高位,用于下一次发送 */
}
IIC_SDA ( 1 ); /* 发送完成,主机释放SDA线 */
}
读取1字节数据
uint8_t iic_read_byte (uint8_t ack) /* 1:ack 0:nack*/
{
uint8_t receive = 0 ;
for (uint8_t t = 0; t < 8; t++)
{
/* 高位先输出,先收到的数据位要左移 */
receive <<= 1;
IIC_SCL ( 1 );
iic_delay( );
if ( IIC_READ_SDA ) receive++;
IIC_SCL ( 0 );
iic_delay( );
}
if ( !ack ) iic_nack();
else iic_ack();
return receive;
}