本章目标:
了解I2C总线协议;
掌握S3C2410/S3C2440中I2C接口的使用方法;
12.1 I2C总线协议及硬件介绍
12.1.1 I2C总线协议
1 I2C总线的概念
2 I2C总线的信号类型
3 I2C总线的数据传输格式
12.1.2 S3C2410/S3C2440 I2C总线控制器
1. S3C2410/S3C2440 I2C总线控制器寄存器介绍
    S3C2410/S3C2440的I2C接口有4种工作模式:主机发送、主机接收、从机发送、
从机接收。其内部结构如图12.6所示。
JZ2440 裸机驱动 第12章 I2C接口
    从图12.6可知,S3C2410/S3C2440提供4个寄存器来完成所有的I2C操作。SDA线上的数据
从IICDS寄存器发出,或传入IICDS寄存器中;IICADD寄存器中保存S3C2410/S3C2440当做从
机时的地址;IICCON、IICSTAT 两个寄存器用来控制或标识各种状态,比如选择工作模式,发出
S信号、P信号,决定是否发出ACK信号,检测是否收到ACK信号。各寄存器的用法如下:
(1)IICCON寄存器(Multi-master IIC-bus control)
    IICCON寄存器用于控制是否发出ACK信号、设置发送器的时钟、开启IIC中断,并标识中断是
发生。它的各位含义如下表12.2所示。
JZ2440 裸机驱动 第12章 I2C接口
     使用IICCON寄存器时,有如下注意事项:
    ① 发送模式的时钟频率由位[6]、位[3:0]联合决定。另外,当IICCON[6] = 0时,IICCON[3:0]
不能去0或1。
    ② IIC中断在以下3种情况下发生:
        当发出地址信息或接收到一个从机地址并且吻合时;
        当总线仲裁失败时;
        当发送/接收完一个字节的数据(包括响应位)时。
    ③ 基于SDA 、SCL线上时间特性的考虑,要发送数据时,先将数据写入IICDS寄存器,
然后清除中断。
    ④ 如果IICCON[5] = 0,IICCON[4]将不能正常工作。所以即使不使用IIC中断,也要将
IICCON[5]设为1。
(2)IICSTAT寄存器(Multi-master IIC-bus control/status)。
    IICSTAT寄存器用于选择IIC接口的工作模式,发出S信号、P信号,使能接收/发送功能,
并标识各种状态,比如总线仲裁是否成功、作为从机时是否被寻址、是否接收到0地址、是
否接收到ACK信号等。
    IICSTAT寄存器的各位如表12.3所示:
JZ2440 裸机驱动 第12章 I2C接口
(3)IICADD寄存器(Multi-master IIC-bus address)
    用到位[7:1],表示从机地址。在IICSTAT[4]为1时,才可以写入;随时都可以读出。
(4)IICDS寄存器(Multi-master IIC-bus Tx/Rx data shift)
    用到位[7:0],其中保存的是要发送或已经接收到的数据。在IICSTAT[4]为1时才可写入,
随时可以读出。
2.S3C2410/S3C2440 I2C总线操作方法
    启动或复位S3C2410/S3C2440 的IIC传输有以下两种方法。
(1)当IICCON[4]即中断状态位为0时,通过写IICSTAT寄存器启动IIC操作。有以下两种
情况。
    ① 在主机模式:
        令IICSTAT[5:4]等于0b11,将发出S信号和IICDS寄存器的数据(寻址),
        令IICSTAT[5:4]等于0b01,将发出P信号。
    ② 在从机模式,令IICSTAT[4]等于1,将等待其他主机发出S信号及地址信息。
(2)当IICCON[4]即中断状态位为1时,表示I2C操作被暂停。在这期间设置好其他寄存器
之后,向IICCON[4]写入0即可恢复I2C操作。
    所谓“设置其他寄存器”,有以下3种情况。
    ① 对于主机模式,可以按照上面(1)的方法写IICSTAT寄存器,恢复I2C操作后即可发出
S信号和IICDS寄存器的值(寻址),或发出P信号。
    ② 对于发送器,可以将下一个要发送的数据写入IICDS寄存器中,恢复I2C操作后即可发
出这个数据。
    ③ 对于接收器,可以从IICDS寄存器中读出接收到的数据。最后向IICCON[4]写入0的同时,
设置IICCON[7]以决定在接收到下一个数据后是否发出ACK信号。
 
    通过中断服务程序驱动I2C传输。
(1)当仲裁失败时,发生中断——本次传输没有抢到总线,可以稍后继续。
(2)对于主机模式,当发出S信号、地址信息并经过一个SCL周期(对应ACK信号)后,发生
中断——主机可在此时判断是否成功寻址到从机。
(3)对于从机模式,当接收到的地址与IICADD寄存器吻合时,先发出ACK信号,然后发生
中断——从机可在此时准备后续的传输。
(4)对于发送器,当发送完一个数据并经过一个SCL周期(对应ACK信号)后,发生中断。这
时可以准备下一个要发送的数据,或发出P信号以停止传输。
(5)对于接收器,当接收到一个数据时,先根据IICCON[7]决定是否发出ACK信号后,然后
发生中断。这是可以读取IICDS寄存器得到数据,并设置IICCON[7]已决定接收到下一个数
后是否发出ACK。
 
    对于4种工作模式,S3C2410/S3C2440数据手册中都有它们的操作流程图。现在以主机发
送器为例说明,它的工作流程如图12.7所示,其他的工作模式请参考数据手册。

JZ2440 裸机驱动 第12章 I2C接口

    下面结合I2C寄存器的用法,详细讲解图12.7中各步骤的含义。
(1)配置主机发送器的各类参数
    设置GPE15、GPE14引脚用于SDA、SCL,设置IICCON寄存器选择I2C发送时钟,最后,
设置IICSTAT[4]为1,这样,后面才能写IICDS寄存器。
    注意:初始时IICCON[4]为0,不能将IICSTAT设为主机模式,否则就会立刻发出S信号、
发送IICDS寄存器里的值。
(2)将要寻址的从机地址写入IICDS寄存器。
(3)将0xF0写入IICSTAT寄存器,即设为主机发送器、使能串行输出功能、发出S信号。
(4)发出S信号后,步骤(2)中设置的IICDS寄存器值也将被发出,它用来寻址从机。
(5)在响应周期之后,发生中断,此时IICCON[4]为1,I2C传输暂停。
(6)如果没有数据要发送,则跳到步骤(10);否则跳到步骤(7)。
(7)将下一个要发送的数据写入IICDS寄存器中。
(8)向IICCON[4]中写入0,恢复I2C传输。
(9)这时,IICDS寄存器中的值将被一位一位地发送出去。当8位数据发送完毕,再经过
另一个SCL周期(对应ACK信号)后,中断再次发生,跳到步骤(5)。
    步骤(5)~(9)不断循环知道发出所有数据。当要停止传输时,跳到步骤(10)。
(10)将0xF0写入IICSTAT寄存器,即设为主机发送器、使能串行输出功能、发出P信号。
            注意:这时的P信号并没有实际发出,只有清除了IICCON[4]后才会发出P信号。
(11)清除IICCON[4],P信号得以发出。
(12)等待一段时间,使得P信号完全发出。
12.2 I2C总线操作实例
12.2.1 I2C接口RTC芯片M41t11的操作方法
    本书所用开发板中,通过I2C总线连接RTC(实时时钟)芯片M4lt11,它使用电池供电,
断电时也可以维持日期和时间。S3C2410/S3C2440作为I2C主机向M4lt11发送数据以设
置日期和时间、读取M4lt11以获取日期和时间。连接图如图12.8所示。
JZ2440 裸机驱动 第12章 I2C接口
     M4lt11中有8个寄存器,分别对应秒、分、时、天(星期几)、日、月、年、控制寄存器,
其中的数据都是以BCD格式保存(BCD格式例子:0x15表示数值15),如表12.4所示。
JZ2440 裸机驱动 第12章 I2C接口
     除上表的8个寄存器(地址为0~7)之外,M4lt11内部还有56字节的RAM(地址为8~63)。
访问M4lt11前,先设置寄存器地址,以后每次读写操作完成后,M4lt11内部会自动将寄
存器地址加1.
    所以读写M4lt11分以下两个步骤:
    (1)主机向M4lt11发出要操作的寄存器起始地址(0~7)。
    (2)要设置M4lt11时,主机连续发出数据;读取M4lt11时,主机连续读取数据。
    M4lt11的I2C从机地址为0xD0。
12.2.2 程序设计
    本实例将在串口上输出一个菜单,可以选择设置时间和日期,或者将它们读出来。将
通过本实例验证I2C主机的发送、接收操作。
12.2.3 设置/读取M4lt11的源码详解
    本实例的源码在/work/hardware/i2c目录下。
    文件i2c.c封装了S3C2410/S3C2440作为主机发送器、主机接收器的4个操作函数:
i2c_init用于初始化,i2c_write用于发起发送数据,i2c_read用于发起读取数据,
I2CIntHandle是I2C中断服务程序,用于完成后续的数据传输。
1.S3C2410/S3C2440 I2C控制器初始化
    i2c_init函数对应于图12.7中的步骤(1),初始化I2C,代码如下:
 1 行号
 2 24行/*
 3 25行 *I2C初始化
 4 26行 */
 5 27行 void i2c_init(void)
 6 28行 {
 7 29行    GPEUP |= 0xc000;        //禁止内部上拉
 8 30行    GPECON |= 0xa0000000;    //选择引脚功能,GPE15:IICSDA,GPE14:IICSCL
 9 31行
10 32行    INTMSK &= ~(BIT_IIC);
11 33行
12 34行    /*bit[7] = 1,使能ACK
13 35行     *bit[6] = 0,IICCLK = PCLK/16
14 36行     *bit[5] = 1,使能中断
15 37行     *bit[3:0] = 0xf,Tx clock = IICCLK/16
16 38行     *PCLK = 50MHz、IICCLK = 3.125MHz,Tx Clock = 0.195MHz
17 39行     */
18 40行    IICCON = (1 << 7) | (0 << 6) | (1 << 5) | (0xf);    //0xaf
19 41行
20 42行    IICADD  = 0x10;        //S3C24xx slave address = [7:1]
21 43行    IICSTAT = 0x10;        //I2C串行输出使能(Rx/Tx)
22 44行 }
23 45行
i2c.c->i2c_init()

相关文章:

  • 2021-06-13
  • 2021-08-13
  • 2021-06-17
  • 2021-05-27
  • 2021-11-01
  • 2022-12-23
  • 2021-12-08
猜你喜欢
  • 2021-12-23
  • 2021-11-05
  • 2021-12-23
  • 2021-09-02
  • 2022-12-23
  • 2022-12-23
  • 2021-11-03
相关资源
相似解决方案