文章目录
I2C 硬件框架

- 在一个芯片(SoC)内部,有一个或多个 I2C 控制器
- 在一个 I2C 控制器上,可以连接一个或多个 I2C 设备
- I2C 总线只需要 2 条线:时钟线 SCL、数据线 SDA
- 在 I2C 总线的 SCL、SDA 线上,都有上拉电阻
I2C 软件框架

I2C的驱动框架包含
- 设备驱动 Device Driver(负责怎么读写数据)
- 控制器驱动 Controller Driver(负责传输数据)
I2C协议(传输数据的格式)
写操作

读操作

I2C 信号
I2C 协议中数据传输的单位是字节,也就是 8 位。但是要用到 9 个时钟:前面 8 个时钟用来传输 8 数据,第 9 个时钟用来传输回应信号。传输时,先传输最高位(MSB)
- 开始信号(S):SCL 为高电平时,SDA 山高电平向低电平跳变,开始传送数据。
- 结束信号(P):SCL 为高电平时,SDA 由低电平向高电平跳变,结束传送数据。
- 响应信号(ACK):接收器在接收到 8 位数据后,在第 9 个时钟周期,拉低SDA
SDA 上传输的数据必须在 SCL 为高电平期间保持稳定,SDA 上的数据只能在SCL 为低电平期间变化
I2C 协议信号如下:

SDA可由主从设备进行控制,所以为了避免争夺线权,实现双向传输,设备的 SDA 中有一个三极管,使用开极/开漏电路(三极管是开极,CMOS 管是开漏,作用一样),这就是 SDA 要使用上拉电阻的原因
SCL 也要使用上拉电阻,在第 9 个时钟之后,如果有某一方需要更多的 时 间 来 处 理 数 据 , 它 可 以 一 直 驱 动 三 极 管 把 SCL 拉 低 。当 SCL 为低电平时候,大家都不应该使用 IIC 总线,只有当 SCL 从低电平变为高电平的时候,IIC 总线才能被使用。当它就绪后,就可以不再驱动三极管,这是上拉电阻把 SCL 变为高电平,其他设备就可以继续使用 I2C 总线了
SMBus 协议
概述
SMBus 是 是 I2C 协议的一个子集
SMBus: System Management Bus,系统管理总线。
SMBus 最初的目的是为智能电池、充电电池、其他微控制器之间的通信链路而定义的。SMBus 也被用来连接各种设备,包括电源相关设备,系统传感器,EEPROM 通讯设备等等。SMBus 为系统和电源管理这样的任务提供了一条控制总线,使用 SMBus 的系统,设备之间发送和接收消息都是通过 SMBus,而不是使用单独的控制线,这样可以节省设备的管脚数。
SMBus 是基于 I2C 协议的,SMBus 要求更严格,SMBus 是 I2C 协议的子集。
硬件和软件上的区别
VDD 的极限值不一样
- I2C 协议:范围很广,甚至讨论了高达 12V 的情况
- SMBus:1.8V~5V
最小时钟频率、最大的 Clock Stretching
- Clock Stretching 含义:某个设备需要更多时间进行内部的处理时,它可以把 SCL 拉低占住 I2C 总线
-I2C 协议:时钟频率最小值无限制,Clock Stretching 时长也没有限制
-SMBus:时钟频率最小值是 10KHz,Clock Stretching 的最大时间值也有限制
地址回应(Address Acknowledge):一个 I2C 设备接收到它的设备地址后,是否必须发出回应信号?
- I2C 协议:没有强制要求必须发出回应信号
- SMBus:强制要求必须发出回应信号,这样对方才知道该设备的状态:busy,failed,或是被移除了
SMBus 协议明确了数据的传输格式
- I2C 协议:它只定义了怎么传输数据,但是并没有定义数据的格式,这完全由设备来定义
SMBus:定义了几种数据格式(含义更加具体)
REPEATED START Condition(重复发出 S 信号)
比如读 EEPROM 时,涉及 2 个操作:
- ① 把存储地址发给设备
- ② 读数据
在写、读之间,可以不发出 P 信号,而是直接发出 S 信号:这个 S 信号就是REPEATED START,如图 10.13 所示

SMBus Low Power Version:SMBus 也有低功耗的版本
SMBus 协议分析
对于 I2C 协议,它只定义了怎么传输数据,但是并没有定义数据的格式,这完全由设备来定义。
对于 SMBus 协议,它定义了几种数据格式。
因为很多设备都实现了 SMBus,而不是更宽泛的 I2C 协议,所以优先使用SMBus。即使 I2C 控制器没有实现 SMBus,软件方面也是可以使用 I2C 协议来模拟 SMBus。所以:Linux 建议优先使用 SMBus。
注意:
- Functionality flag 是 Linux 的某个 I2C 控制器驱动所支持的功能。
- 比如 Functionality flag: I2C_FUNC_SMBUS_QUICK,表示需要 I2C 控制器支持 SMBus Quick Command
符号的含义

SMBus Quick Command

只是用来发送一位数据:R/W#本意是用来表示读或写,但是在 SMBus 里可以用来表示其他含义。比如某些开关设备,可以根据这一位来决定是打开还是关闭。
Functionality flag: I2C_FUNC_SMBUS_QUICK
SMBus Receive Byte

I2C-tools 中的函数:i2c_smbus_read_byte()。读取一个字节,Host adapter 接收到一个字节后不需要发出回应信号(上图中 N 表示不回应)。
Functionality flag: I2C_FUNC_SMBUS_READ_BYTE
SMBus Send Byte

I2C-tools 中的函数:i2c_smbus_write_byte()。发送一个字节。
Functionality flag: I2C_FUNC_SMBUS_WRITE_BYTE
SMBus Read Byte

I2C-tools 中的函数:i2c_smbus_read_byte_data()。先发出 Command Code(它一般表示芯片内部的寄存器地址),再读取一个字节的数据。上面介绍的 SMBus Receive Byte 是不发送 Comand,直接读取数据。
Functionality flag: I2C_FUNC_SMBUS_READ_BYTE_DATA
SMBus Read Word

I2C-tools 中的函数:i2c_smbus_read_word_data()。先发出 Command Code(它一般表示芯片内部的寄存器地址),再读取 2 个字节的数据。
Functionality flag: I2C_FUNC_SMBUS_READ_WORD_DATA
SMBus Write Byte

I2C-tools 中 的 函 数 : i2c_smbus_write_byte_data() 。 先发出Command Code(它一般表示芯片内部的寄存器地址),再发出 1 个字节的数据。
Functionality flag: I2C_FUNC_SMBUS_WRITE_BYTE_DATA
SMBus Write Word

I2C-tools 中 的 函 数 : i2c_smbus_write_word_data() 。 先发出Command Code(它一般表示芯片内部的寄存器地址),再发出 1 个字节的数据。
Functionality flag: I2C_FUNC_SMBUS_WRITE_WORD_DATA
SMBus Block Read

I2C-tools 中 的 函 数 : i2c_smbus_read_block_data() 。 先发出Command Code(它一般表示芯片内部的寄存器地址),再发起度操作:
- 先读到一个字节(Block Count),表示后续要读的字节数
- 然后读取全部数据
Functionality flag: I2C_FUNC_SMBUS_READ_BLOCK_DATA
SMBus Block Write

I2C-tools 中 的 函 数 : i2c_smbus_write_block_data() 。 先发出Command Code(它一般表示芯片内部的寄存器地址),再发出 1 个字节的 Byte Conut

本文详细介绍了I2C和SMBus协议的硬件和软件框架,包括传输数据的格式、操作类型以及信号细节。同时,探讨了SMBus作为I2C子集的特性和差异。此外,文章还涵盖了Linux内核中的I2C架构,以及I2C-Tools的使用方法,如i2cdetect、i2cget和i2cset等,用于无需编写驱动程序即可访问和调试I2C设备。最后,以AP3216C传感器为例,展示了如何使用I2C-Tools进行操作。
2629

被折叠的 条评论
为什么被折叠?



