490 likes | 749 Views
第 9 章 I2C 总线模块. 何宾 2011.12. 本章内容. 本章主要是介绍 PSoC3 内的 I2C 总线模块,其内容主要 包括: I2C 总线模块概述、 I2C 总线实现原理、 I2C 总线寄存 器及操作、 I2C 总线操作模式和 I2C 模块通信的实现。 I2C 总线模块是 PSoC3 所提供的一个重要功能单元,通 过本章内容的学习,不仅能了解和掌握 I2C 总线模块的工作 原理,还能掌握使用 PSoC3 实现 I2C 总线模块通信的方法。. I2C 总线模块 --I2C 总线模块概述.
E N D
第9章 I2C总线模块 何宾 2011.12
本章内容 本章主要是介绍PSoC3内的I2C总线模块,其内容主要 包括:I2C总线模块概述、I2C总线实现原理、I2C总线寄存 器及操作、I2C总线操作模式和I2C模块通信的实现。 I2C总线模块是PSoC3所提供的一个重要功能单元,通 过本章内容的学习,不仅能了解和掌握I2C总线模块的工作 原理,还能掌握使用PSoC3实现I2C总线模块通信的方法。
I2C总线模块--I2C总线模块概述 I2C外设提供了同步两线接口用来与PSoC设备进行 连接,I2C总线与Philip的I2C规范V2.1版本兼容。额外的 I2C接口能通过使用UDB进行例化。 图 I2C总线模块图
典型的I2C总线结构 I2C总线模块--I2C总线模块概述 当在单板上有多个设备或者小的系统构成一个网络 时,系统能被设计使用一个单主设备和多个从设备, 多个主设备,或者多个主和从设备的连接。
I2C总线模块--I2C总线模块概述 为了减少CPU对I2C总线操作的干预,I2C外设提供 了特定支持。这个特定支持用于状态检测和帧比特位的 生成。 I2C操作模式有从模式,单主模式或多主模式。 • 从模式下,总是监听开始条件,用于开始发送或接收数据。 • 在主模式下,产生开始和停止条件,并初始化交易。多主模 式提供时钟同步和仲裁允许总线上有多个主设备存在。如果 使用主模式,不能使用从模式,模块不产生中断。 I2C接口通过DSI布线允许直接连接到任意的GPIO或 者SIO引脚。
I2C总线模块--I2C总线模块概述 • I2C提供了检测7位硬件地址的功能,而不需要CPU的 干预。当I2C的7位地址匹配时,能从休眠模式中唤醒PSoC 。如果要求唤醒模式,那么I2C连接被限制在两个特殊的 SIO引脚上。
I2C总线模块--I2C总线模块概述 PSoC的I2C接口主要特性包含: • 主和从,发送器和接收器操作; • 用于低CPU开销的字节处理; • 中断或者轮询CPU接口; • 支持总线速度最高为1Mbps(3.4Mbps在UDB内); • 7或10位寻址(10位寻址要求固件支持); • 支持系统管理总线(System Management Bus,SMBus)操作(通过固件支持-UDB内支持SMBus,这种总线基于I2C总线); • 7位硬件地址比较; • 地址匹配从低功耗模式唤醒。
I2C总线模块--I2C总线实现原理 • I2C总线由Philips半导体公司(现在为NXP)所提供的 一种简单的方法,允许多个设备在一个总线上直接的互相 通信。I2C总线特点包括: • 只使用两根线: • (1)串行数据(SDA); • (2)串行时钟(SCL); • 串行的8位数据传输,标准模式下最大速度为100kbps;快速模式下最大速度400kbps;快速加模式下最大速度1Mbps;高速模式下最大速度3.4Mbps。
I2C总线模块--I2C总线实现原理 • 使用集电极开路或者开漏级,通过上拉电阻将设备连接到总线上(线“与”功能)。 • 每个连接到总线的设备有独一无二的地址。 • 存在简单的主/从关系; • 支持多主模式,当两个设备同时初始化数据传输时,使用冲突检测和仲裁。
I2C总线传输 I2C总线模块--I2C总线实现原理 • 如下图所示,给出了一个典型的I2C总线的传输过 程。该过程主要包含以下几步:
I2C总线模块--I2C总线实现原理 1. 主设备控制SCL线,产生一个开始(Start)条件, 后面跟着数据字节。数据字节包含7个从设备地址和一个 读/写(RW)位。该位设置相对于主设备的数据传输方 向。高为读,低为写。 2.从设备识别它的地址,并且在第9位的时间间隔 内,通过将数据线拉低产生应答(ACK)字节。如果从设备 没有用ACK响应第1个字节,主设备产生停止(Stop)条 件来终止数据的传输。一个重复的启动条件将用于重新 的尝试传输;
I2C总线模块--I2C总线实现原理 3.主设备发送或接收(取决RW)中间的字节。 4.当数据传输结束时,主设备产生停止条件。 当接收设备需要时间将接收的数据存储或者准备要发 送的数据时,从设备可以将SCL线拉低,这样就使得主设 备进入等待状态。注意有些主设备不支持这种等待方式。
I2C总线模块--I2C总线寄存器及操作 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引脚 有高电流吸收能力和过电压容限。
波特率的设置 I2C总线模块--I2C总线寄存器及操作 波特率=总线时钟频率/(时钟分频因子*过采样率)
I2C总线模块-- I2C总线操作模式 I2C元件支持I2C从,主,多主和多主/从配置模式, 下面将介绍这些操作模式。 当元件配置为多主/从配置时,在从和多主直接的切 换是自动完成的。 通常,设备在从模式,直到一个主API函数调用产生 开始序列。硬件然后又处于从模式,直到产生停止序列为 止,即此时转为主模式,随后又进入从模式状态。
I2C总线模块-- I2C总线操作模式 由于I2C硬件被中断所驱动,因此要求使能全局中 断。即使这个元件要求中断,设计者不需要添加任何代 码到中断服务程序中(ISR)。模块独立于代码而服务所 有的中断。 为这个接口(在应用程序和I2C主设备之间)分配的存 储器缓冲区是非常简单的双口存储器。
I2C总线模块-- I2C总线操作模式 • I2C接口可以产生中断的三个条件包括: • 1.字节传输完毕; • 2.检测到I2C总线开始和停止条件; • 3.检测到I2C总线错误;
从缓冲区的结构 I2C总线模块-- I2C总线操作模式(从模式) 从操作接口有存储器内的两个缓冲区构成。下图给 出了从缓冲区的结构。
I2C总线模块-- I2C总线操作模式(从模式) 一个是用于数据从主设备写道从设备,另一个是保 留着被主设备读取的数据。注意这里的读写是从I2C主 设备的角度定义的。I2C从设备的读和写缓冲区通过下 面的命令设置: • void I2C_SlaveInitReadBuf(uint8 * rdBuf, uint8 bufSize) ; • void I2C_SlaveInitWriteBuf(uint8 * wrBuf, uint8 bufSize) ;
I2C总线模块-- I2C总线操作模式(从模式) • 这些命令不分配存储器,只是复制数组指针和大小 到内部的元件变量。由于元件不能自动地生成缓冲区, 所以用于缓冲区的数组必须被程序初始化。可以使用相 同的缓冲区用于读写缓冲区,但是必须正确的管理数 据。
I2C总线模块-- I2C总线操作模式(从模式) 上面函数的bufSize小于或者等于实际的数组大小, 但不能大于指向rdBuf或者wrBuf的可用的存储空间。 任何时候,传输的字节可以通过调用 I2C_SlaveGetReadBufSize或者I2C_SlaveGetWrite BufSize 函数得到。 读写超过缓冲区大小将引起溢出错误。错误将在 从状态字节中进行设置,可以调用I2C_SlaveStatus得 到。
I2C总线模块-- I2C总线操作模式(从模式) • 复位指针到数组的开始,可以调用下面的命令: • void I2C_SlaveClearReadBuf(void) • void I2C_SlaveClearWriteBuf(void) • I2C多次的读或者写缓冲区,将增加数组的索引值,直到使用清除命令。 • 下图给出了执行两个写交易后的情况。
两次写交易后的情况 I2C总线模块-- I2C总线操作模式(从模式)
I2C总线模块-- I2C总线操作模式(从模式) • 当第二次交易的6个字节写完后,从设备给出NAK 信号,表示到达缓冲区的结尾。如果主机继续写,则后 续交易被放弃,产生NAK信号。 • 读或写缓冲区有四个状态位来描述信号传输的完 成,传输正在进行,缓冲区溢出,传输错误。当传输开 始时,设置忙标志。当结束时,设置传输完成标志,同 时清除忙标志。
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( ); • } • }
I2C总线模块-- I2C总线操作模式(主/多主操作模式 ) 主和多主操作是类似的,但有两点例外。 • 1)当操作在多主模式下,总线总是检查是否处于忙状 态,因为其它主设备可能正在和其它从设备通信。在这种 情况下,程序必须等待直到当前的操作完成,下一个开始 交易启动以前。 • 2)当操作在多主模式下,可以在同一时刻两个主设备 同时启动。如果这种情况发生的话,两个主设备中的一个 将要放开仲裁权。每个字节传输后,必须检查该条件。元 件将自动检查这个条件,如果丢失仲裁权,则响应这个错 误。
I2C总线模块-- I2C总线操作模式(主/多主操作模式 ) 当工作在I2C主设备模式下,有两个操作选项: manual和automatic。在Automatic模式,创建一个缓冲区 来保持整个传输,在写操作下,缓冲区将重新用将要发 送的数据进行填充。如果数据从从设备中读出,分配需 要最小包大小的缓冲。 在自动模式下,写一个数组字节到从设备,使用 下面的函数: • uint8 I2C_MasterWriteBuf (uint8 SlaveAddr, uint8 * wrData, uint8 cnt, uint8 mode) 其中:SlaveAddr是从设备7位的地址变量,范围0-127。
I2C总线模块-- I2C总线操作模式(主/多主操作模式 ) 在自动模式下,从从设备读一个数组的字节,使用 下面的函数: • uint8 I2C_MasterReadBuf (uint8 SlaveAddr, uint8 * wrData, uint8 cnt, uint8 mode) 这两个函数均返回状态值。
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; }
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 */
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 */
I2C模块通信的实现--系统实现原理 该设计使用固定功能的I2C主模块和UDB实现的I2C 从模块。引出I2C主设备的SDA和SCL线,通过外部的连 接将其连接到I2C从模块引脚。 当按下外部按键时,I2C主模块给I2C从模块发送数据 。当按下另一个外部按键时,I2C主模块从从从设备读回 数据。表9.4给出了该设计使用的IP核资源及其功能。
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”按钮;
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;
图9.6 I2C主模块配置界面 I2C模块通信的实现--添加并配置I2C主模块 3.点击“OK”按钮,关闭配置界面。
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 • 其它按照默认参数配置
图9.7 I2C从模块配置界面 I2C模块通信的实现--添加并配置I2C从模块 3.点击“OK”按钮,关闭配置界面。
图9.8 数字输入引脚配置界面 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
I2C模块通信的实现--添加并配置数字输入引脚 3.双击Pin_2,打开配置窗口,Pin_2数字输入引脚 参数配置和Pin_1配置基本一样,只是名字为: • Name:Pin_ReadSwitch
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
图9.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
图9.10 字符LCD配置界面 I2C模块通信的实现--添加并配置字符LCD
I2C模块通信的实现--系统连接 使用连线工具按钮 ,将系统各个元件和引脚进 行连接。图9.11给出了连接完成后的系统结构图。
图9.12 引脚分配界面 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分配 引脚;
I2C模块通信的实现--编写软件程序 • 1. 添加代码到main.c函数 • 2. 添加代码到中断服务程序
I2C模块通信的实现--编程及调试 下面给出对Cypress提供的CY8CKIT-030开发套件进行 编程的步骤,其步骤主要包含: 1.断开开发板的电源。 2.外部将I2C主设备和从设备的引脚连接; 3.板上按键和相对应的I/O引脚连接。 4.按照前一个工程所述方法进行编程。 5.编完程序之后,通过reset键重启开发板,按下不同 的按键观察LCD上显示的信息。 6.保存并关闭工程。