
文章目录
一种I2C接口技术
1. I2C总线系统组成
2. I2C总线状态和信号
3. I2C总线的基本操作
4. 启动和停止条件
5. I2C总线数据传输格式
第二,I2C总线上拉电阻的估计和选择
三,Raspberry Pi和AT24C02接口实验电路以及Python SMBus串行I2C EEPROM应用程序编程
1. 启动RPi串行I2C界面并安装Python SMBus库
2. Raspberry Pi和AT24C02 EEPROM接口的实验电路
3. Python SMBus库函数简介
4. 使用I2C工具和Python SMBus读写AT24C02 EEPROM
一种I2C接口技术
I2C接口是嵌入式系统中常用的网络接口之一. 它使用串行通信将MCU /传感器连接到系统总线,并通过主/从设备协调工作.
I2C / IIC(内部集成电路)总线是PHILIPS于1982年为满足MCU /传感器和其他应用需求而开发的两线串行总线,用于连接MCU和传感器等设备.
I2C总线的主要功能如下:
(1)I2C总线的主要优点是它的简单性和有效性.
(2)由于接口位于组件的正上方,因此I2C总线占用的空间非常小,从而减少了电路板的空间和芯片引脚的数量,并降低了互连成本.
(3)I2C总线的长度可以达到25英尺(约7.6m),并且可以在100Kbps传输速率的标准模式下支持40个组件. 新一代I2C总线还支持400Kbps高速模式传输.
(4)I2C总线的另一个优点是它支持多主机,其中任何能够发送和接收的设备都可以成为主机总线. 主机可以控制信号传输和时钟频率. 当然,在任何时间点只能有一个主人.
1. I2C总线系统组成
I2C总线协议包括两层协议: 物理层和数据链路层.
在物理层上,I2C总线仅使用两条信号线: 一条是串行数据线SDA(串行DAta线),用于数据发送和接收;另一条是串行数据线SDA(串行DAta线). 另一条是串行时钟线SCL(Serial Clock),它构成了一条串行总线,用于指示何时该数据线是有效数据,即数据同步. 在MCU与受控IC之间以及IC与IC之间执行双向传输. I2C标准模式的最大传输速率为100 kbps,I2C快速模式的最大传输速率为400 kbps.
在数据链路层,连接到I2C总线的每个设备都有一个唯一的地址,并且该设备地址由系统设计者确定. 在信息传输期间,根据I2C总线上要完成的功能,在I2C总线上并行连接的每个设备既是主设备(或从设备)又是(或).
由I2C总线组成的系统可以具有多个I2C节点设备,并且可以是多主系统,任何设备都可以是主I2C;但是任何时候都只能有一个主I2C设备,I2C具有总线仲裁功能,以确保系统正确运行. 主I2C设备发出时钟信号,地址信号和控制信号,选择从I2C设备进行通信并控制. I2C总线要求: (1)每个节点设备必须具有I2C接口功能; (2)每个节点设备必须共享地面; (3)两条信号线必须连接到上拉电阻Rp. 如图1所示.

图1多个I2C设备接口的
2. I2C总线状态和信号
(1)空闲状态
SCL和SDA都处于高电平状态,这是总线空闲状态(空闲状态为高电平的原因很简单,因为它们都连接到上拉电阻器. )
(2)占用总线和释放总线
如果要设备使用总线,则应先将其占用,并且拥有总线的主控制器将时钟信号发送到SCL线. 数据传输完成后,应及时释放总线,也就是说,应释放对总线的控制(或拥有)以使其恢复到空闲状态.
(3)启动信号[S]
启动信号由主控制器产生. 当SCL信号为高电平时,SDA会从高电平变为低电平,从而产生启动信号.

(4)结束/停止信号[P]
当SCL线为高电平时,主控制器在SDA线上生成从低电平到高电平的转换,并生成停止信号. 启动信号和停止信号的生成如图2所示.

图2生成开始和停止信号
(5)响应/响应信号[A / NA]
响应信号是字节数据传输的确认. 响应信号占1位. 数据收到1个字节的数据后,它应该向数据发送一个响应信号. 对应于SCL的第9个响应时钟脉冲,如果SDA线保持高电平,则它是一个无响应信号(NA / ACK). 低电平是响应,传输继续进行;高级别表示无响应,传输结束.
(6)控制位信号[R / nW]
控制位信号占一位. 由IIC主机发送的读/写控制信号对于读为高,对于写为低(对于IIC主机). 控制位(或方向位)在寻址字节中给出.
(7)地址信号
地址信号是从站的地址,它占7位,称为“可寻址字节”(见表1).
表1寻址字节

下面描述表1中的每个字段.
设备地址(DA3-DA0): DA3-DA0是I2C总线接口设备的固有地址代码,由设备制造商提供. 例如,AT24C××I2C总线EEPROM设备的地址为1010.
引脚地址(A2,A1,A0): 引脚地址由I2C总线接口设备的地址引脚A2,A1,A0的高度确定. 高电平为1,地面为0.
读/写控制位/方向位(R / n W): R / nW为1表示主机读,R / nW为0表示主机写.
7位地址和读写控制位形成1个字节,即可寻址字节.
(8)等待状态
在IIC总线中,接收数据的设备有权使系统等待,但只有在完全接收到一个数据字节后才能执行等待状态. 例如,在执行主机发送从机接收的数据传输操作时,如果从机接收到数据字节并且由于中断处理等原因不能按时接收下一个字节;从机可以将SCL下拉至低电平,强制主机进入等待状态. 在等待状态下,主机无法发送数据,直到从机认为它可以继续接收数据,然后释放SCL线以使系统退出等待状态,主机才能继续执行后续数据发送.
3. I2C总线的基本操作
(1)串行数据线SDA和串行时钟线SCL在连接到总线的设备之间传输信息.
(2)每个设备都有唯一的地址标识,无论是MCU,LCD驱动器,内存还是键盘接口.
(3)每个设备都可以用作或,具体取决于设备的功能. 显然,LCD驱动器只是一个,内存可以接收和发送数据.
(4)除了将设备视为和之外,在执行数据传输时也可以将其视为主机或从机.
(5)主机是启动总线上的数据传输并生成允许传输的时钟信号的设备. 此时,任何寻址的设备都被视为从设备.
4. 启动和停止条件
当SCL线为高电平时,SDA线从高电平切换为低电平. 该条件称为开始条件. 当SCL为高电平时,SDA线从低电平切换为高电平,这称为停止条件.
启动和停止条件通常由主机生成. 在启动条件之后,总线被视为处于繁忙状态,而在停止条件下,经过一定时间后,总线被视为再次处于空闲状态. 如果在没有停止条件P的情况下产生了重复的开始条件Sr,则总线将始终处于繁忙状态.
5. I2C总线数据传输格式
I2C总线的数据传输格式如图3所示. 在图3中,S是起始信号,R / nW是读写控制位,A / NA是响应信号,P是停止信号信号.

图3 I2C总线数据传输格式
第二,I2C总线上拉电阻的估计和选择
由于I2C器件的SCL和SDA总线是漏极开路的,因此在上图1中,必须将I2C总线的SCL和SDA引脚连接到上拉电阻Rp.
通常,I2C的上拉电阻Rp在1kΩ∽10kΩ之间选择,例如Rp可以取典型值,例如1.5kΩ,1.8kΩ,2.2kΩ,4.7kΩ,5.1kΩ,6.8 kΩ,10kΩ等. 电阻的大小对时序,信号的上升时间和下降时间都有一定的影响.

选择I2C上拉电阻Rp的估算公式如下:
Rpmin = {VDD(min)-0.4V} / 3mA
Rpmax =(T / 0.874)* C(T = 1us,100KHz; T = 0.3us,400KHz)
C是总线电容(Bus Capacitance)或总线负载电容.
Rp的最大值由总线电容CBmax的最大值确定,Rp的最小值由VIO(VDD)和上拉驱动电流(将最大值设置为3mA)确定;
关于Rpmin的值: 在由5V供电的嵌入式系统中,Rpmin = 5V /3mA≈1.7kΩ;在由3.3V供电的嵌入式系统中,Rpmin = 3.3V / 3mA =1.1kΩ;在以2.8V供电的嵌入式系统中,Rpmin = 2.8V /3mA≈1kΩ.
关于Rpmax的值: 在I2C标准模式下,100Kbps总线的最大负载电容为<= 400pF;在I2C快速模式下,400Kbps总线的最大负载电容为<= 200pF. 根据具体的使用场景,当前器件的制造工艺,PCB走线距离等因素以及标准向下兼容性,该设计基于I2C快速模式,即当总线负载电容小于200pF时,传输速度达到400Kbps. 没问题,据估计5V电源系统对应于50pF∽200pF,Rpmax的范围为1.7kΩ∽6.9kΩ. 根据Rpmin和Rpmax的限制,在5V供电的嵌入式系统中smbus时序图,可以采用Rp =5.1kΩ,也可以轻松实现总线负载电容的环境要求;在由3.3V供电的嵌入式系统中,Rp =1.8kΩ∽可以选择为4.7kΩ. 在由2.8V供电的嵌入式系统中,Rp =1.5kΩ∽2.2kΩ对于控制台应用是可选的,而在可穿戴或应用等低功耗应用中,Rp =4.7kΩ为电池寿命而牺牲. 简而言之,电源电压限制了上拉电阻Rp的最小值. 总线负载电容(总线电容)限制了上拉电阻Rp的最大值.
三,Raspberry Pi和AT24C02接口实验电路以及Python SMBus串行I2C EEPROM应用程序编程
如果使用Raspberry Pi I2C总线控制设备或传感器,则Raspberry Pi通常在主机模式下工作. Raspberry Pi I2C总线符合SMBus(系统管理总线,系统管理总线)协议. 在类型方面,可以将SMBus协议视为I2C总线协议的子类,并且可以使用Python语言直接将SMBUS库/ SMBUS模块直接用于访问I2C设备.
1. 启动RPi串行I2C界面并安装Python SMBus库
默认情况下,禁止使用I2C总线. 我们可以在Linux终端上使用raspi-config工具来启动IC2接口. 运行raspi-config工具命令,如下所示:
$ sudo raspi-config
运行后,按菜单提示启动I2C界面.
启动I2C界面的另一种方法是在“首选项”主菜单中找到“ Raspberry Pi配置”工具以启动I2C界面.
安装Python的I2C库SMBus的方法是输入以下命令:
$ sudo apt-get install python-smbus
为了使这些更改生效,您需要重新启动Raspberry Pi.
2. Raspberry Pi和AT24C02 EEPROM接口的实验电路
以Raspberry Pi 3B为例,RPi 3B与AT24C02 EEPROM接口的实验电路如图4所示. 从图4可以看出,RPi 3B串行I2C总线具有1.8kΩ的电阻. 上拉电阻. 因此,RPi 3B串行I2C总线和AT24C02接口不需要外部上拉电阻. 需要强调的是,是否在I2C总线上连接了外部上拉电阻,取决于所使用的开发板是否具有自己的I2C总线上拉电阻. 如果开发板不提供I2C总线上拉电阻,则需要根据之前的I2C总线将其上拉. 电阻估计方法连接两个上拉电阻Rp.

图4 RPi 3B和AT24C02 EEPROM接口的实验电路原理图
为方便起见,实验板用于构建RPI 3B和AT24C02接口的实验电路. ATC24C02的VCC连接到RPi 3B的3.3V电源Pin1物理引脚. GND连接到RPI 3B的GND接地引脚Pin14. SCL连接到RPI 3B I2C-1串行时钟线SCL.1 Pin14物理引脚连接,SCL和RPI 3B I2C-1串行数据线SDA.1 Pin3物理引脚连接. 在此,地址线A0,A1和A2全部接地. 查看AT24C02设备手册,我们可以看到在此配置中,I2C设备AT24C02地址为0x50(注意: Raspberry Pi中的I2C设备地址计算是基于I2C设备的实际寻址地址0b1010A2A1A0,因此寻址AT24C02设备的地址为0b1010000 = 0x50;如果I2C设备手册中给出的具有读写控制位的寻址地址字节为0b1010A2A1A0R / nW,即I2C设备的寻址地址为0xa0,则读取I2C设备寻址地址为0xa1),写保护WP接地,因此Raspberry Pi可以正常读写I2C设备. 实验接口电路连接好后,建议先用万用表检查接口连接是否正确(特别注意电源与地之间的短路),然后启动树莓派AT24C02器件进行读写操作(请参见图5).

图5 RPI 3B和AT24C02接口电路接线图
3. Python SMBus库函数简介
在Raspberry Pi中,我们可以使用Python SMBus库函数来访问串行I2C设备,导入SMBus模块和常用的SMBus库函数,如下所示.
(1)导入SMBus
●要使用SMBus Python模块访问Raspberry Pi上的I2C总线,请按以下步骤导入SMBus模块.
导入smbus
●创建SMBus类的对象以访问基于I2C的Python函数.
= smbus.SMBus(I2C端口号)
I2C端口号: I2C端口号. 即0或1
●示例总线= smbus.SMBus(1)
现在,我们可以使用Bus对象访问SMBus类了.
(2)Bus.write_byte_data(设备地址,寄存器地址,值)

●此功能用于将数据写入所需的寄存器.
设备地址: 7位或10位设备地址
注册地址: 我们需要写入的注册地址
值: 需要写入寄存器的传递值
●Example-Bus.write_byte_data(0x68、0x01、0x07)
(3)Bus.write_i2c_block_data(设备地址,寄存器地址,[value1,value2,…. ])
●此功能用于写入32个字节的块.
设备地址: 7位或10位设备地址
注册地址: 我们需要向其写入数据的注册地址
Value1 Value2….: 将一个字节的块写入所需的地址
●Example-Bus.write_i2c_block_data(0x68,0x00,[0,1,2,3,4smbus时序图,5])#从0地址写入6个字节的数据.
(4)Bus.read_byte_data(设备地址,寄存器地址)
●此功能用于从所需的寄存器读取数据字节.
设备地址: 7位或10位设备地址
注册地址: 我们需要从中读取数据的注册地址
●Example-Bus.read_byte_data(0x68,0x01)
(5)Bus.read_i2c_block_data(设备地址,寄存器地址,字节块)
●此功能用于读取32个字节的块.
设备地址– 7位或10位设备地址
注册地址–我们需要从中读取数据的注册地址
字节块–从所需地址中读取任何字节
●Example-Bus.read_i2c_block_data(0x68,0x00,8)#返回值是6个字节的列表
4. 使用I2C工具和Python SMBus读写AT24C02 EEPROM
在Raspberry Pi终端上输入以下命令以安装I2C工具:
pi @ yuanzy: 〜$ sudo apt-get install i2c-tools
接下来,对于图4的实验接口电路,使用I2C Tools命令来验证AT24C02的基本读写操作. 在以下I2C工具命令中,I2C使用Raspberry Pi的I2C-1(SCL.1,SDA.1),AT24C02的设备地址为0x50.
pi @ yuanzy: 〜$ sudo i2cdetect -l </ p>
i2c-1i2cbcm2835 I2C适配器
pi @ yuanzy: 〜$ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: –-------------
10: ---------------
20: ----------------
30: ----------------
40: ----------------

50: 50 51--------------
60: ----------------
70: --------
pi @ yuanzy: 〜$ sudo i2cdump -y 1 0x50
未指定大小(使用字节数据访问)
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
30: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff…
上面的i2cdump显示了AT24C02器件的所有字节单元的内容. 因为它是新购买的芯片,所以它的256字节单位全为1或0xff(即芯片内容为空).
pi @ yuanzy: 〜$ sudo i2cset -y 1 0x50 0x00 0x60
pi @ yuanzy: 〜$ sudo i2cget -y 1 0x50 0x00
0x60
上面使用i2cset命令向AT24C02设备0#字节单元写入0x60,i2cget读取AT24C02设备0#字节单元的内容显示为0x60,表示写入数据与读取数据一致,即Raspberry Pi读取AT24C02写入设备正常运行.
以下是用Python和Python SMBus库编写的名为I2CAT24C02.py的程序,其功能是依次从0〜255写入256字节的AT24C02设备,然后依次读取AT24C02的字节单元并显示输出,该程序该列表如图6所示.

图6读写AT24C02 I2C EEPROM Python程序
I2CAT24C02.py程序顺序读取AT24C02中的256字节单元. 显示结果如图7所示.

图7 Python程序读取AT24C02器件256字节单元的内容并显示
I2C工具的i2cdump命令还可以用于显示AT24C02中256字节单元的内容(请参见图8). 从图2和图3可以看出. 如图7和8所示,读取AT24C02器件字节单元内容的显示结果与写入AT24C02器件字节单元的数据完全相同.

图8 i2cdump命令显示AT24C02设备的256字节单元的内容
(作者电子邮件联系人: yuanzywhu@163.com)
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/ruanjian/article-241567-1.html
电池更耐用了
果断把今天刚买的芝麻糊扔掉