关于I2C的理论知识

I2C(Inter-Integrated Circuit)总线是由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。是微电子通信控制领域广泛采用的一种总线标准。它是同步通信的一种特殊形式,具有接口线少,控制方式简单,器件封装形式小,通信速率较高等优点。I2C 总线支持源任何IC 生产过程(CMOS、双极性)。通过串行数据(SDA)线和串行时钟 (SCL)线在连接到总线的器件间传递信息。每个器件都有一个唯一的地址识别(无论是微控制器——MCU、LCD 驱动器、存储器或键盘接口),而且都可以作为一个发送器或接收器(由器件的功能决定)。LCD 驱动器只能知作为接收器,而存储器则既可以接收又可以发送数据。除了发送器和接收器外道,器件在执行数据传输时也可以被看作是主机或从机。主机是初始化总线的数据传输并产生允许传输的时钟信号的器件。此时,任何被寻址的器件都被认为是从机。

I2C的从模式与主模式的区别是什么?

宏观上来讲,主模式:就是主CPU作为主机,向从机(挂载器件)发送接收数据。
从模式:就是主CPU作为从机,接来收和发送主机(挂载器件)数据。
而主从机的分别其实是一个触发的作用,主机主动触发,从机只能被动响应触发。

一、I2C 基础知识

I2C 总线是由 Philips 公司开发的一种简单、双向二线制同步串行总线。它只需要两根线 SDA 、SCL 即可在连接于总线上的器件之间传送信息,I2C 总线数据传输速率在标准模式下可达 100kbit/s,快速模式下可达 400kbit/s,高速模式下可达 3.4Mbit/s,在超高速模式下可达到 5Mbit/s。

1. I2C 主要特点

(1)简单的双向两线总线(漏极开路模式):

(2)串行数据(SDA)串行时钟(SCL)

(3)带仲裁功能的多主机的总线

(4)总线上的每个设备都具有不同的识别地址

(5)每次数据传输都是由主机发起,且时钟总是由主机提供

2. I2C 硬件框图

(1)I2C 支持带仲裁功能的多设备通信,在一条总线上可以挂载多个 I2C 外设

(2)I2C 两条总线为漏极开路结构,需要外接上拉电阻

 

 

 

3. I2C 数据通讯

3.1 I2C 总线协议

I2C 总线由起始信号、停止信号、应答信号、非应答信号组成,如图 1.4.1 所示:

起始信号:当时钟线 SCL 为高期间,数据线 SDA 由高到低的跳变

停止信号:当时钟线 SCL 为高期间,数据线 SDA 由低到高的跳变

应答信号(ACK):应答位为低电平时,规定为有效应答位,表示接收器已经成功接收该字节;

非应答信号(NACK):应答位为高电平时,规定为非应答位,一般表示接收器接收该字节没有成功

数据有效性:SCL 在高电平期间,SDA 上的数据必须保持稳定,只有在 SCL 为低电平期间,SDA 状态才允许变化。

 

3.2 I2C 总线的操作

对 I2C 总线的操作实际就是主从设备之间的读写操作。大致可分为以下二种操作情况:

1. 主设备往从设备中写数据,如图 1.4.3 所示

2. 主设备从从设备中读数据,如图 1.4.3 所示

4. I2C 时钟同步

由于总线具有线“与”的逻辑功能,当多个节点同时发送时钟信号时,在总线上表现的是统一的时钟信号,只要有一个节点发送的是低电平,总线上表现为低电平,只有当所有节点都发送高电平时,总线才表现为高电平,由此可知总线时钟取决于低电平周期最长的节点时钟。这就是 SCL 的同步原理,如图 4.5 所示

 

 

 

 

5. I2C 仲裁

(1)I2C 仲裁:在多节点的 I2C 通信中,为解决两个或两个以上节点同时向一条总线发送数据形成的冲突,需要进行 I2C 总线仲裁。

(2)仲裁机制:根据总线线“与”逻辑原理,当有一个节点发送低电平时,总线上表现为低电平,而发送高电平的节点将会失去仲裁。

(3)以图 4.6 两个节点为例,DATA1 和 DATA2 分别是节点向总线所发送的数据信号,SDA 为总线上所呈现的数据信号,SCL 是总线上所呈现的时钟信号

起始:DATA 1 和 DATA 2 发送起始信号,DATA 1 和 DATA 2 为高电平,根据总线线“与”功能,总线为高电平,DATA 1、DATA 2 与 总线电平相同,继续发送数据。

第一个时钟周期:DATA1 和 DATA 2 为高电平,总线为高电平,DATA 1、DATA 2 继续发送数据。

第二个时钟周期:DATA1 和 DATA 2 为低电平,总线为低电平,DATA 1、DATA 2 继续发送数据。

第三个时钟周期:DATA1 为高电平,DATA2 为低电平,SDA 总线为低电平,DATA1 继续发送数据,DATA 2 与 SDA 总线电平不同失去仲裁。

 

 

 

二、LPC824 I2C 性能概述

1. 性能概述

(1)支持数据速率 400 Kbit/s 的标准模式和高达 1Mbit/s 的快速模式

(2)独立的主机、从机和监视器功能

(3)硬件中支持多个 I2C 从机地址

(4)支持 SMBus

(5)片上 ROM 提供 I2C 驱动

(6)收发支持 DMA

(7)支持低功耗模式唤醒

2. I2C0 与 I2C1/2/3 异同

 

 

 

3. I2C 时钟框图

I2C 的时钟由 system clock、AHB 时钟控制寄存器、时钟分频寄存器、SCL 主机时间寄存器四部分组成

 

 

 4. I2C 功能框图

 

 

 

三、LPC824 I2C 具体应用操作

LPC824 I2C 具体应用操作可分为 8 种:时钟配置、IO 配置、地址配置、主从机功能配置、主机功能初始化、主机数据传输、主机中断处理、从机功能初始化、从机中断处理。

1. 时钟配置

1.1 I2C 的 AHB 时钟使能

 

 

 1.2 I2C 的时钟分频寄存器

 

 

 1.3 I2C 的时钟 SCL 主机时间寄存器

 

1.4 波特率计算

 

 

 

 

 2. IO 配置2.1 I2C 的管脚分配

2.2 I2C 的管脚配置

3. 地址配置3.1 从机地址寄存器

 

 

 3.2 从机地址限定寄存器

 

 

 4. 主从功能配置

 

 

 5. 其它寄存器一览

 

 

 

 

 6. I2C 主机功能初始化

 

 

 

 7. I2C 主机数据传输

 

 

 8. I2C 主机中断处理

 

9. I2C 从机功能初始化

 

 

 10. I2C 从机中断处理

11. 监测功能

(1)监测功能用于监听 I2C 总线数据传输

(2)操作配置寄存器使能监测功能

(3)读取 MONRXDAT 寄存器,获取 I2C 总线数据传输信息

12. DMA 应用

(1)I2C 被设置为主机或从机模式,都可以使用 DMA 进行数据收发

(2)需要软件来确认地址传输

(3)使用 DMA 模式,需要配置 DMA 控制器相关寄存器

(4)DMA 请求

 

 四、LPC824 I2C 低功耗模式唤醒1. 低功耗模式唤醒

 

Sleep 模式下,任何触发 I2C 中断的信号都可以唤醒芯片。相关配置如下:

 

 

 

 2. 低功耗模式唤醒

 

 Deep_Sleep/Power_down 模式下,只能支持 I2C 从机模式的唤醒(因为 I2C 时钟被关闭)。相关配置如下:

 

 Startlogic1interruptwake-upenableregister

五、LPC824 I2C 主从机通信实验

1. 实验目的:

通过本实验,理解和掌握 I2C 配置和用法。

2. 实验软/硬件环境搭建:

硬件:LPC824Lite-V1.0(评估板)

软件:SDK 从 NXP 官网下载(https://mcuxpresso.nxp.com/en/select);

工程位置:

..\..\..\driver_examples\i2c\interrupt_b2b_transfer\master\mdk\lpc_i2c_interrupt_b2b_transfer_master.uvprojx

..\..\..\driver_examples\i2c\interrupt_b2b_transfer\slave\mdk\lpc_i2c_interrupt_b2b_transfer_master.uvprojx

3. 实验描述:

本实验中以 I2C0 为例,一个板子作为主机,将另一个板子作为从机,主机发送数据给从机,从机接收数据并发送给主机,串口助手上可看到主从的收发数据。

4. 实验结果:

上电之前将两个板子的 SDA 和 SCL 相连,按下复位键,在串口助手上可以看到 master 及 slave 的收发打印信息。5. 软件设计5.1 使能 I2C 时钟

/* Enable clock of i2c0. */

CLOCK_EnableClock(kCLOCK_I2c0);//使能 I2C 时钟

通过 SYSAHBCLKCTRL 寄存器使能 I2C 时钟,具体函数实现如图 5.1 所示

5.2 IO 配置

BOARD_InitPins(); //IO 配置

 

 

 具体函数实现如上图所示:

5.3 master 配置

(1)master 初始化

masterConfig.enableMaster = true; //使能 Master

masterConfig.baudRate_Bps = 100000U; //设置波特率 100K

masterConfig.enableTimeout = false; //不使能 Timeout

I2C_MASTER_CLOCK_FREQUENCY=12000000; //master 时钟

/* Initialize the I2C master peripheral */

I2C_MasterInit(EXAMPLE_I2C_MASTER, &masterConfig, I2C_MASTER_CLOCK_FREQUENCY);//初始化 I2C

 

I2C 的角色为 Master,波特率为 100K,没有 Timeout 功能,I2C_MasterInit 具体函数配置实现如图 5.3.1 所示

(2)创建中断回调函数

/* Create the I2C handle for the non-blocking transfer */

I2C_MasterTransferCreateHandle(EXAMPLE_I2C_MASTER, &g_m_handle, i2c_master_callback,

 

 

 I2C_MasterTransferCreateHandle具体函数实现如图 5.3.2 所示

(3)master 发送一次数据

/* subAddress = 0x01, data = g_master_txBuff - write to slave.

start + slaveaddress(w) + subAddress + length of data buffer + data buffer + stop*/

uint8_t deviceAddress = 0x01U;

masterXfer.slaveAddress = I2C_MASTER_SLAVE_ADDR_7BIT; //从机地址

masterXfer.direction = kI2C_Write; //I2C 写模式

masterXfer.subaddress = (uint32_t)deviceAddress; //子地址

masterXfer.subaddressSize = 1; //子地址大小

masterXfer.data = g_master_txBuff; //发送数据 buff

masterXfer.dataSize = I2C_DATA_LENGTH; //发送数据 buff 大小

masterXfer.flags = kI2C_TransferDefaultFlag; //传输以起始信号开始,以停止信号结束

/* Send master non-blocking data to slave */

reVal = I2C_MasterTransferNonBlocking (EXAMPLE_I2C_MASTER, &g_m_handle, &masterXfer);//发送一次数据

 

 

 

I2C_MasterTransferNonBlocking 具体函数实现如图 5.3.3 所示

5.4 slave 配置

(1)slave 初始化

/* Set up i2c slave */

slaveConfig.enableSlave = true;//使能 slave

slaveConfig.address1.addressDisable = true;//address1 使能

slaveConfig.address2.addressDisable = true;//address2 使能

slaveConfig.address3.addressDisable = true;//address3 使能

/* Change the slave address */

slaveConfig.address0.address = I2C_MASTER_SLAVE_ADDR_7BIT;//设置主机地址

/* Initialize the I2C slave peripheral */

I2C_SlaveInit(EXAMPLE_I2C_SLAVE, &slaveConfig, I2C_SLAVE_CLOCK_FREQUENCY);//初始化 I2C

I2C_SlaveInit 具体函数实现如图 5.4.1 所示

(2)创建中断回调函数

/* Create the I2C handle for the non-blocking transfer */

I2C_SlaveTransferCreateHandle(EXAMPLE_I2C_SLAVE, &g_s_handle, i2c_slave_callback, NULL);//创建中断回调函数

 

I2C_SlaveTransferCreateHandle 具体函数实现如图 5.4.2 所示

(3)接收一次数据

/* Start accepting I2C transfers on the I2C slave peripheral */

reVal = I2C_SlaveTransferNonBlocking(EXAMPLE_I2C_SLAVE, &g_s_handle,

kI2C_SlaveAddressMatchEvent | kI2C_SlaveCompletionEvent);//读一次数据

 

 

 I2C_SlaveTransferCreateHandle 具体函数实现如图 5.4.3 所示

 

 

posted on 2020-04-12 22:34  一郎哥哥  阅读(1674)  评论(0编辑  收藏  举报

导航