正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-23.1,2 讲 I2C驱动

前言:

本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。

引用:

正点原子IMX6U仓库 (GuangzhouXingyi) - Gitee.com

《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.5.2.pdf》

正点原子资料下载中心 — 正点原子资料下载中心 1.0.0 文档

正文:

本文是 “正点原子[第二期]Linux之ARM(MX6U)裸机篇--第23讲 I2C驱动。本节将参考正点原子的视频教程第23讲和配套的正点原子开发指南文档进行学习。

0. 概述

I2C 是最常用的通信接口,众多的传感器都会提供 I2C 接口来和主控相连,比如陀螺仪、加速度计、触摸屏等等。所以 I2C 是做嵌入式开发必须掌握的, I.MX6U 有 4 个 I2C 接口,可以通过这 4 个 I2C 接口来连接一些 I2C 外设。 I.MX6U-ALPHA 使用 I2C1 接口连接了一个距离传感器 AP3216C,本章我们就来学习如何使用 I.MX6U 的 I2C 接口来驱动 AP3216C,读取AP3216C 的传感器数据。

1. I2C简介

I2C是一种很常见的总线协议,I2C是NXP公司设计的,I2C使用的两条线在主控制器和从机之间通信。一条是SCL(串行时钟线),另外一条是SDA(串行数据线),这两条数据线需要接上拉电阻,总线空闲的时候SCL和SDA都处于高电平。I2C总线标准模式下速度可以达到100Kbp/S,款速模式下可以达到400Kb/s。I2C总线工作是按照一定的协议来运行的,接下来就看一下I2C协议。

I2C是支持多从机的,也就是一个I2C控制器下可以挂多个I2C从设备,这些不同的I2C从设备有不同的器件地址,这样I2C主控制器就可以通过i2C设备的器件地址访问指定的I2C设备了,一个I2C总线连接多个I2C从设备如下图所示:

图中SDA和SCL这两根线必须要接一个上拉电阻,一般是4.7K。其它的I2C设备都挂接在SDA和SCL这两根线上,这样就可以通过SDA和SCL这两根线来访问多个I2C设备。

1.1 I2C协议的有关术语

1.1.1 起始位

顾名思义,也就是I2C通信的起始标志,通过这个起始位就可以告诉I2C从机,“我”要开始进行I2C通信了。在SCL为高电平的时候,SDA从高电平变为低电平出现下降沿就表示起始位,如下图所示。

1.1.2 停止位

停止位就是停止I2C通信的标志位,和起始位的功能相反。在SCL为高电平的时候,SDA出现上升沿(从低电平变为高电平)就表示为停止位,如下图所示:

1.1.3 数据传输

I2C总线在数据传输的时候要保证在SCL高电平期间,SDA上的数据稳定,因此SDA上的数据变化只能出现在SCL低电平期间发生,如下图所示:

1.1.4 应答信号

当I2C主机发送完8个数据位之后会将SDA设置为输入状态,等待I2C从机的应答,也就是等到I2C从机高速主句它接收到了数据了。应答信号是由从机发出的,主句需要提供应答信号所需的时钟,主机发送完8位数据以后紧跟着的一个时钟信号就是给应答信号用的。从机通过将SDA拉低表示发出了应答ACK信号,表示通信成功,从机没有拉低SDA表示发送的N-ACK信号,表示通信失败。

产生NACK信号的情况有如下几种:

引用连接,这里讲的很好,将I2C协议的所以细节都讲到了:

你没有真正掌握的I2C总线-2_哔哩哔哩_bilibili你没有真正掌握的I2C总线-2, 视频播放量 13334、弹幕量 162、点赞数 810、投硬币枚数 524、收藏人数 401、转发人数 23, 视频作者 硬件研究狮, 作者简介 【分享硬件技术,技术问题交流】,相关视频:你没有真正掌握的I2C总线-3(完结),你没有真正掌握的I2C总线-1,SPI总线: 你真的懂它 ?,八分钟掌握I2C总线核心知识点-时序图,23届前端开发只能看饮水机了,拿着死工资生活无望啊,复杂主板的硬件设计流程【电脑主板 / 服务器主板】,“受不了学习的累,便要吃生活的苦”8个农村专科生的不惑之年~,【硬件工程师】几种常见调试方法: debug思路分享,离职第一件事:自己交社保,计算机叕叕tm炸了,这怕不是会成为下一个土木,现在转专业还来得及icon-default.png?t=N7T8https://www.bilibili.com/video/BV1PN411Z7WH/

I2C的时钟永远由I2C Master 主机来控制产生

  • I2C主机 Master-Transmit 的时候,主机控制I2C总线的SCL时钟,主机发送8个数据位之后,主机SDA释放,主机发送第九个时钟,从机拉低SDA总线表示ACK(或者从机不拉低SDA表示NACK)
  • I2C主机是Master-Receiver的时候,主机控制I2C总线的SCL时钟,从机在主机的SCL时钟控制下从机发送8个数据位,发送8个数据位之后从机释放SDA总线,主机发出第九个时钟并且主机拉低SDA表示ACK信号回复给从机,或者主机不拉低SDA表示NACK信号回复给从机。

1-无:主机发送了I2C从机的地址,从机地址不存在,在第9个时钟信号时没有从机拉低SDA电平,表示发送了NACK信号。

2-错:主机发送了8位数据之后,从机没有正确处理或者有错误,在第9个时钟信号时没有从机拉低SDA电平,表示发送了NACK信号。

3-停:在主机 Master-Receive模式,主机在接收完最有个DATA数据后发送 NACK 信号从机数据已经接收结束。

4-忙:Slave忙碌,无法开始数据传输

1.5 I2C写时序

主机通过I2C总线与从机之间进行通信不外乎两个操作:写和读,I2C总线单字节写时序如下图所示:

  1. Start起始位
  2. 从机地址(7bit, MSB先发送,了LSB后发送),方向位(1bit ,读1, 写0)
  3. 主机发送8bit数据为之后,从机回复ACK
  4. 主机重发送Start起始位,repeated-start
  5. 主机发送8位寄存器地址
  6. 从机回复ACK
  7. 主机发送8位DATA数据
  8. 从机回复ACK
  9. 主机发送STOP停止位

图 26.1.1.5 就是 I2C 写时序,我们来看一下写时序的具体步骤:
1)、开始信号。
2)、发送 I2C 设备地址,每个 I2C 器件都有一个设备地址,通过发送具体的设备地址来决定访问哪个 I2C 器件。这是一个 8 位的数据,其中高 7 位是设备地址,最后 1 位是读写位,为1 的话表示这是一个读操作,为 0 的话表示这是一个写操作。
3)、 I2C 器件地址后面跟着一个读写位,为 0 表示写操作,为 1 表示读操作。
4)、从机发送的 ACK 应答信号。
5)、重新发送开始信号。
6)、发送要写写入数据的寄存器地址。
7)、从机发送的 ACK 应答信号。
8)、发送要写入寄存器的数据。
9)、从机发送的 ACK 应答信号。
10)、停止信号。

1.6 I2C读时序

I2C总线的单字节读时序如下图所示:

I2C的单字节读时序要比写时序复杂一些,不时序分为4大步:

  • 第一步是发送设备地址
  • 第二步是发送要读取的寄存器地址
  • 第三部是重新发送设备地址
  • 最后一步就是从I2C从器件输出要读取的寄存器值。 

读取的寄存器值,我们具体来看一下这几步

  1. 主机发送起始信号Start
  2. 主机发送知己要读取的I2C从机地址
  3. 读写控制位,因为事项I2C从机发送数据,因此是写信号。
  4. 从机发送ACK应答信号
  5. 重新发送Start起始信号
  6. 主机发送要读取的寄存器地址
  7. 从机发送ACK应答信号
  8. 重新发送START信号
  9. 重新要发送要读取的I2C从机地址
  10. 读写控制位,这里是读信号,表示接下来是从I2C 从设备里读取数据
  11. 从设备发送ACK应答信号
  12. 从I2C器件里读取数据
  13. 主机发出 NO ACK信号,表示读取完成,不需要从机再发送ACK信号了。
  14. 主机发出STOP信号,停止I2C通信。

2. I2C 多字节读写时序

有时候我们需要读写多个字节,多字节读写时序和单字节的基本一致,只是在读写数据的时候可以连续发送多个自己的数据,其它的控制时序都是和单字节是一样的。
 

3. I.MX6U I2C

3.1 I.MX6U I2C 简介

I.MX6U提供了4个I2C外设,通过这4个I2C外设即可以完成与I2C从器件进行通信,I.MX6U的I2C外设特性如下:

  1. 与标准I2C总线兼容
  2. 多主机运行
  3. 软件可以编程的64种不同的串行时钟序列
  4. 软件可选择的应答位
  5. 开始/结束信号生成和检测
  6. 重复开始信号生成
  7. 确认位生成
  8. 总线忙检测

I.MX6U的I2C支持两种工作模式:标准模式和快速模式,标准模式下I2C数据传输速率最高100Kbps,在快速模式下数据传输速率最高为400Kbps。

3.2 I.MX6U I2C 寄存器

我们接下来看一下I2C的几个重要寄存器。

3.2.1 I2Cx_IADR

首先看一下 I2Cx_IADR (x=1~4)寄存器,这是I2C的地址寄存器,此寄存器结构如下图:

I2Cx_IADR 中存放7bit的I2C从机地址,当I2C器件工作在Slave从机模式下时,从机收到主机发送的Slave地址就做出回应(ACK)。本实验我们作为I2C主机不需要设置I2Cx_IAR。

寄存器 I2Cx_IADR 只有 ADR(bit7:1)位有效,用来保存 I2C 从设备地址数据。

当我们(I2C主机)要访问某个 I2C 从设备的时候就需要将其设备地址写入到 I2Cx_ADR 里面。

3.2.2 I2Cx_IFDR

接下来看一下寄存器I2Cx_IFDR,这个是 I2C 的分频寄存器,寄存器结构如图 26.1.2.2 所示:

寄存器 I2Cx_IFDR 也只有 IC(bit5:0)这个位,用来设置 I2C 的波特率, I2C 的时钟源可以选择 IPG_CLK_ROOT=66MHz,通过设置 IC 位既可以得到想要的 I2C 波特率。 IC 位可选的设置如图 26.1.2.3 所示:

不像其他外设的分频设置一样可以随意设置,图 26.1.2.3 中列出了 IC 的所有可选值。比如现在I2C的时钟源为66MHz,我们要设置I2C的波特率为100KHz,那么IC就可以设置为0X15,也就是 640 分频。 66000000/640=103.125KHz≈100KHz。

3.2.3 I2Cx_ICR

寄存器 I2Cx_ICR 的各位定义如下:

描述
IEN bit[7]

I2C使能位,0的时候关闭I2C,1的时候使能I2C,必须在其它I2C控制位设置之前先使能该位。

该位也控制着I2c的软件复位

IIEN bit[6]

I2C中断使能位,

0, I2C中断关闭,但是I2Cx_I2SR[IIF]寄存器的IIF标志还是会在中断条件满足的时候置1,用户需要清除I2Cx_I2SR[IIF]位。

1, I2C中断使能,当I2C中断发生的时候 I2C_I2SR[IIF]位也会被置1。

MSTA bit[5]

Master/Slave mode,主机/从机模式

Note: MSTA标记被软件清除用来产生一个STOP停止位,它也可能会被硬件清除当硬件检测到仲裁丢失的时候。

0: Slave 从机模式

1: Master 主机模式

MTX bit[4]

Transmit/Receive mode select

发送/接收模式选择

0: Receive

当一个从机被寻址到后,软件应该根据从机的I2C_I2SR[SRW]寄存器里的 read/write bit 位来设置MTX

1: Tansmit

在主机模式,MTX应该根据读写类型来设置,所以说对于address cycle 寻址周期,MTX总是1.

TXAK bit[3]

Transmit acknowledge enable ,发送应答使能。控制驱动到 I2Cx_SDA 总线上应答类型,对于主机和从机都一样。

注意: 只有当I2C工作在Receiver模式下时才能写  TXAK 

0: ACK 信号发送,在接收完数据后第9个时钟周期的时候

1: NACK 信号发送

RSTA bit[2]

Repeated Restart,重开始

总是读为0,在没有丢失总线控制权的情况下重发送一个 start (repeated start)

未使用 bit[0]保留未使用

3.2.4 I2Cx_I2SR

I2Cx_I2SR寄存器里指示传输方向和传输状态。

描述
保留 bit[15:8]保留未使用
ICF bit[7]

数据传输指示位,当数据中的任一个字节传输时清零此位

0 数据正在传输

1 数据传输完成, 在最后一个字节传输万完成的第9个时钟的下降沿设置此位。

IAAS bit[6]

I2C设备被作为从机寻址成功

0: 没有被寻址

1: 寻址成功,当I2C自己的I2Cx_IADR寄存其的值和呼叫寻址匹配的时候设置

IBB bit[5]

I2C bus busy,I2C总线忙位

注意:当I2C启用之后,它会不停的轮询SDA和SCL总线信号好探测Start起始位和Stop停止位。

0: 总线空闲 idel , if Stop信号被探测到 ibb位被清零

1: 总线忙 busy,if start信号被探测到 ibb 位被设置

IAL bit[4]

仲裁丢失,被硬件设置(IAL 必须被软件清除通过对此位写0 在中断服务函数中)

I2Cn_SDA 输入采样到低,当主机master驱动一个高电平在寻址或者数据传输周期。

I2Cn_SDA输入采样到低,当主句驱动高电平在主句ACK应答周期。

0: 无仲裁丢失

1: 仲裁丢失

保留 bit[3]
SRW bit[2]
IIF bit[1]

I2C中断,必须被软件清零通过写0

0:没有中断被pending

1:有争端被pending

3.2.5 I2C_I2DR 

最后一个寄存器就是 I2Cx_I2DR,这是 I2C 的数据寄存器,此寄存器只有低 8 位有效,当要发送数据的时候将要发送的数据写入到此寄存器,如果要接收数据的话直接读取此寄存器即可得到接收到的数据。

In Master Receive mode, reading the data register allows a read to occur and initiates the next byte to be received. In Slave mode, the same function is available after it isaddressed.
 

在主机接收模式,读取数据寄存器允许read发生并且指示下一个自己可以别接收。所以读取之前需要“假读”。

4. 硬件原理 

根据正点原子I.MX6U APLHA 开发板的电路原理图,I2C1 使用的引脚如下

正点原子 I.MX6ULL  引脚复用:

引脚复用IO复用ALT
I2C1_SCLUART4_TXD
I2C1_SDAUART4_RXD

4.1. I2C IO 复用寄存器

正点原子 I.MX6ULL ALPHA开发板使用 I2C1 时使用 UART4_TX_DATA 作为 I2C1_SCL , UART4_RX_DATA 作为 I2C1_SDA 。 

对应的寄存器如下

在I.MX6ULL 参考手册里说明,使用I2C需要将IO引脚配置为开漏模式,并且配置IO引脚的 SION 为打开。

5 AP3216C 红外/接近/环境光传感器

AP3216C 简介
I.MX6U-ALPHA 开发板上通过 I2C1 连接了一个三合一环境传感器: AP3216C, AP3216C是由敦南科技推出的一款传感器,其支持环境光强度(ALS)、接近距离(PS)和红外线强度(IR)这三个环境参数检测。该芯片可以通过 IIC 接口与主控制相连,并且支持中断, AP3216C 的特点如下:
①、 I2C 接口,快速模式下波特率可以到 400Kbit/S
②、多种工作模式选择: ALS、 PS+IR、 ALS+PS+IR、 PD 等等。
③、内建温度补偿电路。
④、宽工作温度范围(-30° C ~ +80° C)。
⑤、超小封装, 4.1mm x 2.4mm x 1.35mm
⑥、环境光传感器具有 16 位分辨率。
⑦、接近传感器和红外传感器具有 10 位分辨率。
AP3216C 常被用于手机、平板、导航设备等,其内置的接近传感器可以用于检测是否有物
体接近,比如手机上用来检测耳朵是否接触听筒,如果检测到的话就表示正在打电话,手机就会关闭手机屏幕以省电。也可以使用环境光传感器检测光照强度,可以实现自动背光亮度调节。

AP3216C 结构如图 26.1.3.1 所示:

AP3216 的设备地址为 0X1E,同几乎所有的 I2C 从器件一样, AP3216C 内部也有一些寄存器,通过这些寄存器我们可以配置 AP3216C 的工作模式,并且读取相应的数据。 AP3216C 我们用的寄存器如表 26.1.3.1 所示:


敦南科技AP3216C 红外/环境光/接近传感器的 I2C 写时序1:

敦南科技AP3216C 红外/环境光/接近传感器的 I2C 写时序2:

敦南科技AP3216C 红外/环境光/接近传感器的 I2C 读时序1:

敦南科技AP3216C 红外/环境光/接近传感器的 I2C 读时序2:

AP3216C传感器的重要寄存器

6. 结束

本文至此结束

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值