十三.I2C使用1——I2C基础和AP3216C的使用
I2C是一种最常用的接口,有很多传感器或IC都提供了I2C接口来和MCU连接。所以I2C是我们必须要掌握的接口。今天这个I2C的实现流程会有些复杂,我们要从I2C的通讯流程、从机设备等几个方面来讲解。
I2C硬件结构
I2C只用来两根线:SCL(Serial Clock Line 串行时钟线)和SDA(Serial Data Line串行数据线),两台设备间通过这两条线连接的时候需要通过上拉电阻和Vdd连接
这样,在空闲的时候,SCL和SDA就会处于高电平。 其余的I2C设备都挂在这两根总线上,通过每台设备的地址,即可完成多台设备间的数据传输。
I2C通讯流程
I2C通讯有两个方向:读时序和写时序。要搞清这两个时序,先要了解几个基本概念
I2C术语
- 发送器: 发送数据到总线的器件
- 接收器: 从总线接收数据的器件
- 主机: 启动数据传送并产生时钟信号的设备
- 从机: 被主机寻址的器件
- 多主机: 同时有多于一个主机尝试控制总线但不破坏传输
- 仲裁: 是一个在有多个主机同时尝试控制总线但只允许其中一个控制总线并使传输不被破坏的过程
- 同步: 两个或多个器件同步时钟信号的过程
起始位
Start信号,主机通过起始位告诉从机,要进行I2C通讯录。Start信号是在时钟高电平的时候SDA一个下降沿的信号
停止位
I2C通讯的停止位,和起始位功能相反,SCL高电平,SDA出现上升沿就是停止位
数据位
I2C在传输数据时要保证在SCL高电平区间,也就是说SCL高电平时SDA的电平必须保持稳定,所以SDA的电平反转只能在SCL低电平时进行。
数据格式
传输的每个字节必须为8位,但是总字节数不受限制。每个字节后必须跟一个响应位。首先开始传输的是数据最高位,即MSB位。如果此时从机正忙于其他功能,如正在中断服务程序,则需要使SCL线保持低电平迫使主机进入等待状态,直到从机准备完成。
响应ACK
数据接收方收到传输的一个字节数据后,需要给出响应,此时处在第九个时钟,发送端释放SDA线控制权,将SDA电平拉高,由接收方控制。若希望继续,则给出“应答(ACK)”信号,即SDA为低电平;反之给出“非应答(NACK)”信号,即SDA为高电平。
I2C写时序
I2C的数据传输一般是由主机发起的,主机(master)发出时钟信号和Start信号,然后每发送8个bit都会跟一个对应从机的ACK信号,下面的图对应的就是写数据的流程(图表上MSB为高地址,LSB为低地址)
- 1.master发出Start信号
- 2~4主机指定从机地址(7bit)和一个读写标志(3),读写标志位为1时表示读操作,0时为写操作;8个bit完成后(4)为对应从机发的ACK响应
- 5重新发送Start信号,告诉从机要进行操作
- 6~7告诉从机要操作都进村起地址,等待从机ACK响应
- 8~9写入到寄存器的数据,等待从机ACK响应
- 10主机发送停止位,停止I2C通讯
I2C读单字节时序
I2C读单字节数据的时候哟阿比写时序稍微复杂些
前面部分都是一样的
- 1~7是主机发Start信号,指定设备地址以及读写位(这里必须是1,因为要写寄存器地址),等待ACK响应后重新发送Start信号,发送要读取到寄存器地址,等待ACK响应。
- 8,master重新发送start信号
- 9~11是主机发送要读取的设备地址及读写位(这次是要读了,读写位为0),等待ACK
- 12是从I2C设备读取1个字节的数据
- 13主机发出NOACK信号,表示读取操作已经完成,不需要从机再发ACK信号
- 14主机发送STOP信号
I2C读写多字节
I2C读取连续操作个字节的方法是一样的,只是在读写数据的部分连续进行多个数据的读写,其他的控制时序和单字节是一样的。
I.MX6UL的I2C使用
I.MX6UL提供了4个I2C外设接口,通过这四个接口可以实现外设的通讯,其特性如下:
- 兼容标准I2C总线
- 多主机模式
- 通过软件编程选择64种串行时钟序列
- 软件选择ACK应答位
- 开始/结束信号生成/检测
- 总线忙检测
I.MX的I2C设备具备两种模式:标准模式和快速模式,标准模式下速率是100Kbit/s,快速模式为400kbit/,也不需要特殊的配置。
IO复用初始化
I.MX6UL的物理接口
前面说过,I.MX6UL提供了4个I2C接口。对应的物理引脚如下
所以在使用时候,我们要选择需要的IO接口,并设置合适的复用和电气性能参数
时钟源
可以从时钟树上看到I2C的时钟源
可以看出来,I2C的时钟可以从66MHz的PERCLK_CLK_ROOT=IPG_CLK_ROOT,也可以从下面的表里看出来可以选用perclk_clk_rook
两个时钟源可以相互独立的使用,但是要注意的是,时钟必须要大于12.8MHz,才能使用400kbit/s的高速模式。
I2C寄存器
I2C的寄存器很少
每组I2C接口一共就5个寄存器,
I2Cx_IADR
有效域只有7位,在Soc工作在从机模式下用来保存从机地址
这个寄存器的值在软复位的时候不会被复位,我们要使用的是master模式,这个寄存器我们不用设置。
I2Cx_IFDR
分频器设置低7位有效,觉得了传输的比特率。我们选用的时钟源是66MHz,选择合适的分频值达到需要对比特率。
这个分频的值不是直接设定的数值,操作手册给了个表,需要按照表里的对应值去设定
比如我们要使用的比特率是100Kbit/s,时钟源是66MHz,IC=(66000000)/100000=660分频,从表格里差一个靠近的640,66000000/640=103.125kbit/s,满足100K的要求。表格里有些分频值是一样的,用那个值都可以。
I2Cx_I2CR
控制寄存器,用来使能I2C和I2C中断使能、指定工作模式
IEN:I2C使能
IIEN:I2C中断使能
MSTA:主从模式选择,1的时候为master,0时是slave模式
MTX:传输方向,1时发送,0时接收
TXAK:发送ACK响应,0时发送ACK信号,1是发送NoACK信号。
RSTA:重新发送Start信号,1时生成一个Start信号。
I2Cx_I2SR
状态寄存器,表述了I2C的通讯状态
ICF 数据传输状态标志,0时表示数据正在传输,1时表示数据传输完成
IAAS 从设备地址,1时表示I2C_IADR里的地址是从设备地址
IBB I2C总线忙标志,0时表示总线空闲
IAL 仲裁丢失标志,1时表示仲裁丢失
SRW 从机读写标志,当I2C作为从机时候使用,用来接收的主机信号是读还是写。0时表明主机要向向从机写数据,1时表示主机要向从机读数据。
IIF I2C中断挂起标志,1时表示有中断挂起,需要软件写0清除。
RXAK 应答标志,为0的时候表示收到了ACK响应,1时表示收到NoACK响应
I2Cx_I2DR
数据寄存器,低8位有效,当要发送数据时把要发送到数据写入该寄存器,如果接收数据时只需读取寄存器值即可。
AP3216使用
这次的I2C通讯实操我们是用了个AP3216C的IC作为从机和I.MX6UL进行数据交互。IC具有光强度(ALS)、接近距离(PS)和红外线强度(IR)三个参数检测功能。3216的内部框图和外围的电路放在下面
可以看出来,IC的SDA和SCL引脚和MCU(也就是我们的I.MX6UL)的SDA和SCL连接,我们只需要设置好寄存器值就可以使用
使用流程如下
0x00寄存器设置为0x04,进行软复位一次
0x00设置为0x03,使能ALS+PS+IR
读取0x0A~0x0x0F,一共6个寄存器保存了3个传感器的值,如果我们使能了3个传感器,读取寄存器的时候是有时间要求的
主机和从机的实现流程我们在下一章去讲