I2C总线的结构、工作时序与模拟编程I2C总线(InterIntegratedCircuit)是飞利浦公司于上个世纪80年代开发的一种“电路板级”的总线结构。与其它串行接口相比,无论从硬件结构、组网方式、软件编程都有很大的不同。在AT89C51系统上使用汇编语言模拟I2C总线的各种信号及编程原理,为自主开发、设计具有I2C总线接口的系统打下一个良好的基础,也为其它串口的模拟编程创造一个好的思路和可行的方法。I2C总线的主要特点1.二线制结构。即双向的串行数据线SDA、串行同步时钟线SCL。总线上的所有器件其同名端都分别挂在SDA、SCL线上(见图7.1);2.I2C总线所有器件的SDA、SCL引脚的输出驱动都为漏极开路结构(见图7.2),通过外接上拉电阻将总线上所有节点的SDA、SCL信号电平实现“线与”的逻辑关系。这不仅可以将多个节点器件按同名端引脚直接挂在SDA、SCL线上,还使I2C总线具备了“时钟同步”、确保不同工作速度的器件同步工作;3.系统中的所有外围器件都具有一个7位的“从器件专用地址码”,其中高4位为器件类型地址(由生产厂家制定),低3位为器件引脚定义地址(由使用者定义),主控器件通过地址码建立多机通信的机制。因此I2C总线省去了外围器件的片选线,这样无论总线上挂接多少器件,其系统仍然为简约的二线结构;4.I2C总线上的所有器件都具有“自动应答”功能,保证了数据交换的正确性;5.I2C总线系统具有“时钟同步”功能。利用SCL线的“线与”逻辑协调不同器件之间的速度问题;6.在I2C总线系统中可以实现“多主机(主控器)”结构。依靠“总线仲裁”机制确保系统中任何一个主控器都可以掌握总线的控制权。任何一个主控器之间没有优先级,没有中心主机的特权。当多主机竞争总线时,依靠主控器对其SDA信号的“线与”逻辑,自动实现“总线仲裁”功能;7.I2C总线系统中的主控器必须是带CPU的逻辑模块;而被控器可以是无CPU的普通外围器件,也可以是具有CPU的逻辑模块。主控器与被控器的区别在于SCL的发送权,即对总线的控制权;8.I2C总线不仅广泛应用于电路板级的“内部通信”场合,还可以通过I2C总线驱动器进行不同系统间的通信;9.I2C总线的工作速度分为3种版本:S(标准模式),速率为100kb/s。主要用于简单的检测与控制场合;F(快速模式),速率为400kb/s;Hs(高速模式),速率为3.4Mb/s。I2C总线的系统和接口内部结构2.1I2C总线的系统结构SDASCLSDASCLSDASCLSDASCLSDASCLSDASCL主控器A主控器B外围器件1外围器件2外围器件3外围器件nSDASCLVCC图7.1具有多主机的I2C总线的系统结构2.2I2C总线接口的内部结构每一个I2C总线器件内部的SDA、SCL引脚电路结构都是一样的,引脚的输出驱动与输入缓冲连在一起。其中输出为漏极开路的场效应管、输入缓冲为一只高输入阻抗的同相器。这种电路具有两个特点:串行时钟输入串行时钟输出串行数据输入串行数据输出图7.2I2C总线接口内部结构SDASCLVCCSCLSDA①由于SDA、SCL为漏极开路结构,借助于外部的上拉电阻实现了信号的“线与”逻辑;②引脚在输出信号的同时还将引脚上的电平进行检测,检测是否与刚才输出一致。为“时钟同步”和“总线仲裁”提供硬件基础。I2C总线的工作过程与原理总线上的所有通信都是由主控器引发的。在一次通信中,主控器与被控器总是在扮演着两种不同的角色。3.1主控制器向被控器发送数据操作过程如下:(1)主控器在检测到总线为“空闲状态”(即SDA、SCL线均为高电平)时,发送一个启动信号“S”,开始一次通信的开始;(2)主控器接着发送一个命令字节。该字节由7位的外围器件地址和1位读写控制位R/W组成(此时R/W=0);(3)相对应的被控器收到命令字节后向主控器回馈应答信号ACK(ACK=0);(4)主控器收到被控器的应答信号后开始发送第一个字节的数据;(5)被控器收到数据后返回一个应答信号ACK;(6)主控器收到应答信号后再发送下一个数据字节……(7)当主控器发送最后一个数据字节并收到被控器的ACK后,通过向被控器发送一个停止信号P结束本次通信并释放总线。被控器收到P信号后也退出与主控器之间的通信。从机地址(7位)SR/WA数据1P地址字节(命令字)N个数据字节的写入应答信号启动信号停止信号图7.3主控器向被控器写N个数据的过程主控器产生的信号被控器产生的信号A数据2A数据1A数据NA需要说明的是:①主控器通过发送地址码与对应的被控器建立了通信关系,而挂接在总线上的其它被控器虽然同时也收到了地址码,但因为与其自身的地址不相符合,因此提前退出与主控器的通信;②主控器的一次发送通信,其发送的数据数量不受限制。主控器是通过P信号通知发送的结束,被控器收到P信号后退出本次通信;③主机的每一次发送后都是通过被控器的ACK信号了解被控器的接收状况,如果应答错误则重发。3.2主控器接收数据的过程过程简述如下:(1)主机发送启动信号后,接着发送命令字节(其中R/W=1);(2)对应的被控器收到地址字节后,返回一个应答信号并向主控器发送数据;(3)主控器收到数据后向被控器反馈一个应答信号;(4)被控器收到应答信号后再向主控器发送下一个数据……;(5)当主机完成接收数据后,向被控器发送一个“非应答信号(ACK=1)”,被控器收到ASK=1的非应答信号后便停止发送;(6)主机发送非应答信号后,再发送一个停止信号,释放总线结束通信。主控器所接收数据的数量是由主控器自身决定,当发送“非应答信号/A”时被控器便结束传送并释放总线(非应答信号的两个作用:前一个数据接收成功,停止从机的再次发送)。从机地址(7位)SR/WA数据1P地址字节N个数据字节的接收应答信号启动信号停止信号图7.4主控器接收N个数据的过程A数据2A数据1/A数据NA主控器产生的信号被控器产生的信号I2C总线的信号时序以主控器向被控器发送一个字节的数据(写操作R/W=0)为例。整个过程由主控器发送起始信号S开始,紧跟着发送一个字节的命令字(7位地址和一个方向位R/W=0),得到被控器的应答信号(ACK=0)后就开始按位发送一个字节的数据。得到应答后发送P信号,一个字节的数据传送完毕。其数据传送的时序如图7.5所示。12345678D7D0SDASCLR/WD7D09ACK主控器发送8位数据ACK主控器发送STOP信号主控器发送命令字节主控器发送数据字节被控器应答被控器应答主控器发送START信号图7.5主控器发送一个字节数据的时序被控器7位地址D1在数据传送中数据高位(D7)在先,SDA线上的数据在时钟脉冲SCL为低电平时允许变化(如图所示),在数据稳定后时钟脉冲为高电平期间传送数据有效。主控器接收数据(R/W=1)的时序类似于发送,主要区别有两点:①主机接收到数据后要向被控器发送应答信号(ACK=0);②当主机接收完最后一个数据时向被控器返回一个“非应答信号/ACK=1”以通知被控器结束发送操作,最后主控器发送一位停止信号P并释放总线(参见图7.4)。这里具体的时序可以在后面的“接收子程序”中进行描述。I2C总线的时钟同步与总线仲裁I2C总线的SCL同步时钟脉冲一般都是由主控器发出作为串行数据的移位脉冲。每当SDA上出现一位稳定的数据后,在SCL上发送一个高电平的移位脉冲。5.1SCL信号的同步如果被控器希望主控器降低传送速度可以通过将SCL主动拉低延长其低电平时间的方法来通知主控器,当主控器在准备下一次传送发现SCL的电平被拉低时就进行等待,直至被控器完成操作并释放SCL线的控制控制权。这样以来,主控器实际上受到被控器的时钟同步控制。可见SCL线上的低电平是由时钟低电平最长的器件决定;高电平的时间由高电平时间最短的器件决定。这就是时钟同步,它解决了I2C总线的速度同步。5.2I2C总线上的总线仲裁如果在同一个I2C总线系统中存有两个主控器,其时钟信号分别为SCK1、SCK2,它们都具有控制总线的能力。假设两者都开始要控制总线进行通信,由于“线与”的作用,实际的SCL的波形如图7.6所示。在总线做出仲裁之前,两个主控器都会以“线与”的形式共同参与SCL线的使用,速度快的主控器1等待落后的主控器2(如图7.6)。SCK1SCK2SCL图7.6SCL信号的同步主机1等待DATA1DATA2SDASCL110010100图7.7I2C总线上的总线仲裁时序图总线得到仲裁主控器1释放总线S对于SDA线上的信号的使用,两个主控器同样也是按照“线与”的逻辑来影响SDA上的电平变化。假设主控器1要发送的数据DATA1为“101……”;主控器2要发送的数据DATA2为“1001……”。总线被启动后两个主控器在每发送一个数据位时都要对自己的输出电平进行检测,只要检测的电平与自己发出的电平一致,他们就会继续占用总线。在这种情况下总线还是得不到仲裁。当主控器1发送第3位数据“1”时(主控器2发送“0”),由于“线与”的结果SDA上的电平为“0”,这样当主控器1检测自己的输出电平时,就会测到一个与自身不相符的“0”电平。这时主控器1只好放弃对总线的控制权;因此主控器2就成为总线的唯一主宰者。仲裁过程如图5.2所示。不难看出:①对于整个仲裁过程主控器1和主控器2都不会丢失数据;②各个主控器没有对总线实施控制的优先级别;③总线控制随即而定,他们遵循“低电平优先”的原则,即谁先发送低电平谁就会掌握对总线的控制权。根据上面的描述,“时钟同步”与“总线仲裁”可以总结如下规律:①主控器通过检测SCL上的电平来调节与从器件的速度同步问题——时钟同步;②主控器通过检测SDA上自身发送的电平来判断是否发生总线“冲突”——总线仲裁。因此,I2C总线的“时钟同步”与“总线仲裁”是靠器件自身接口的特殊结构得以实现的。I2C总线的工作时序与AT89C51单片机的模拟编程对于具有I2C总线接口的高档单片机来说,整个通信的控制过程和时序都是由单片机内部的I2C总线控制器来实现的。编程者只要将数据送到相应的缓冲器、设定好对应的控制寄存器即可实现通信的过程。对于不具备这种硬件条件的AT89C51单片机来说只能借助软件模拟的方法实现通信的目的。软件模拟的关键是要准确把握I2C总线的时序及各部分定时的要求。单片机与I2C器件的连接及引脚定义由图7.8所示,使用伪指令定义对I/O端口进行定义(设单片机的系统时钟fosc为6M,即单周期指令的运行时间为2μS)。AT89C51(主控器)P1.0P1.1外围器件(被控器)SDASCL图7.8单片机与I2C器件的连接SDABITP1.0SCLBITP1.16.1发送启动信号S在同步时钟线SCL为高电平时,数据线出现的由高到低的下降沿。启动信号子程序STASDASCLtHD:STA>4μS启动信号>4.7μS图7.9启动信号的时序图STA:SETBSDASETBSCLNOPNOP;完成4.7μS定时CLRSDA;产生启动信号NOPNOP;完成tHD,STA定时CLRSCLRET【注】tHD,STA:起始信号保持时间,最小值为4μS。在这个信号过后才可以产生第一个同步信号;6.2发送停止信号P在SCL为高电平期间SDA发生正跳变。SDASCLtSU:SOP>4μS停止信号tBUF>4.7μS图7.10停止信号的时序图停止信号子程序STOPSTOP:CLRSDASETBSCLNOPNOP;tSU:SOP定时SETBSDANOPNOP;tBUF定时CLRSCLCLRSDARET【注】tSU:SOP停止信号建立时间应大于4.0μS。tBUFP信号和S信号之间的空闲时间应大于4.7μS。6.3发送应答信号ACKtHIGH>4μS图7.11应答信号MACK时序图SDASCL在SDA为低电平期间,SCL发送一个正脉冲。应答信号子程序MACKMACK:CLRSDASETBSCLNOPNOP;产生tHIGH定时CLRSCLSETBSDARET【注】tHIGH同步时钟SCL高电平最小时间,应大于4.0μS。6