49
第 9 第 I2C 第第第第 何何 2011.12

第 9 章 I2C 总线模块

Embed Size (px)

DESCRIPTION

第 9 章 I2C 总线模块. 何宾 2011.12. 本章内容. 本章主要是介绍 PSoC3 内的 I2C 总线模块,其内容主要 包括: I2C 总线模块概述、 I2C 总线实现原理、 I2C 总线寄存 器及操作、 I2C 总线操作模式和 I2C 模块通信的实现。 I2C 总线模块是 PSoC3 所提供的一个重要功能单元,通 过本章内容的学习,不仅能了解和掌握 I2C 总线模块的工作 原理,还能掌握使用 PSoC3 实现 I2C 总线模块通信的方法。. I2C 总线模块 --I2C 总线模块概述. - PowerPoint PPT Presentation

Citation preview

Page 1: 第 9 章  I2C 总线模块

第 9 章 I2C 总线模块

何宾 2011.12

Page 2: 第 9 章  I2C 总线模块

本章内容

本章主要是介绍 PSoC3 内的 I2C 总线模块,其内容主要包括: I2C 总线模块概述、 I2C 总线实现原理、 I2C 总线寄

存器及操作、 I2C 总线操作模式和 I2C 模块通信的实现。 I2C 总线模块是 PSoC3 所提供的一个重要功能单元,通过本章内容的学习,不仅能了解和掌握 I2C 总线模块的工作原理,还能掌握使用 PSoC3 实现 I2C 总线模块通信的方法。

Page 3: 第 9 章  I2C 总线模块

I2C 总线模块--I2C 总线模块概述

I2C 外设提供了同步两线接口用来与 PSoC 设备进行连接, I2C 总线与 Philip 的 I2C 规范 V2.1 版本兼容。额外的I2C 接口能通过使用 UDB 进行例化。

图 I2C 总线模块图

Page 4: 第 9 章  I2C 总线模块

I2C 总线模块--I2C 总线模块概述

典型的 I2C 总线结构

当在单板上有多个设备或者小的系统构成一个网络时,系统能被设计使用一个单主设备和多个从设备,多个主设备,或者多个主和从设备的连接。

Page 5: 第 9 章  I2C 总线模块

I2C 总线模块--I2C 总线模块概述

为了减少 CPU 对 I2C 总线操作的干预, I2C 外设提供了特定支持。这个特定支持用于状态检测和帧比特位的生成。 I2C 操作模式有从模式,单主模式或多主模式。

从模式下,总是监听开始条件,用于开始发送或接收数据。 在主模式下,产生开始和停止条件,并初始化交易。多主模 式提供时钟同步和仲裁允许总线上有多个主设备存在。如果 使用主模式,不能使用从模式,模块不产生中断。

I2C 接口通过 DSI 布线允许直接连接到任意的 GPIO 或者 SIO 引脚。

Page 6: 第 9 章  I2C 总线模块

I2C 总线模块--I2C 总线模块概述

I2C 提供了检测 7 位硬件地址的功能,而不需要 CPU 的干预。当 I2C 的 7 位地址匹配时,能从休眠模式中唤醒 PSoC。如果要求唤醒模式,那么 I2C 连接被限制在两个特殊的SIO 引脚上。

Page 7: 第 9 章  I2C 总线模块

I2C 总线模块--I2C 总线模块概述

PSoC 的 I2C 接口主要特性包含: 主和从,发送器和接收器操作; 用于低 CPU开销的字节处理; 中断或者轮询 CPU接口; 支持总线速度最高为 1Mbps( 3.4Mbps在 UDB内); 7 或 10位寻址( 10位寻址要求固件支持); 支持系统管理总线( System Management Bus,SMBus)操作(通过固件支持 -UDB内支持 SMBus,这种总线基于I2C总线);

7 位硬件地址比较; 地址匹配从低功耗模式唤醒。

Page 8: 第 9 章  I2C 总线模块

I2C 总线模块--I2C 总线实现原理

I2C 总线由 Philips 半导体公司(现在为 NXP )所提供的

一种简单的方法,允许多个设备在一个总线上直接的互相通信。 I2C 总线特点包括:

只使用两根线: ( 1 )串行数据( SDA); ( 2 )串行时钟( SCL);

串行的 8 位数据传输,标准模式下最大速度为 100kbps;快速模式下最大速度 400kbps;快速加模式下最大速度 1Mbps;高速模式下最大速度 3.4Mbps。

Page 9: 第 9 章  I2C 总线模块

I2C 总线模块--I2C 总线实现原理

使用集电极开路或者开漏级,通过上拉电阻将设备连接到总线上(线“与”功能)。

每个连接到总线的设备有独一无二的地址。 存在简单的主 / 从关系; 支持多主模式,当两个设备同时初始化数据传输时,使用冲突检测和仲裁。

Page 10: 第 9 章  I2C 总线模块

I2C 总线模块--I2C 总线实现原理

如下图所示,给出了一个典型的 I2C 总线的传输过程。该过程主要包含以下几步:

I2C 总线传输

Page 11: 第 9 章  I2C 总线模块

I2C 总线模块--I2C 总线实现原理

1. 主设备控制 SCL 线,产生一个开始( Start )条件,后面跟着数据字节。数据字节包含 7 个从设备地址和一个读 / 写( RW )位。该位设置相对于主设备的数据传输方向。高为读,低为写。 2 .从设备识别它的地址,并且在第 9 位的时间间隔内,通过将数据线拉低产生应答 (ACK) 字节。如果从设备没有用 ACK 响应第 1 个字节,主设备产生停止( Stop )条件来终止数据的传输。一个重复的启动条件将用于重新的尝试传输;

Page 12: 第 9 章  I2C 总线模块

I2C 总线模块--I2C 总线实现原理

3 .主设备发送或接收(取决 RW )中间的字节。 4 .当数据传输结束时,主设备产生停止条件。 当接收设备需要时间将接收的数据存储或者准备要发送的数据时,从设备可以将 SCL 线拉低,这样就使得主设备进入等待状态。注意有些主设备不支持这种等待方式。

Page 13: 第 9 章  I2C 总线模块

I2C 总线模块--I2C 总线寄存器及操作

I2C寄存器及功能

寄存器 功能I2C_CFG 配置 - 基本的操作模式,过采样率和中断选择I2C_XCFG 配置 - 配置扩展特性I2C_CLK_DIV1I2C_CLK_DIV2

时钟分频 - 设置波特率

I2C_CSR 控制 / 状态 - 用来控制数据字节流,和在传输过程中跟踪总线状态I2C_MCSR 主模式控制 / 状态 - 实现 I2C 组帧控制和提供总线状态I2C_ADR 从设备地址 - 用于硬件识别从设备地址,保持 7 位从设备地址I2C_D 数据 - 提供对数据移位寄存器的读 / 写访问

Page 14: 第 9 章  I2C 总线模块

I2C 总线模块--I2C 总线寄存器及操作

I2C 总线接口的操作步骤包括:1 )设置 I2C_XCFG的第 7 位,打开 I2C接口;2 )按照下表,布线 SDA和 SCL到期望的引脚对;

3 )按照下表,设置寄存器 I2C_CFG的第 2 位和I2C_CLK_DIV1和 I2C_CLK_DIV2寄存器;

4 )使能期望的操作模式。 注:所使用的端口引脚必须配置成“开漏,驱动低”模式(模式 4 )。 SIO引脚更适合这种应用,这是因为 SIO引脚

有高电流吸收能力和过电压容限。

引脚对 端口引脚 寄存器设置I2C0 P12[4,5] I2C_XCFG[6]=1 , I2C_XCFG[7]=0

I2C1 P12[0,1] I2C_XCFG[6]=1 , I2C_XCFG[7]=1

任何其他 GPIO/SIO对

可选择 I2C_XCFG[6]=0 ,根据选择的引脚对设置其它DSI 和 GPIO 寄存器

Page 15: 第 9 章  I2C 总线模块

I2C 总线模块--I2C 总线寄存器及操作

波特率的设置

波特率 = 总线时钟频率 / (时钟分频因子 * 过采样率)

Page 16: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式

I2C 元件支持 I2C 从,主,多主和多主 / 从配置模式,

下面将介绍这些操作模式。 当元件配置为多主 / 从配置时,在从和多主直接的切换是自动完成的。 通常,设备在从模式,直到一个主 API 函数调用产

生开始序列。硬件然后又处于从模式,直到产生停止序列为止,即此时转为主模式,随后又进入从模式状态。

Page 17: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式

由于 I2C 硬件被中断所驱动,因此要求使能全局中断。即使这个元件要求中断,设计者不需要添加任何代码到中断服务程序中( ISR )。模块独立于代码而服务所有的中断。 为这个接口 ( 在应用程序和 I2C 主设备之间 ) 分配的存储器缓冲区是非常简单的双口存储器。

Page 18: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式

I2C 接口可以产生中断的三个条件包括: 1 .字节传输完毕; 2 .检测到 I2C 总线开始和停止条件; 3 .检测到 I2C 总线错误;

Page 19: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式(从模式)

从操作接口有存储器内的两个缓冲区构成。下图给出了从缓冲区的结构。

从缓冲区的结构

Page 20: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式(从模式)

一个是用于数据从主设备写道从设备,另一个是保留着被主设备读取的数据。注意这里的读写是从 I2C

主设备的角度定义的。 I2C 从设备的读和写缓冲区通过

下面的命令设置:

void I2C_SlaveInitReadBuf(uint8 * rdBuf, uint8 bufSize) ; void I2C_SlaveInitWriteBuf(uint8 * wrBuf, uint8 bufSize) ;

Page 21: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式(从模式)

这些命令不分配存储器,只是复制数组指针和大小到内部的元件变量。由于元件不能自动地生成缓冲区,所以用于缓冲区的数组必须被程序初始化。可以使用相同的缓冲区用于读写缓冲区,但是必须正确的管理数据。

Page 22: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式(从模式)

上面函数的 bufSize小于或者等于实际的数组大小,但不能大于指向 rdBuf 或者 wrBuf 的可用的存储空间。 任何时候,传输的字节可以通过调用I2C_SlaveGetReadBufSize 或者

I2C_SlaveGetWrite BufSize函数得到。 读写超过缓冲区大小将引起溢出错误。错误将在从状态字节中进行设置,可以调用 I2C_SlaveStatus 得到。

Page 23: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式(从模式)

复位指针到数组的开始,可以调用下面的命令: void I2C_SlaveClearReadBuf(void) void I2C_SlaveClearWriteBuf(void)

I2C 多次的读或者写缓冲区,将增加数组的索引值,直到使用清除命令。

下图给出了执行两个写交易后的情况。

Page 24: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式(从模式)

两次写交易后的情况

Page 25: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式(从模式)

当第二次交易的 6 个字节写完后,从设备给出NAK

信号,表示到达缓冲区的结尾。如果主机继续写,则后续交易被放弃,产生 NAK 信号。 读或写缓冲区有四个状态位来描述信号传输的完成,传输正在进行,缓冲区溢出,传输错误。当传输开始时,设置忙标志。当结束时,设置传输完成标志,同时清除忙标志。

Page 26: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式(从模式)

下面给出这种操作模式下的一段代码: uint8 wrBuf[10]; uint8 userArray[10]; uint8 byteCnt; I2C_SlaveInitWriteBuf((uint8 *) wrBuf, 10); /* Wait for I2C master to complete a write */ for(;1;) /* loop forever */ { /* Wait for I2C master to complete a write */ if(I2C_SlaveStatus( ) & I2C_SSTAT_RD_CMPT ) { byteCnt = I2C_SlaveGetWriteBufSize( ); I2C_SlaveClearReadStatus( ); For(i=0; I < byteCnt; i++) { userArray[i] = wrBuf[i]; /* Transfer data */ } I2C_SlaveClearWriteBuf( ); } }

Page 27: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式(主 /多主操作模式 )

主和多主操作是类似的,但有两点例外。 1 )当操作在多主模式下,总线总是检查是否处于忙状态,因为其它主设备可能正在和其它从设备通信。在这种情况下,程序必须等待直到当前的操作完成,下一个开始交易启动以前。 2 )当操作在多主模式下,可以在同一时刻两个主设备同时启动。如果这种情况发生的话,两个主设备中的一个将要放开仲裁权。每个字节传输后,必须检查该条件。元件将自动检查这个条件,如果丢失仲裁权,则响应这个错误。

Page 28: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式(主 /多主操作模式 )

当工作在 I2C 主设备模式下,有两个操作选项:manual 和 automatic 。在 Automatic 模式,创建一个缓冲区

来保持整个传输,在写操作下,缓冲区将重新用将要发送的数据进行填充。如果数据从从设备中读出,分配需要最小包大小的缓冲。 在自动模式下,写一个数组字节到从设备,使用下面的函数: uint8 I2C_MasterWriteBuf (uint8 SlaveAddr, uint8 * wrData, uint8 cnt,

uint8 mode)

其中: SlaveAddr 是从设备 7 位的地址变量,范围 0-127 。

Page 29: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式(主 /多主操作模式 )

在自动模式下,从从设备读一个数组的字节,使用下面的函数:

uint8 I2C_MasterReadBuf (uint8 SlaveAddr, uint8 * wrData, uint8 cnt, uint8 mode)

这两个函数均返回状态值。

Page 30: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式(主 /多主操作模式 )

下面给出了写从设备的一段代码: I2C_MasterClearWriteStatus(); /* Clear any previous status */

I2C_MasterWriteBuf(4, (uint8 *) wrData, 10, I2C_MODE_COMPLETE_XFER);

For(;1;) { if(I2C_MasterClearWriteStatus() &

I2C_MSTAT_CMPLT ) /* Transfer complete */ break; }

Page 31: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式(主 /多主操作模式 ) 元件也可以工作在手工模式下,在这种模式下使用各自的命令完成写操作的每一部分。下面给出了在手工模式下写从设备的代码:

I2C_MasterClearWriteStatus(); status = I2C_MasterSendStart(4, I2C_WRITE_XFER_MODE); if(status == I2C_MSTAT_CMPLT) /* Check if transfer completed

without errors */ { /* Send array of 5 bytes */ for(i=0; i<5; i++) { status = I2C_MasterWriteByte(userArray[i]); if(status != I2C_MSTAT_CMPLT) { break; } } } I2C_MasterSendStop(); /* Send Stop */

Page 32: 第 9 章  I2C 总线模块

I2C 总线模块-- I2C 总线操作模式(主 /多主操作模式 ) 手工读操作和写操作是类似的,除了最后一个字节需要被 NAK 。下面给出了手工模式下的读从设备的操作。

I2C_MasterClearWriteStatus(); status = I2C_MasterSendStart(4, I2C_READ_XFER_MODE); if(status == I2C_MSTAT_CMPLT) /* Check if transfer completed

without errors */ { /* Read array of 5 bytes */ for(i=0; i<5; i++) { status = I2C_MasterWriteByte(userArray[i]); if(i < 4) { userArray[i] =

I2C_MasterReadByte(I2C_ACK_DATA); } else { userArray[i] = I2C_MasterReadByte(I2C_NAK_DATA);} } } I2C_MasterSendStop(); /* Send Stop */

Page 33: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 系统实现原理

该设计使用固定功能的 I2C 主模块和 UDB 实现的I2C

从模块。引出 I2C 主设备的 SDA 和 SCL 线,通过外部的连

接将其连接到 I2C 从模块引脚。 当按下外部按键时, I2C 主模块给 I2C 从模块发送数

据。当按下另一个外部按键时, I2C 主模块从从从设备读回数据。表 9.4 给出了该设计使用的 IP核资源及其功能。

Page 34: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 系统实现原理

例化名字 元件名字 元件范围 描述I2C_M I2C Master(Fixed Function) Communications 固定功能的 I2C 主模块I2C_S I2C Slave(UDB) Communications 通用数字块 I2C 从模块Pin_SDA_M Digital Bidirectional Pin Ports and Pins I2C 主模块数据引脚Pin_SDA_S Digital Bidirectional Pin Ports and Pins I2C 从模块数据引脚Pin_SCL_M Digital Bidirectional Pin Ports and Pins I2C 主模块时钟引脚Pin_SCL_S Digital Bidirectional Pin Ports and Pins I2C 从模块时钟引脚Pin_WriteSwitch Digital Bidirectional Pin Ports and Pins 数字输入引脚Pin_ReadSwitch Digital Bidirectional Pin Ports and Pins 数字输入引脚clock Clock System 时钟输入LCD Character LCD Display 字符型 LCD

isr_WriteSwitch Interrupt System 中断模块isr_ReadSwitch Interrupt System 中断模块ZeroTerminal_1 Logic Low ’0’ Logic ‘逻辑 0’

Page 35: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 创建和配置工程

1 .在计算机上的桌面上,选择开始 -> 所有程序 ->Cypress->PSoC Creator 2.0->PsoC Creator 2.0 。打

开 PSoC Creator软件; 2 .在 PSoC Creator 2.0软件的主界面下,选择 File->New->Project... ; 3 .在 New Project窗口,选择Empty PSoC3

Design 模板,并将工程命命名为 I2C 。选择工程保存路径,点击“ OK”按钮;

Page 36: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 添加并配置 I2C 主模块

下面给出添加并配置 I2C 主模块的步骤,主要步骤包括: 1 .拖动并且放置 I2C 主模块元件到原理图内(Components Catalog->Communcation-> I2C->I2C Master(Fixed Function)) 。 2 .双击理图内的 I2C 主模块,打开配置窗口,如图9.6 , I2C 主模块的参数配置如下:

Name : I2C_M Mode : Master Data Rate : 100 Implementation: Fixed Function;

Page 37: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 添加并配置 I2C 主模块

图 9.6 I2C 主模块配置界面

3 .点击“OK”按钮,关闭配置界面。

Page 38: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 添加并配置 I2C 从模块

1 .拖动并且放置 I2C 从模块元件到原理图内(Components Catalog->Communcation-> I2C->I2C Slave(UDB) 。 2 .双击理图内的 I2C 从模块,打开配置窗口,如图

9.7, I2C 从模块的参数配置如下:

Name : I2C_S Mode: Slave Slave Address:4 Implementation: UDB Address Decode: Hardware UDB Clock Source: External Clock 其它按照默认参数配置

Page 39: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 添加并配置 I2C 从模块

图 9.7 I2C 从模块配置界面3 .点击“OK”按钮,关闭配置界面。

Page 40: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 添加并配置数字输入引脚

1 .拖动并且放置两个数字输入引脚元件到原理图内(Components Catalog->Port and Pins-> Digital Input

Pin 。 2 .双击 Pin_1 ,打开配置窗口,如图 9.8 , Pin_1 数

字输入引脚参数配置如下:

Name : Pin_WriteSwitch 不选中 HW Connection ;

General标签下: Drive Mode : Resistive Pull Up Initial State : High ( 1 )

Input标签下: Interrupt : Falling Edge

图 9.8 数字输入引脚配置界面

Page 41: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 添加并配置数字输入引脚

3 .双击 Pin_2 ,打开配置窗口, Pin_2 数字输入引脚参数配置和 Pin_1 配置基本一样,只是名字为:

Name : Pin_ReadSwitch

Page 42: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 添加并配置中断控制器

1 .拖动并且放置两个中断控制器元件到原理图内(Components Catalog->System-> Interrupt 。 2 .双击 isr_1 ,打开配置窗口,如图 9.9 , isr_1 中断

控制器参数配置如下:

Name : isr_WriteSwitch InterruptType : DRIVED

3 .双击 isr_2 ,打开配置窗口, isr_2 中断控制器参数配置如下:

Name : isr_ReadSwitch InterruptType : DRIVED

Page 43: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 添加并配置中断控制器

图 9.9 中断控制器配置界面

Page 44: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 添加并配置字符 LCD

下面给出添加并配置 LCD 的步骤,主要步骤包括: 1 .拖动字符 LCD 并将其放置于原理图内 (Component Catalog->Display->Character LCD) 。 2 .双击原理图内的 LCD_Char_1 器件打开配置窗口。 3 .如图 9.10 所示,在 Basic标签内按如下方式进行配置

: Name : LCD ; LCD Custom Character Set : None选中 Include ASCII to Number

Page 45: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 添加并配置字符 LCD

图 9.10 字符 LCD 配置界面

Page 46: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 系统连接

使用连线工具按钮 ,将系统各个元件和引脚进行连接。图 9.11 给出了连接完成后的系统结构图。

Page 47: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 配置引脚

如图 9.12 所示,给出配置管脚的步骤,主要步骤包括:

1 .从 Workspace Explorer窗口,双击I2C.cydwr 。

2 .为Pin_SCL_S 、 Pin_ReadSwitch 、 Pin_WriteSwitch 、

Pin_SCL_M 、 Pin_SDA_S 、 Pin_SDA_M 和LCD_Char_1 分配

引脚;图 9.12 引脚分配界面

Page 48: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 编写软件程序

1. 添加代码到 main.c 函数 2. 添加代码到中断服务程序

Page 49: 第 9 章  I2C 总线模块

I2C 模块通信的实现-- 编程及调试

下面给出对 Cypress 提供的 CY8CKIT-030 开发套件进行编程的步骤,其步骤主要包含: 1 .断开开发板的电源。 2 .外部将 I2C 主设备和从设备的引脚连接; 3 .板上按键和相对应的 I/O 引脚连接。 4 .按照前一个工程所述方法进行编程。 5 .编完程序之后,通过 reset键重启开发板,按下不同 的按键观察 LCD 上显示的信息。 6 .保存并关闭工程。