嵌入式常用技术概览之IIC(I2C)

2019-04-13 11:33发布

一、先决知识

            (1)模电基础知识(用以理解IIC如何通信)

二、IIC概览

              I2C是80年代飞利浦(Philips->NXP->高通)研发的双线串行总线。目前,I2C广泛应用与单微处理器,EEPROM,数模转换,压力传感器等芯片的接口。

三、IIC结构,协议和时序

        1、总线结构

                        由图中可知               SDA:data line (数据传输线)                SCL:clock line (时钟线)            (1)IIC采用了双线总线           (2)由1,2箭头指示可知 IIC器件内部采用了开漏的方法,总线被上拉,即总线状态只能是被下拉为0(当MOS管输入0的时候)            (3)只要有一方下拉了总线,总线状态必定为0

        2、IIC协议

        (1)模式               

标准IIC速度Standard-mode (Sm)普通模式 100 kbit/s
Fast-mode (Fm)快速模式
400 kbit/s
High-speed mode (Hs-mode)高速模式
3.4 Mbit/s
变种IIC
Fast-mode Plus (Fm+)快速+模式
1 Mbit/s
Low-speed mode(Ls-mode)低速模式10kb/s

        (2)具体通信时序

                ①IIC协议上不区分主从设备,谁发起谁是主设备
                ②IIC通信时序的组成元素
            
               易见:IIC时序主由以上四个元素组成
            如何理解这四个时序?            由于IIC只有两根线,其中一根被用于时钟信号(SCL),且如我们一般所知的,CLK在高电平时传输的是数据是稳定的,那么就传输的内容可以分为两种情况:在CLK高时不变的是数据位,在CLK高时跳变的是控制位。并且跳变有两个方向:1-0和0-1(又知SDA总线闲事是1,且只有下拉操作)故1-0是开始信号,0-1是结束信号(释放总线信号)
           由于,SDA传输完一个bit之后,主机会释放SDA线(最后一位是0时即取消下拉或者最后一位本来就是1),这时SDA处于高电平的状态,从机就可以控制SDA线了,若从机下拉了SDA线并且主机从SDA读到了这一个低电平,则表示从机发送了一个确认信号(0)。若从机不对SDA下拉,则主机读到SDA依然位高电平,故表示一个非应答信号(1)。
        
            ③如何发起通信
            
         流程如上图,可以总结位:设备发出开始信号(当总线没有被占用时)通知其他设备总线被‘我’占用了我要开始操作了,成为主机-->主机占用SDA发出地址和读/写操作-->主设备放SDA-->地址对应的设备占用SDA,发出回应(其他设备忽略,并且记下总线被占用了)-->主设备收到回复重新占用SDA发送数据-->主设备释放SDA等待回应-->从设备占用SDA发出ack信号-->主设备发出停止信号,告知从设备和其他设备通信结束,总线被释放 。
            ④常见读写时序
                Ⅰ:单字节写(如上图)(数据只能在SCLK为低的时候变换,高的时候要保持稳定)

            ⑤关于IIC设备地址问题

               Ⅰ:通常 设备地址的高7位为地址,最低位  读写操作位 0位读 1为写              Ⅱ:设备地址数的问题:理论上7位由128位地址,然而除去保留几个保留地址如广播地址0x00等,数量少于128个,且标准协议里遇见了地址的局限性,扩充了10位地址的概念(此处不进行论述)
            Ⅲ:对于IIC可以挂多少个设备的问题:对于同一个地址的设备来说,在不进行地址扩充(片选)的情况下只能挂一个,对于不同的设备来说,标准协议里面没由限制具体的个数的多少,这个由线路布线情况,软件情况以及工作模式确定。对于标准模式,只要总线上的负载电容不超过400pf,不超过芯片的负载能力既可以。

四、如何模拟IIC通信协议

        (1)由上可见,我们只要模拟4个1位的基本信号+2个8位传输信号就可以完成所有的模式。        具体要实现的函数        Ⅰ:I2C_START()  //开始信号
        Ⅱ:I2C_STOP()    //结束信号
        III: I2C_ACK()        //发送响应信号
        Ⅳ:I2C_NACK()    //发送非响应信号        Ⅵ:I2C_SEND(unsinged char data) //数据发送信号
        Ⅶ:I2C_READ(unsigned char * data)//数据读取信号
        显现时需要注意的细节:结束后总是释放SDA,即输出1。时序的延时问题要小心,参看具体器件的datasheet。