基于Proteus的I2C总线技术仿真*
2020-04-19向继文
向继文
(吉首大学信息科学与工程学院,湖南 吉首 416000)
I2C总线是Philips公司推出的芯片间串行传输总线,以2根连线(SDA和SCL)即可实现完善的全双工同步数据传送,具有规范完整、结构独立和使用简单等特点[1],最高传输速率可达400 kbps[2].I2C总线最初是为音频和视频设备开发的[3].如今,支持I2C技术的控制器和外围器件的种类很多,I2C总线技术在各类电子产品、家用电器和通信设备中得到了广泛应用.然而,I2C总线器件与主控器件之间的线路连接虽然简单,但是相应的软件却较复杂,其控制程序调试有一定的难度.针对这个问题,笔者拟设计一款I2C器件的控制电路,主控制器采用单片机,并利用Proteus软件对所设计的I2C器件控制电路进行仿真.
1 I2C总线的硬件连接
1.1 I2C总线的硬件连接结构
I2C总线只要求2条信号线,一条是串行数据线SDA,另一条是串行时钟线SCL[4].2条信号线都是双向的,各I2C器件的数据线均连接到SDA总线上,各I2C器件的时钟线均连接到SCL总线上,2条信号线均需要通过上拉电阻连接正电源.I2C总线与单片机的硬件连接结构如图1所示.
图1 I2C总线与单片机的硬件连接结构
1.2 I2C总线的器件地址
支持I2C总线标准的外围器件较多,常见的有A/D及D/A转换器、SRAM及E2PROM存储器、日历时钟芯片、LED/LCD驱动芯片和数字音频处理芯片等.每个连接到I2C总线上的器件都有唯一的地址[5],器件地址码为B3,B2,B1,B0,引脚地址为A2,A1,A0,方向控制位为R/W。
地址码中的器件地址用于区分器件的大类类型,4位器件地址码可以支持16个大类器件地址,这个地址由器件厂商给定.引脚地址共3位,最多可以支持8个同一类型的器件,由用户根据实际情况通过物理连接设定.理论上,连接到I2C总线上的器件最多为16种类型共128个器件,但实际上是不可能的.这是因为I2C总线没有那么强的驱动能力,且连接到总线上的器件太多,引脚分布电容也会较大,从而使得信号的质量下降,通信的误码率增大.方向控制位用于设定主器件(如单片机)和从器件(如I2C存储器)的数据传送方向,为1时设定为主器件读从器件传送来的数据,为0时设定为主器件对从器件进行写操作.以图2所示的I2C存储器为例,设定各器件的地址.
图2 I2C存储器与单片机的连接
存储器芯片采用Atmel公司生产的AT24C02芯片,每片存储容量为256 B,固定的器件地址码为1010,引脚地址A2,A1,A0通过硬件连接设定.根据电路连接图(图2),可以得到各芯片的地址(表1).
表1 AT24C02芯片的读写地址
2 I2C总线的数据传输协议
在I2C总线协议中,数据的传输必须由主器件发送的起始信号开始,由主器件发送的停止信号结束.总线信号包括4种类型:
(1)起始信号.当时钟线SCL为高电平时,数据线SDA产生从高电平到低电平的跳变,要求SDA在跳变前高电平维持时间大于4.7 μs,跳变后低电平时间大于4 μs.
(2)停止信号.当时钟线SCL为高电平时,数据线SDA产生从低电平到高电平的跳变,要求SDA在跳变前低电平维持时间大于4 μs,跳变后高电平时间大于4.7 μs.
(3)应答信号.I2C总线每传送1 Byte的数据后,在时钟线SCL为高电平时,由接收方将数据线SDA拉成低电平,表示数据传输正确,要求SCL高电平维持时间大于4 μs.
(4)数据信号.在起始信号与停止信号之间传送的是数据信息,包括从器件的地址信息.数据信息以操作时序为单位进行传送,字节数没有限制,但每个字节必须为8 bit,先发送高位,后发送低位,每个字节后面必须接收1个应答信号.
在传输数据信息时,数据线只允许在时钟线SCL为低电平时改变,因为时钟线为高电平时数据线的改变已经做了定义,不能用于传送数据信息.
3 Proteus仿真实验
3.1 Proteus仿真电路设计
Proteus软件是英国Lab Center Electronics公司推出的EDA工具软件,不仅具备其他 EDA工具软件的仿真功能,还具备极好的仿真单片机及外围器件的功能.采用Proteus软件进行仿真测试,有利于降低系统开发的软硬件成本[6-7].本系统Proteus仿真电路如图3所示.
图3 Proteus仿真电路
仿真电路包括时钟电路、复位电路、液晶显示电路、中断触发电路和I2C存储器电路等.仿真时,首先运行主程序,液晶模块LCD1602显示初始信息,并在主程序中调用I2C写信息子程序,分别给3片AT24C02芯片写入不同的信息;当要读出存储器中的信息时,按下单片机P3.2引脚外接的按键触发外部中断0,由外部中断子程序调用相关子程序,分别将3片AT24C02芯片中原来写入的信息读出,并通过液晶模块LCD1602加以显示.
3.2 主要的子程序设计
控制程序采用单片机汇编语言编写,该程序能够非常方便地通过C语言改写.主要子程序包括液晶模块相关子程序、I2C总线启动子程序、I2C总线停止子程序、检测应答子程序、字节写入子程序、多字节写入子程序和字节读出子程序等,在此仅介绍与I2C总线操作主要相关的子程序.
(1)总线启动子程序.该子程序按照I2C总线时序和电平宽度要求编写,完成I2C总线的启动.
I2C_START:SETB SDA ∥拉高数据线
NOP
SETB SCL ∥拉高时钟线
NOP ∥5条NOP指令延时
…
CLR SDA ∥拉低数据线
NOP ∥5条NOP指令延时
…
CLR SCL ∥拉低时钟线
NOP
RET
(2)总线停止子程序.该子程序按照I2C总线时序和电平宽度要求编写,完成I2C总线的停止.
I2C_STOP:CLR SDA
NOP
SETB SCL
NOP ∥5条NOP指令延时
…
SETB SDA
NOP ∥5条NOP指令延时
…
RET
(3)字节写通用子程序.该子程序完成向存储器芯片写入1 Byte数据,需要写入的字节在累加器A中.
WRBYTE:MOV R0,#08H
WLP:RLC A ∥先发送高位,再发送低位
JC WR1
SJMP WR0
WR1:SETB SDA ∥写1
NOP
SETB SCL
NOP ∥5条NOP指令延时
…
CLR SCL
SJMP RETURN
WR0:CLR SDA ∥写0
NOP
SETB SCL
NOP ∥5条NOP指令延时
…
CLR SCL
RETURN:DJNZ R0,WLP ∥判断1 B是否发送完毕
RET
(4)字节读通用子程序.该子程序实现读存储器芯片向单片机发送1 Byte数据,读出的字节放在累加器A中.
RDBYTE:MOV R0,#08H
RLP:SETB SDA
NOP
SETB SCL ∥时钟线拉高,准备接收数据
NOP
NOP
MOV C,SDA ∥读数据
NOP
NOP
RLC A ∥读取的数据移位到累加器A中
NOP
CLR SCL
DJNZ R0,RLP ∥判断1 B是否接受完毕
RET
(5)外部中断0子程序.该子程序实现依次读出3片存储器芯片的内容,并发送给液晶显示器显示.
RD_I2CRAM_INT:ACALL INIT ∥调用液晶显示模块初始化子程序
MOV A,#10000000B ∥设置液晶显示第1行起始地址
MOV R1,#00H ∥设置芯片内部读起始地址
MOV R2,#16 ∥设置读取的字节数
MOV R3,#10100000B ∥传送1#片器件地址,写操作
MOV R4,#10100001B ∥传送1#片器件地址,读操作
ACALL RD_I2CRAM ∥调用读子程序,并显示
MOV A,#11000000B ∥设置液晶显示第2行起始地址
MOV R1,#0
MOV R2,#8
MOV R3,#10100010B ∥传送2#片器件地址,写操作
MOV R4,#10100011B ∥传送2#片器件地址,读操作
ACALL RD_I2CRAM
MOV A,#11001000B ∥设置3#片内容显示的起始地址
MOV R1,#0
MOV R2,#8
MOV R3,#10100100B ∥传送3#片器件地址,写操作
MOV R4,#10100101B ∥传送3#片器件地址,读操作
ACALL RD_I2CRAM
RETI
3.3 仿真测试
程序运行时,先显示初始信息“HELLO HOW ARE YOU”(图4),并调用写信息子程序,对3个存储器分别写入不同的字符信息;当按下P3.2引脚外接的按键触发外部中断0以后,由外部中断程序调用相关子程序依次读出3片存储器芯片的内容,并在液晶显示器上显示出来.仿真测试结果如图5所示,由图可见结果正确.
图4 初始信息截图
图5 3片存储器芯片的信息截图
4 结语
研究了I2C总线的硬件连接和数据传输协议,设计了一款有3个I2C存储器的仿真电路,并利用Proteus软件进行了仿真测试.程序采用单片机汇编语言编写,能满足操作时序中高低电平对时间的要求,也能非常方便地改写为C语言程序.采用通用子程序的方式完成程序的编写,有利于移植到不同类型的I2C器件的程序开发中.根据系统功能的不同需求,在实际应用中,可以改用12864之类的LCD显示模块,以便显示更多的信息,还可以连接更多类型的I2C器件,实现更多的操作需求.