目录
一、硬件原理图分析
二、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(初值为 0x10B0)
- IOMUXC_SW_PAD_CTL_PAD_UART4_RX_DATA(初值为 0x10B0)
/*************** 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 |= 2; // 复用为I2C1_SCL
IOMUXC_SW_PAD_CTL_PAD_UART4_TX_DATA = 0x10B0;
/*************** 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 |= 2; // 复用为I2C1_SDA
IOMUXC_SW_PAD_CTL_PAD_UART4_RX_DATA = 0x10B0;
三、I2C 寄存器解析
3.1 时钟配置
早在学习 CCM 配置时钟主频的时候,就已经配置过该寄存器了。 CSCMR1[PERCLK_PODF] 配置为 1 分频时,IPG_CLK_ROOT = PERCLK_CLK_ROOT = 66 MHz。
配置方式参考:IPG_CLK 配置
3.2 I2C1_IADR(设置从机地址)
bit 7- 1 保存了主机要通信的从机地址。
寄存器: 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: 设置通信方向。(0: 接收 1: 发送)
bit 5: 当前设备是主机还是从机。如果有多主机参与总线占用,会发生冲裁,当前设备如果仲裁失败,当前位会被清零(0: 从机 1: 主机)
bit 6: I2C 中断使能(0: 禁用 1: 使能)
bit 7: I2C 使能(0: 禁用 1: 使能)
// 一开始不会初始化所有的位,一些位只有在实际使用才会被设置
寄存器: I2C1_I2CR
基地址: 0x21A0008
3.5 I2C1_I2SR(保存通信状态)
bit 0: 收到了ACK/NACK(0: 收到的是ACK 1: 收到的是NACK)
bit 1: 是否有I2C中断挂起(0: 无中断挂起 1: 有中断挂起)
bit 2: 当前通信方向(0: 从机接收,主机发送 1: 从机发送,主机接收)
bit 4: 冲裁是否失败。以下三种情况会被判为仲裁失败,该位的状态由硬件控制,软件不可设置(0: 冲裁没有失败 1: 仲裁失败,丢失主线控制权)
- 总线被占用时,发送开始信号
- 当前设备为从机,请求重复启动
- 主机没有发送停止信号,但是却检测到了停止信号
bit 5: I2C 总线是否空闲(0: 总线空闲 1: 总线被占用)
bit 6: 当前设备是否为从机。如果当前设备是从机,需要根据 I2SR 的 bit 2 获取当前的通信方向,并设置 I2CR 寄存器的对应位,即bit 4(0: 当前设备没有被定位 1: 当前设备被指定为从机)
bit 7: 当前数据传输状态。(0: 数据传输中 1: 传输完成,当时钟的第9个周期的下降沿出现时,才会被置 1)
寄存器: 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)
2、IR + PS
IR一般和PS搭配使用,IR 数据占 10 bit,PS 数据也是占 10 bit。
① IR Data:保存的是当前环境下的红外光强度
② PS Data:保存物体当前的位置
3、ALS
ALS 数据占 16 bit,保存的是环境光强度