I2C通信协议基础笔记

I2C通信简介

I2C使用两根线,一个SDA串行数据线和一根SCL时钟线,半双工,支持一主多从或者多主多从模式
SDA:主机和从机发送和接收数据的线路
SCL:传输时钟信号的线路

I2C工作原理

I2C协议

启动条件:在SCL线从高电平切换到低电平之前 ,SDA线从高电平 切换到低电平。

停止条件: SCL 线由低电平切换到高电平后 ,SDA 线由低电平 切换到高电平。

地址帧: 每个从机唯一的 7 或 10 位序列,当主机想要与它通信时,它会识别从机。

读/写位: 指定主机是向从机发送数据(低电压电平)还是向从机请求数据(高电压电平)的单个位。

ACK/NACK 位: 消息中的每一帧后跟一个确认/不确认位。如果成功接收到地址帧或数据帧,则接收设备会向发送方返回一个 ACK​​ 位。

寻址

I2C 没有像 SPI 这样的从机选择线,因此它需要另一种方式让从机知道数据正在发送给它,而不是另一个从机。它通过 寻址来做到这一点。地址帧始终是新消息中起始位之后的第一个帧。

主机将要与之通信的从机的地址发送给与其连接的每个从机。然后,每个从机将从主机发送的地址与其自己的地址进行比较。如果地址匹配,它会向主机发送一个低电压 ACK 位。如果地址不匹配,从机什么也不做,SDA 线保持高电平。

读写位

地址帧末尾包含一个位,用于通知从机主机是要向其写入数据还是要从其接收数据。如果主机要向从机发送数据,读/写位为低电压电平。如果主机向从机请求数据,则该位为高电平。

数据帧

主机检测到从机的 ACK 位后,第一个数据帧就可以发送了。

数据帧总是 8 位长,并以最高有效位在前发送。每个数据帧后面紧跟一个 ACK​​/NACK 位,以验证该帧是否已成功接收。ACK 位必须由主机或从机(取决于谁在发送数据)接收到,然后才能发送下一个数据帧。

发送完所有数据帧后,主机可以向从机发送停止条件以停止传输。停止条件是在 SCL 线上从低到高转换之后 SDA 线上的电压从低到高转换,而 SCL 线保持高电平。

I2C数据传输步骤

下文利用C语言展示如何通过GPIO引脚模拟I2C信号,同时通过示波器信号加深印象

1. 开始信号

主机通过将 SDA 线从高电压电平切换到低电压电平 ,然后 将 SCL 线从高电平切换到低电平,向每个连接的从机发送启动条件

 void IIC_Start(void)
{
    
	SDA_OUT();     	//设置SDA线为输出
	SCL_OUT();     	//设置SCL线为输出
	SET_IIC_SDA=1;	//SDA置高  
	SET_IIC_SCL=1;  //SCL置高
	delay_us(4);    //让数据保持一段时间
	
    //SCL线从高电平切换到低电平之前 ,SDA线从高电平  切换到低电平
 	IIC_SDA=0;		
	delay_us(4);    
	IIC_SCL=0;		//钳住I2C总线,准备发送或接收数据 
}

起始信号

2.寻址

主机向每个从机发送它想与之通信的从机的 7 位或 10 位地址,以及读/写位

//发送七位地址数据+一位读写位
void gpio_iic_write(int data)
{
    int i = 0;
    for (i = 0; i < 8; i++)
    {
        if (data & (1 << (7 - i)))
        {
            SET_IIC_SDA(1);
        }
        else
        {
            SET_IIC_SDA(0);
        }
        delay(1);
        SET_IIC_SCL(1);
        delay(2);
        SET_IIC_SCL(0);
        delay(1);
    }
}
//从机地址要左移一位,加上一位读写位
gpio_iic_write((SlaveAddr << 1) | I2C_TX);

寻址

3. 主机等待返回应答信号

每个从机将主机发送的地址与自己的地址进行比较。如果地址匹配,从机通过将 SDA 线拉低一位来返回一个 ACK​​ 位。如果来自主机的地址与从机自己的地址不匹配,则从机将 SDA 线保持为高电平。

//主机发送数据,此时从机每次接收到一帧数据之后,要返回一个低电平,那么主机就要接收这个ack,因此主机数据线引脚要设置为输入
void gpio_iic_slave_ack(void)
{
    SDA_IN();
    delay(1);
    SET_IIC_SCL(1);
    delay(1);
    GET_IIC_SDA();
    SET_IIC_SCL(0);
    osa_udelay(1);
    SDA_OUT(1);//接收到ack之后,要马上设置回输出引脚,继续发送信号
    delay(1);
}

应答

4. 数据帧

主机发送或者接收数据帧

//读取一个字节数据
int gpio_iic_read(void)
{
    int data = 0;
    int i = 0;
    volatile int temp = 0;

    SET_SDA_IN();
    for (i = 0; i < 8; i++)
    {
        delay(1);
        SET_IIC_SCL(0);
        delay(2);
        SET_IIC_SCL(1);
        delay(1);
      
        temp = GET_IIC_SDA();//读取sda一个bit有效数据,而且是从高位往低位接收数据,所以需要移位处理
        if (temp)
        {
            data |= (1 << (7 - i)); // MSB
        }
    }
    delay(1);
    SET_IIC_SCL(0);
    delay(1);
    return data;
}
//发送八位数据
void gpio_iic_write(int data)
{
    int i = 0;
    for (i = 0; i < 8; i++)
    {
        if (data& (1 << (7 - i)))
        {
            SET_IIC_SDA(1);
        }
        else
        {
            SET_IIC_SDA(0);
        }
        delay(1);
        SET_IIC_SCL(1);
        delay(2);
        SET_IIC_SCL(0);
        delay(1);
    }
}
//最好这样传参
gpio_iic_write(data & 0xff);//除了后面八位有效数据其他均抹去

5.应答信号

传输完每个数据帧后,接收设备会向发送方返回另一个 ACK​​ 位,以确认已成功接收到该帧

同3

6.停止位

要停止数据传输,主机在将 SDA 变为高之前通过将 SCL 变为高来向从机发送停止条件
或者说,在SCL变为高之后,将SDA变为高,停止条件成立
有时候同样的文字的描述也会让人感到疑惑,结合看图会更好理解

void gpio_iic_stop(void)
{
    SDA_OUT();
    SET_IIC_SDA(0);
    delay(2);
    SET_IIC_SCL(1);
    delay(4);
    SET_IIC_SDA(1);
    delay(2);
}

在这里插入图片描述

总结I2C优缺点

优点

  1. 只用两根线
  2. 支持多主多从
  3. ACK/NACK 位确认每帧传输成功
  4. 硬件不如 UART 复杂
  5. 众所周知且广泛使用的协议

缺点

  1. 数据传输速率比 SPI 慢
  2. 数据帧的大小限制为 8 位
  3. 需要实现比 SPI 更复杂的硬件
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
I2C通信协议是一种串行总线协议,它允许多个设备在同一条总线上进行通信。在I2C总线上,每个设备都有一个唯一的地址,可以通过这个地址与其他设备进行通信。下面是I2C通信协议的详细讲解: 1. 总线结构 I2C总线结构包括两根信号线:SCL和SDA。SCL是时钟线,由主设备负责产生;SDA是数据线,用于传输数据。 2. 通信方式 I2C通信协议主要分为两种方式:传输数据和发送命令。在传输数据时,从设备首先向主设备发送一个应答信号(ACK),主设备接收到应答信号后,才会继续发送数据。在发送命令时,主设备向从设备发送命令并等待从设备的应答信号。 3. 传输数据 在I2C总线上传输数据时,每个字节都由8位二进制数字组成。在传输一个字节之前,主设备必须向从设备发送一个起始信号(Start Bit),表示一个新的传输过程开始了。然后主设备会先发送从设备的地址(包括读/写位),然后等待从设备的应答信号。如果从设备存在,并且它的地址与主设备发送的地址匹配,那么它会发送一个应答信号。接下来主设备会开始发送数据,每发送一个字节就等待从设备的应答信号。当主设备发送完最后一个字节后,它会发送一个停止信号(Stop Bit),表示这次传输已经结束了。 4. 发送命令 在I2C总线上发送命令时,主设备首先向从设备发送命令,并等待从设备的应答信号。如果从设备存在,并且它的地址与主设备发送的地址匹配,那么它会发送一个应答信号。接下来主设备可以向从设备发送一个或多个字节的数据,然后等待从设备的应答信号。当主设备完成数据传输后,它会向从设备发送停止信号。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值