IIC设备驱动程序(十一)————I2C 原理及应用

来源:互联网 发布:nginx image filter 编辑:程序博客网 时间:2024/05/21 17:56

1. I2C总线介绍

I2C(Inter-Integrated Circuit)总线(也称IIC或I2C)是由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备,是微电子通信控制领域广泛采用的一种总线标准。它是同步通信的一种特殊形式,具有接口线少、控制方式简单、器件封装形式小、通信速率较高等优点。I2C有着如下的特点。
        (1)两条总线线路:一条串行数据线SDA,一条串行时钟线SCL。
        (2)每个连接到总线的器件都可以通过唯一的地址联系主机,同时主机可以作为主机发送器或主机接收器。
        (3)是一个真正的多主机总线,如果两个或更多主机同时初始化,数据传输可以通过冲突检测和仲裁防止数据被破坏。
        (4)串行的8位双向数据传输位速率在标准模式下可达100 kbit/s,快速模式下可达400 kbit/s,高速模式下可达3.4Mbit/s。
        (5)连接到相同总线的I2C数量只受到总线的最大电容400 pF限制。

2. I2C总线术语

发送器:发送数据到总线的器件。
        接收器:从总线接收数据的器件。
        主机:初始化发送产生的时钟信号和终止发送的器件。
        从机:被主机寻址的器件。
        多主机:同时有多于一个主机尝试控制总线但不破坏传输。
        仲裁:是一个在有多个主机同时尝试控制总线但只允许其中一个控制总线并使传输不被破坏的过程。
        同步:两个或多个器件同步时钟信号的过程。

3. I2C总线位传输

由于连接到I2C 总线的器件有不同种类的工艺(CMOS、NMOS、双极性),逻辑0(低)和逻辑1(高)的电平不是固定的,它由电源VCC的相关电平决定,每传输一个数据位就产生一个时钟脉冲,数据有效性如图1所示。


图1 数据有效性

SDA 线上的数据必须在时钟的高电平周期保持稳定。数据线的高或低电平状态 I2C位传输数据的有效性在SCL 线的时钟信号是低电平时才能改变,起始和停止条件如图2所示。


图2 起始和停止条件

SCL 线是高电平时,SDA 线从高电平向低电平切换,这个情况表示起始条件;SCL线是高电平时,SDA 线由低电平向高电平切换,这个情况表示停止条件。起始和停止条件一般由主机产生,总线在起始条件后被认为处于忙碌状态,在停止条件的某段时间后总线被认为再次处于空闲状态。如果产生重复起始条件而不产生停止条件,总线会一直处于忙碌的状态,此时的起始条件(S)和重复起始条件(Sr) 在功能上是一样的。

3. I2C总线数据传输

1.字节格式

发送到SDA线上的每个字节必须为8位,每次传输可以发送的字节数量不受限制。每个字节后必须跟一个响应位。首先传输的是数据的最高位(MSB),如果从机要完成一些其他功能后(如一个内部中断服务程序)才能接收或发送下一个完整的数据字节,可以使时钟线SCL保持低电平,迫使主机进入等待状态,当从机准备好接收下一个数据字节并释放时钟线SCL后,数据传输继续。

2.应答响应

应答响应如图3所示。

数据传输必须带响应,相关的响应时钟脉冲由主机产生。在响应的时钟脉冲期间发送器释放

SDA 线(高)。在响应的时钟脉冲期间,接收器必须将SDA 线拉低,使它在这个时钟脉冲的高电平期间保持稳定的低电平。通常被寻址的接收器在接收到每个字节后,会产生一个响应。当从机不能响应从机地址时(如它正在执行一些实时函数不能接收或发送),从机必须使数据线保持高电平,主机然后产生一个停止条件终止传输或者产生重复起始条件开始新的传输。


图3 应答响应

如果从机接收器响应了从机地址,但是在传输了一段时间后不能接收更多数据字节,主机必须再一次终止传输。这个情况用从机在第一个字节后没有产生响应来表示。从机使数据线保持高电平,主机产生一个停止或重复起始条件。

如果传输中有主机接收器,它必须在从机不产生时钟的最后一个字节不产生响应,向从机发送器通知数据结束。从机发送器必须释放数据线,允许主机产生一个停止或重复起始条件。

4. I2C总线寻址方式

1.7位寻址

第一个字节的头7位组成了从机地址,最低位(LSB)是第8位,它决定了普通的和带重复开始条件的7位地址格式方向。第一个字节的最低位是“0”,表示主机会写信息到被选中的从机;“1”表示主机会向从机读信息,当发送了一个地址后,系统中的每个器件都在起始条件后将头7位与它自己的地址比较,如果一样,器件会判定它被主机寻址,至于是从机接收器还是从机发送器,都由R/W位决定。

2.10位寻址

10位寻址和7位寻址兼容,而且可以结合使用。10位寻址采用了保留的1111XXX作为起始条件,或重复起始条件的后第一个字节的头7位。10位寻址不会影响已有的7位寻址,有7位和10位地址的器件可以连接I2C总线10位地址格式到相同的I2C总线。它们都能用于标准模式和高速模式系统。

10位从机地址由在起始条件或重复起始条件后的头两个字节组成。第一个字节的头7位是11110XX的组合,其中最后两位XX是10位地址的两个最高位(MSB)。第一个字节的第8位是R/W位,决定了传输的方向,第一个字节的最低位是“0”,表示主机将写信息到选中的从机,“1”表示主机将向从机读信息。如果R/W位是“0”,则第二个字节是10位从机地址剩下的8位;如果R/W位是“1”,则下一个字节是从机发送给主机的数据。

5 快速和高速模式

1.快速模式

快速模式器件可以在400 kbit/s下接收和发送。最小要求是:它们可以和400 kbit/s传输同步,可以延长SCL信号的低电平周期来减慢传输。快速模式器件都向下兼容,可以和标准模式器件在0~100 kbit/s的I2C 总线系统通信。但是,由于标准模式器件不向上兼容,所以不能在快速模式I2C总线系统中工作。快速模式I2C总线规范与标准模式相比有以下另外的特征。
        (1)最大位速率增加到400 kbit/s。
        (2)调整了串行数据(SDA)和串行时钟(SCL)信号的时序。
        (3)快速模式器件的输入有抑制毛刺的功能,SDA和SCL输入有施密特触发器。
        (4)快速模式器件的输出缓冲器对SDA和SCL信号的下降沿有斜率控制功能。
        (5)如果快速模式器件的电源电压被关断,SDA和SCL的I/O引脚必须悬空,不能阻塞总线。
        (6)连接到总线的外部上拉器件必须调整以适应快速模式I2C总线更短的最大允许上升时间。对于负载最大是200 pF的总线,每条总线的上拉器件可以是一个电阻,对于负载在200~400 pF之间的总线,上拉器件可以是一个电流源(最大值3 mA)或者是一个开关电阻电路。

2.高速模式

高速模式(Hs模式)器件对I2C总线的传输速度有很大的突破。高速模式器件可以在高达3.4 Mbit/s的位速率下传输信息,而且保持完全向下兼容快速模式或标准模式器件,它们可以在一个速度混合的总线系统中实现双向通信。

高速模式传输除了不执行仲裁和时钟同步外,与快速模式系统有相同的串行总线协议和数据格式。

6. S5PC100下的I2C控制器介绍

S5PC100处理器支持多主机I2C串行总线接口,并且它支持主机发送模式、主机接收模式、从机发送模式和从机接收模式4种模式,图4所示为I2C总线的概括图。


图4 I2C总线的概括图

7. I2C总线控制寄存器详解

表1为I2C总线控制寄存器描述。

表1        I2C总线控制寄存器

I2CCON位描 述复 位 值应答产生[7]IIC应答产生使能位
     0 = 禁止 1 = 使能0Tx时钟源选择[6]IIC传输时钟预分值选择位
     0 = I2CCLK = fPCLK /16
     1= I2CCLK = fPCLK /5120Tx/Rx中断[5]I C-Bus Tx/Rx 中断控制位
     0 = 禁止 1 = 使能0传输时钟值[3:0]IIC总线时钟预分值
     Tx clock = I2CCLK/(I2CCON[3:0]+1)未定义

表2为I2C状态寄存器描述。

表2        I2C状态寄存器

I2CSTAT位描 述复 位 值模式选择[7:6]IIC总线主/从Tx/Rx模式选择位
     00=从机接收模式
     01=从机发送模式
     10=主机接收模式
     11=主机发送模式00忙信号状态位[5]IIC 总线忙信号状态位
     读:0=准备
 &nbsnbsp;   1=忙
     写:产生开启信号0串行输出[4]IIC总线数据输出使能/禁止位
     0=禁止Rx/Tx 1=使能Rx/Tx0Ar位定量状态标志[3]0=定量成功
     1=失效0从地址状态标志[2]0=当开启/停止条件侦测到时清除
     1=接收到的从地址匹配I2CADD的地址值0地址0状态标志[1]0=当开启/停止条件侦测到时清除
     1=接收从地址值为00000000b0最后的接收位状态标志[0]0=为0
     1=为10

表3为I2C数据发送/接收移位寄存器描述。

表3        I2C数据发送/接收移位寄存器

I2CDS位描 述复 位 值保留位[31:8]保留位,没有使用未定义数据移位[7:0]8位数据移位寄存器
     如果串行输出使能,则I2CDS将变为可写。并且
     I2CDS任何时刻都是可读的,不管当前I2CSTAT的设置未定义

8. 电路原理分析

结合上面已经提到的I2C理论基础,将以一个例子来进行实际讲解,用I2C来操作LM75温度传感器。

图5所示为LM75的原理图。


图5 LM75原理图

可以看到SDA/SCL被接到了S5PC100的IIC控制器上,并且接了一个外部中断,该中断可作为从机应答信号。

下面简单介绍一下LM75的操作时序,其操作时序的第一部分如图6所示。


图6 LM75操作时序第一部分

如图6所示显示了LM75操作时序的第一阶段,可以看到,如果要获取数据,需要先配置一下模式,并且LM75的从机地址为0x90,发送地址后要做的就是配置工作模式,LM75芯片提供了以下4种模式。

(1)温度(只读模式)。

(2)配置(读/写)。

(3)T(HYST读/写)。

(4)T(OS读/写)。

这里选择第一个即可,也就是发送0x0,接着有如图7所示的时序。


图7 时序第二部分

接下来再次发送从机地址,选择LM75芯片后,即可等待芯片回送数据,这时芯片会发送给主机端两次数据,第一次是主要值,第二次是小数部分,最小能精确到0.5。要注意的是每一次都要进行应答,才能保证数据的有效性。

9. 代码实现

1.寄存器定义

/*IIC寄存器结构体定义*/
        /*
        *I2C0 REGISTERS
        */
        typedef struct {
                unsigned int I2CCON0 ;
                unsigned int I2CSTAT0 ;
                unsigned int I2CADD0 ;
                unsigned int I2CDS0 ;
                unsigned int I2CLC0 ;
        }i2c0;
        #define I2C0 (* (volatile i2c0 *)0xEC100000 )
        /*设置GPIO*/
        void cfg_gpio(void)
        { 
                GPD.GPDCON=(GPD.GPDCON&(~((0X0f<<12)|(0x0f<<16))))+((2<<12) | (2<<16)) ;
        }
        /*写入LM75要读取的地址,然后读出2字节的温度数据*/
        int set_pointer_and_read_2byte(int mode)
        {
                I2C0.I2CDS0 = 0x90;        /*LM75 SLAVE ADDRESS 第0位为0 代表接下来是要写入数据*/
                I2C0.I2CCON0 = 0xe0;        /*ENABLE ACK BIT, PRESCALER:512 ,RX/TX INTERRUPT ENABLE ,*/
                I2C0.I2CSTAT0 =0xf0;        /*Master Trans mode ,START ,ENABLE RX/TX ,*/
                while(!(I2C0.I2CCON0&(1<<4)));        /*The end of the waiting to be sent */
                I2C0.I2CDS0 = mode;        // READ TEMPERATURE ONLY
                I2C0.I2CCON0 &= ~(1<<4);        /* Clear pending condition & Resume the operation */
                while(!(I2C0.I2CCON0&(1<<4)));        /*The end of the waiting to be sent */
                // 以上是主机发送一个从机地址和一个从机的命令
                I2C0.I2CDS0 = 0x91;        /*Again to send LM75 salve address 第0位为1 代表接下来是要读出数据*/
                I2C0.I2CSTAT0 =0xb0;        /*Master receive mode ,START ,ENABLE RX/TX ,*/
                I2C0.I2CCON0 &= ~(1<<4);        /* Clear pending condition & Resume the operation */
                while(!(I2C0.I2CCON0&(1<<4)));        /*The end of the waiting to be sent */
                I2C0.I2CCON0 &= ~(1<<4);        /* Clear pending condition & Resume the operation */
                while(!(I2C0.I2CCON0&(1<<4)));        /*The end of the waiting to read */
                high = I2C0.I2CDS0;        /*read temperature of low 8 bit */
                I2C0.I2CCON0 &= ~((1<<7)|(1<<4)); 
                /* Clear pending condition & Resume the operation & no ack*/
                while(!(I2C0.I2CCON0&(1<<4)));        /*The end of the waiting to read */
                low = I2C0.I2CDS0;        /*read temperature of low 2 bit */
                I2C0.I2CSTAT0 &= ~(1<<5);        /*STOP signal generation,free bus */
                I2C0.I2CCON0 &= ~(1<<4);        /*clean interrup pending bit */
                return ((high << 8) | low);
        }
        int main()
        {
                volatile int delay;
                int low, high, temp, config, i;
                uart0_init();
                cfg_gpio();
                /*循环打印采集的数据*/
                while (1){
                        read_data_one();        // 配置模式
                        temp = read_data_two();        // 开始连续两次读数据
                        high = temp >> 8;
                        low = temp & 0xff;
                        printf("TEMP is : %d.%d\n", high, (((low>>7)==0) ? 0 : 5));
                }
                return 0;
        }

2.实验调试过程与结果

编译生成的.elf文件,连接硬件。并连接好FS_JTAG仿真器套件。将程序编译后获得.elf文件,将该文件通过仿真器下载并运行在目标板上,终端打印信息如图8所示。

TEMP is :22.5
        TEMP is :22.5
        TEMP is :23.0
        TEMP is :23.0
        TEMP is :23.0
        TEMP is :23.5
        TEMP is :23.5
        TEMP is :23.5
        TEMP is :23.5
        TEMP is :23.5
        TEMP is :23.5


阅读全文
1 0
原创粉丝点击