I2C协议详解

本文围绕I2C总线展开,介绍了其物理拓扑结构,由SDA、SCL及上拉电阻组成,通过高低电平时序控制传递数据。阐述了总线特征,包括设备主从属性、地址、挂接数量、传输速率等。讲解了总线协议,如起始和停止信号,以及数据传输和地址指定过程。还提及了主从设备间的读写操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 I2C总线知识

1.1  I2C总线物理拓扑结构
                      
    I2C 总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成。通信原理是通过对SCL和SDA线高低电平时序的控制,来产生I2C总线协议所需要的信号进行数据的传递。在总线空闲状态时,这两根线一般被上面所接的上拉电阻拉高,保持着高电平。

1.2  I2C总线特征
    I2C总线上的每一个设备都可以作为主设备或者从设备,而且每一个设备都会对应一个唯一的地址(可以从I2C器件的数据手册得知),主从设备之间就通过这个地址来确定与哪个器件进行通信,在通常的应用中,我们把CPU带I2C总线接口的模块作为主设备,把挂接在总线上的其他设备都作为从设备。
I2C总线上可挂接的设备数量受总线的最大电容400pF限制,如果所挂接的是相同型号的器件,则还受器件地址位的限制。
I2C总线数据传输速率在标准模式下可达100kbit/s,快速模式下可达400kbit/s,高速模式下可达3.4Mbit/s。一般通过I2C总线接口可编程时钟来实现传输速率的调整,同时也跟所接的上拉电阻的阻值有关。
    I2C总线上的主设备与从设备之间以字节(8位)为单位进行双向的数据传输。

1.3  I2C总线协议
    I2C协议规定,总线上数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。起始和结束信号总是由主设备产生。总线在空闲状态时,SCL和SDA都保持着高电平,当SCL为高电平时,SDA由高到低的跳变,则会产生一个起始条件;当SCL为高时,SDA由低到高的跳变,则会产生一个停止条件。在起始条件产生后,总线处于忙状态,由本次数据传输的主从设备独占,其他I2C器件无法访问总线;而在停止条件产生后,本次数据传输的主从设备将释放总线,总线再次处于空闲状态当然也可以不释放总线,可以直接选取下一个从设备并且开始下一次传输,最后在释放总线即可。如图所示:

                              

在了解起始条件和停止条件后,我们再来看看在这个过程中数据的传输是如何进行的。前面我们已经提到过,数据传输以字节为单位。主设备在SCL线上产生每个时钟脉冲的过程中将在SDA线上传输一个数据位,当一个字节按数据位从高位到低位的顺序传输完后,紧接着从设备将拉低SDA线,回传给主设备一个应答位,此时才认为一个字节真正的被传输完成。当然,并不是所有的字节传输都必须有一个应答位,比如:当从设备不能再接收主设备发送的数据时,从设备将回传一个否定应答位。数据传输的过程如图所示:

                            
    注意:传输数据过程中,当SCL为高电平时,SDA的点平必须保持稳定,否则可能会产生开始位或者停止位,所以数据传输过程中,SCL为高电平时获取SDA的数据,在SCL为低电平时可以进行点平的转换(SCL为低点平时不会有影响)

                           
    在前面我们还提到过,I2C总线上的每一个设备都对应一个唯一的地址,主从设备之间的数据传输是建立在地址的基础上,也就是说,主设备在传输有效数据之前 要先指定从设备的地址,地址指定的过程和上面数据传输的过程一样,只不过大多数从设备的地址是7位的,然后协议规定再给地址添加一个最低位用来表示接下来 数据传输的方向,0表示主设备向从设备写数据,1表示主设备向从设备读数据。如图所示:
 1.4  I2C总线操作
    对I2C总线的操作实际就是主从设备之间的读写操作。大致可分为以下种操作情况:
    第一,主设备往从设备中写数据。数据传输格式如下:
                              

    第二,主设备从从设备中读数据。数据传输格式如下:

                             
    

 

 

 

### I2C协议的工作原理详解 I2C(Inter-Integrated Circuit)是一种广泛应用于短距离通信的串行总线协议,主要用于微控制器与其外围设备之间的数据交换。以下是关于I2C协议工作原理的详细介绍: #### 1. **基本概念** I2C协议采用两根双向线路进行通信:SDA(Serial Data Line,串行数据线)和SCL(Serial Clock Line,串行时钟线)。这两条线均需通过上拉电阻连接到电源电压[^1]。 #### 2. **起始与停止条件** - **起始条件**:当SCL保持高电平时,SDA由高变低表示通信开始。 - **停止条件**:当SCL保持高电平时,SDA由低变高表示通信结束[^1]。 #### 3. **地址帧** 在每次数据传输之前,主设备会先发送一个从设备的7位或10位地址,随后跟随一位读/写指示位。如果该位为0,则为主设备向从设备写入数据;若为1,则为主设备从从设备读取数据[^2]。 #### 4. **应答机制** 每传送完一字节的数据后,接收方需要返回一个应答信号(ACK),表明已成功接收到数据并准备接受下一字节。如果没有应答信号(NACK),则意味着当前操作失败或者不再有后续数据要传输[^3]。 #### 5. **数据帧结构** 每个数据帧包含8比特的有效数据,在这些数据之后紧跟着的是上面提到过的应答位。无论是地址还是实际的数据都遵循这样的格式[^1]。 #### 6. **同步与时序控制** 由于所有的设备共享同一套时钟源(SCL),因此它们之间可以实现精确的时间协调。这种同步方式允许不同速度等级下的器件在同一网络中共存,并且不会因为速率差异而造成混乱[^2]。 #### 7. **仲裁处理** 在一个多主机环境中可能会发生冲突的情况,这时就需要依靠硬件层面来完成仲裁过程。具体来说就是利用SDA线上持续监测状态变化以及SCL上的握手动作共同决定哪个主机获得优先使用权[^3]。 #### 示例代码展示如何初始化简单的I2C接口 ```c #include <i2c.h> void i2c_init(void){ // 设置波特率等参数 } uint8_t i2c_start(uint8_t address){ // 发送启动信号及目标地址 } void i2c_stop(){ // 结束序列 } bool i2c_write_byte(uint8_t data){ // 写单个字节至指定位置 } uint8_t i2c_read_byte(bool ack){ // 从特定寄存器读取数据 } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值