【裸机开发】I2C 通信接口(二)—— I2C 寄存器解析

目录

一、硬件原理图分析

二、IO 复用寄存器解析

三、I2C 寄存器解析

3.1 时钟配置

3.2  I2C1_IADR(设置从机地址)

3.3  I2C1_IFDR(设置分频值)

3.4  I2C1_I2CR(I2C使能、中断控制)

3.5  I2C1_I2SR(保存通信状态)

3.6  I2C1_I2DR(数据发送 / 接收)

四、 AP3216C 解析

1、功能选择(0x00 — bit2:0)

2、IR + PS

3、ALS


一、硬件原理图分析

I2C 主要涉及到两个引脚,分别是 SCL 和 SDA,既然是涉及 IO,那就需要知道哪两个引脚可以被复用为 SCL 和 SDA。

首先看底板上的 I2C 模块。我们发现,IMX.6ULL 有两个 I2C 控制器,分别是 I2C1 和 I2C2。假设我们要使用 I2C1 。

然后再看底板上的 I2C 模块连接到了核心板上的哪些引脚。

最后就是找到和 UART4_TXD、UART4_RXD 相关的复用寄存器。

① TXD 相关(复用为SCL)

  • IOMUXC_SW_MUX_CTL_PAD_UART4_TX_DATA
  • IOMUXC_SW_PAD_CTL_PAD_UART4_TX_DATA

② RXD 相关(复用为 SDA)

  • IOMUXC_SW_MUX_CTL_PAD_UART4_RX_DATA
  • IOMUXC_SW_PAD_CTL_PAD_UART4_RX_DATA

二、IO 复用寄存器解析

IO 初始化就涉及到两方面,一个是指定复用为哪个功能,一个是配置复用引脚的电气属性,电气属性的初值和之前一样,设为 0x10B0。

  • IO 复用
    • IOMUXC_SW_MUX_CTL_PAD_UART4_TX_DATA复用为 SCL
    • IOMUXC_SW_MUX_CTL_PAD_UART4_RX_DATA(复用为 SDA)

  • 配置电气属性
    • IOMUXC_SW_PAD_CTL_PAD_UART4_TX_DATA(初值为 0x70B0)
    • IOMUXC_SW_PAD_CTL_PAD_UART4_RX_DATA(初值为 0x70B0)
/*************** SCL复用初始化 ******************/
寄存器(基地址): IOMUXC_SW_MUX_CTL_PAD_UART4_TX_DATA (0x20E00B4)
寄存器(基地址): IOMUXC_SW_PAD_CTL_PAD_UART4_TX_DATA (0x20E0340)
初始化操作:
    IOMUXC_SW_MUX_CTL_PAD_UART4_TX_DATA &=~ (0xF);    // 低4位清零
    IOMUXC_SW_MUX_CTL_PAD_UART4_TX_DATA |= 1;         // 复用为I2C1_SCL

    IOMUXC_SW_PAD_CTL_PAD_UART4_TX_DATA = 0x70B0;

/*************** SDA复用初始化 ******************/
寄存器(基地址): IOMUXC_SW_MUX_CTL_PAD_UART4_RX_DATA (0x20E00B8)
寄存器(基地址): IOMUXC_SW_PAD_CTL_PAD_UART4_RX_DATA (0x20E0344)
初始化操作:
    IOMUXC_SW_MUX_CTL_PAD_UART4_RX_DATA &=~ (0xF);    // 低4位清零
    IOMUXC_SW_MUX_CTL_PAD_UART4_RX_DATA |= 1;         // 复用为I2C1_SDA

    IOMUXC_SW_PAD_CTL_PAD_UART4_RX_DATA = 0x70B0;

三、I2C 寄存器解析

3.1 时钟配置

早在学习 CCM 配置时钟主频的时候,就已经配置过该寄存器了。 CSCMR1[PERCLK_PODF] 配置为 1 分频时,IPG_CLK_ROOT = PERCLK_CLK_ROOT = 66 MHz。

配置方式参考:IPG_CLK 配置

3.2  I2C1_IADR(设置从机地址)

如果当前设备是从机,才需要设置 I2C1_IADR 寄存器。如果当前设备是主机,设置的是I2C1_I2DR 寄存器。

寄存器: I2C1_IADR
基地址: 0x21A0000
地址设置: 
    I2C1_IADR = 0;           // 地址清零
    I2C1_IADR |= address;    // address 表示从机地址

3.3  I2C1_IFDR(设置分频值)

在 I2C 控制器内部还可以再次分频,时钟源就是 PERCLK_CLK_ROOT = IPG_CLK_ROOT = 66 MHz。标准模式下, I2C 传输速度最高可达 100 kbit/s,那么分频数 = 66000000 / 100000 = 660

我们要在下面这个表中找到分频数最接近 660 的,我们发现最接近的就是 640,因此寄存器要设置的值可以是 0x15、0x38

寄存器: I2C1_IFDR
基地址: 0x21A0004
地址设置: 
    I2C1_IFDR = 0x15;    // 分频值为 640    

3.4  I2C1_I2CR(I2C使能、中断控制)

bit 2: 产生一次重复启动。一般是主机用于修改通信方向或通信地址。如果总线已经被占用,却不是被当前设备占用,此时无法发送(0: 不重复启动        1: 产生一次重复启动)

bit 3: 发送应答。(0: 发送一次应答,相当于ACK=0        1: 不发送应答,相当于ACK=1)

bit 4: 设置通信方向。本质是在表明接下来要向 DR 寄存器读数据还是向 DR 寄存器写数据(0: 接收(读)        1: 发送(写) ) 

bit 5: 当前设备是主机还是从机。该位一旦被置1,相当于发出了要占用主线的开始信号。如果有多主机参与总线占用,会发生仲裁,当前设备如果仲裁失败,当前位会被清零(0: 从机        1: 主机)

bit 6: I2C 中断使能(0: 禁用        1: 使能)

bit 7: I2C 使能(0: 禁用        1: 使能)

// 一开始不会初始化所有的位,一些位只有在实际使用才会被设置
寄存器: I2C1_I2CR
基地址: 0x21A0008 
相关操作:
    /* 
     * 发送开始信号(抢占总线,让自己成为主机)
     * bit 4: 1 发送
     * bit 5: 1 主机
     */
    I2C1_I2CR |= ((1 << 4) | (1 << 5));
    
    /* 
     * 发送重复开始信号(总线已经被占用,而且必须是当前设备占用总线,才能发送重复开始信号)
     * bit 2: 1 产生一次重复开始信号
     * bit 4: 1 发送
     */
    I2C1_I2CR |= ((1 << 2) | (1 << 4));

    /* 
     * 产生一个停止信号 
     * bit 3: 0 产生一个ACK
     * bit 4: 0 接收(要产生一个ACK,当前设备必须为接收模式)
     * bit 5: 0 从机
     */
    I2C1_I2CR &= ~((1 << 3) | (1 << 4) | (1 << 5));

3.5  I2C1_I2SR(保存通信状态)

bit 0: 收到了ACK/NACK(0: 收到的是ACK        1: 收到的是NACK)

bit 1: 是否有I2C中断挂起。下面是触发中断的三种情况(0: 无中断挂起        1: 有中断挂起)

  • 一个字节的数据传输完成
  • 从机接收的模式下,与主机发送的地址匹配
  • 仲裁失败,丢失总线占用权

bit 2: 当前通信方向(0: 从机接收,主机发送        1: 从机发送,主机接收)

bit 4: 仲裁是否失败。和上面I2CR 的 bit 5 不一样,这里就是纯粹的获取仲裁结果。

以下三种情况会被判为仲裁失败,该位的状态由硬件控制,软件不可设置(0: 仲裁没有失败        1: 仲裁失败,丢失主线控制权)

  • 总线被占用时,发送开始信号
  • 当前设备为从机,请求重复启动
  • 主机没有发送停止信号,但是却检测到了停止信号

bit 5: I2C 总线是否空闲(0: 总线空闲        1: 总线被占用)

bit 6: 当前设备是否为从机。如果当前设备是从机,需要根据 I2SR 的 bit 2 获取当前的通信方向,并设置 I2CR 寄存器的对应位,即bit 4(0: 当前设备没有被定位        1: 当前设备被指定为从机)

bit 7: 当前数据传输状态。其实就是判断 DR寄存器是否可以用于下一次传输。(0: 数据传输中        1: 传输完成,当时钟的第9个周期的下降沿出现时,才会被置 1)

注意:每一次的传输数据,无论是发送还是接收,在使用 DR 寄存器之前,需要先等待 DR 寄存器可用,类似于一种初始化操作。

  • bit 1:数据是否传递完毕
  • bit 7:DR 寄存器是否可以被用于下一次传输
寄存器: I2C1_I2SR
基地址: 0x21A000C 

3.6  I2C1_I2DR(地址 / 数据传输)

如果当前设备是接收方,该寄存器保存的是接收到的数据;如果当前设备是发送方,该寄存器保存的是要被发送的数据。

寄存器: I2C1_I2DR
基地址: 0x21A0010

四、 AP3216C 解析

AP3216C 是一个三合一的集成模块,集成了 ALS(光传感器)、PS(接近传感器)、IR(红外LED),兼容I2C 接口。

AP3216C 参考手册给出了系统寄存器以及ALS、PS、IR各个模块的详细寄存器配置,系统配置主要是要启用哪些模块,以及不同模块获取到的数据;如果要对某个模块的细微调整,那就要查看各个模块的详细寄存器配置了。

1、功能选择(0x00 — bit2:0)

System Configure 寄存器占一个字节,地址为 0x00

其中bit 2:0 可以控制三个模块的开启与关闭

2、IR + PS

IR一般和PS搭配使用,IR 数据占 10 bit,PS 数据也是占 10 bit。

① IR Data:保存的是当前环境下的红外光强度。0x0A 和 0x0B 所在寄存器大小为一个字节

 ② PS Data:保存物体当前的位置。0x0E 和 0x0F 所在寄存器大小为一个字节

3、ALS

ALS 数据占 16 bit,保存的是环境光强度。0x0C 和 0x0D 所在寄存器大小为一个字节

猜你喜欢

转载自blog.csdn.net/challenglistic/article/details/131510850
今日推荐