I2C协议(转载)

本文详细介绍了I2C协议的技术性能、基本工作原理、读写通讯过程及总线信号时序分析等内容。并阐述了I2C协议的寻址约定。

一. I2C协议技术性能:
    工作速率有100K和400K两种;
    支持多机通讯;
    支持多主控模块,但同一时刻只允许有一个主控;     
    由数据线SDA和时钟SCL构成的串行总线;
    每个电路和模块都有唯一的地址;                   
    每个器件可以使用独立电源

二. I2C协议基本工作原理:
    以启动信号START来掌管总线,以停止信号STOP来释放总线;
    每次通讯以START开始,以STOP结束;
    启动信号START后紧接着发送一个地址字节,其中7位为被控器件的地址码,一位为读/写控制位R/W,R. /W位为0表示由主控向被控器件写数据,R/W为1表示由主控向被控器件读数据;
    当被控器件检测到收到的地址与自己的地址相同时,在第9个时钟期间反馈应答信号;
    每个数据字节在传送时都是高位(MSB)在前;

写通讯过程:
    1. 主控在检测到总线空闲的状况下,首先发送一个START信号掌管总线;
    2. 发送一个地址字节(包括7位地址码和一位R/W);
    3. 当被控器件检测到主控发送的地址与自己的地址相同时发送一个应答信号(ACK);
    4. 主控收到ACK后开始发送第一个数据字节;
    5. 被控器收到数据字节后发送一个ACK表示继续传送数据,发送NACK表示传送数据结束;
    6. 主控发送完全部数据后,发送一个停止位STOP,结束整个通讯并且释放总线;

三.I2C协议读通讯过程:
    1. 主控在检测到总线空闲的状况下,首先发送一个START信号掌管总线;
    2. 发送一个地址字节(包括7位地址码和一位R/W);
    3. 当被控器件检测到主控发送的地址与自己的地址相同时发送一个应答信号(ACK);
    4. 主控收到ACK后释放数据总线,开始接收第一个数据字节;
    5. 主控收到数据后发送ACK表示继续传送数据,发送NACK表示传送数据结束;
    6. 主控发送完全部数据后,发送一个停止位STOP,结束整个通讯并且释放总线;

四. I2C协议总线信号时序分析
    1. 总线空闲状态
    SDA和SCL两条信号线都处于高电平,即总线上所有的器件都释放总线,两条信号线各自的上拉电阻把电平拉高;
    2. 启动信号START
    时钟信号SCL保持高电平,数据信号SDA的电平被拉低(即负跳变)。启动信号必须是跳变信号,而且在建立该信号前必修保证总线处于空闲状态;
    3. 停止信号STOP
    时钟信号SCL保持高电平,数据线被释放,使得SDA返回高电平(即正跳变),停止信号也必须是跳变信号。
    4. 数据传送
    SCL线呈现高电平期间,SDA线上的电平必须保持稳定,低电平表示0(此时的线电压为地电压),高电平表示1(此时的电压由元器件的VDD决定)。只有在SCL线为低电平期间,SDA上的电平允许变化。
    5. 应答信号ACK
    I2C总线的数据都是以字节(8位)的方式传送的,发送器件每发送一个字节之后,在时钟的第9个脉冲期间释放数据总线,由接收器发送一个ACK(把数据总线的电平拉低)来表示数据成功接收。
    6. 无应答信号NACK
    在时钟的第9个脉冲期间发送器释放数据总线,接收器不拉低数据总线表示一个NACK,NACK有两种用途:
    a. 一般表示接收器未成功接收数据字节;
    b. 当接收器是主控器时,它收到最后一个字节后,应发送一个NACK信号,以通知被控发送器结束数据发送,并释放总线,以便主控接收器发送一个停止信号STOP。

五. I2C协议寻址约定
    地址的分配方法有两种:
    1. 含CPU的智能器件,地址由软件初始化时定义,但不能与其它的器件有冲突;
    2. 不含CPU的非智能器件,由厂家在器件内部固化,不可改变。

    高7位为地址码,其分为两部分:
    1. 高4位属于固定地址不可改变,由厂家固化的统一地址;
    2. 低三位为引脚设定地址,可以由外部引脚来设定(并非所有器件都可以设定);

### 为什么 I2C 协议使用开漏输出而不使用推挽输出 #### 信号线共享与多设备通信 I2C 总线是一种多主从设备共享的通信总线,它仅使用两条信号线(SCL 和 SDA)进行通信。在这样的通信结构中,多个设备需要共享同一信号线进行数据传输。开漏输出结构允许多个设备同时连接到同一信号线,而不会因多个设备同时输出高电平而导致短路或冲突。这种特性使得开漏输出非常适合用于需要多个设备共享信号线的场景,例如 I2C 总线[^2]。 #### 线与逻辑(Wired-AND)实现 开漏输出支持线与逻辑(Wired-AND),即多个开漏输出可以并联连接到同一信号线上。当任意一个设备将信号线拉低时,整个信号线的电平就会被拉低。这种机制是 I2C 协议实现仲裁和冲突检测的基础。推挽输出无法实现这种功能,因为如果多个推挽输出同时连接到同一信号线上,可能会导致电源与地之间的短路。 #### 避免高电平冲突 推挽输出具有主动驱动高电平的能力,而开漏输出则依赖外部上拉电阻来实现高电平。在 I2C 总线中,多个设备可能同时连接到同一信号线上,如果使用推挽输出,则多个设备同时输出高电平时可能会导致电流冲突,从而损坏设备。而开漏输出的高电平由外部上拉电阻统一提供,避免了这种冲突问题[^2]。 #### 电平转换与兼容性 I2C 总线中的设备可能工作在不同的电压水平下,例如 3.3V 和 5V。开漏输出配合外部上拉电阻可以实现电平转换,使得不同电压域的设备能够在同一总线上通信。上拉电阻可以连接到目标电压域,从而实现电平兼容性。而推挽输出无法实现这种灵活的电平转换能力[^1]。 #### 简化电路设计与降低成本 由于开漏输出结构简单,仅需要一个晶体管和外部上拉电阻即可实现,因此在芯片设计中占用的面积较小,降低了芯片成本。此外,开漏输出的结构使得 I2C 总线设计更加简洁,仅需要外部上拉电阻即可实现高电平驱动,而不需要复杂的电源管理电路[^1]。 ### 示例代码 以下是一个简单的 I2C 主设备与从设备通信的模拟代码,展示了开漏输出如何在 I2C 总线中工作: ```python class I2CDevice: def __init__(self, address, sda, scl): self.address = address self.sda = sda self.scl = scl def start_condition(self): self.sda.set_output(False) # SDA 从高到低 self.scl.set_output(False) # SCL 保持低电平 def stop_condition(self): self.sda.set_output(True) # SDA 从低到高 self.scl.set_output(True) # SCL 保持高电平 def write_bit(self, bit): self.sda.set_output(bit) # 设置 SDA 电平 self.scl.set_output(True) # 拉高 SCL,采样数据 self.scl.set_output(False) # 拉低 SCL,准备下一个 bit def read_bit(self): self.sda.set_output(True) # 释放 SDA,允许外部上拉拉高 return self.sda.get_voltage() > 0 # 读取 SDA 电平 class GPIO: def __init__(self, pull_up_resistor=1000): self.pull_up_resistor = pull_up_resistor # 上拉电阻值 self.voltage = 5 # 电源电压 self.state = False # 初始状态为低电平 def set_output(self, state): self.state = state # 设置输出状态 def get_voltage(self): if self.state: # 如果状态为高电平 return self.voltage # 由外部上拉电阻拉高 else: # 如果状态为低电平 return 0 # 接地 # 创建 SDA 和 SCL 引脚 sda = GPIO(pull_up_resistor=1000) scl = GPIO(pull_up_resistor=1000) # 创建 I2C 设备 device = I2CDevice(address=0x50, sda=sda, scl=scl) # 开始通信 device.start_condition() device.write_bit(True) device.write_bit(False) device.stop_condition() # 读取 SDA 电平 print(f"当前 SDA 电平为: {device.read_bit()}") ``` 这段代码模拟了 I2C 设备通过开漏输出进行通信的行为,展示了如何利用外部上拉电阻实现高电平驱动。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值