ImageVerifierCode 换一换
格式:DOCX , 页数:54 ,大小:94.98KB ,
资源ID:3958706      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/3958706.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(模拟I2C协议.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

模拟I2C协议.docx

1、模拟I2C协议模拟I2C协议在现代电子系统中,有为数众多的IC需要相互之间以及与外界的通信。为了简化电路的设计,Philips公司开发了一种用于内部IC控制的简单的双向两线串行总线I2C(Intel-Integrated Circuit bus)。1998年当推出I2C总线协议2.0版本时,I2C协议实际上已经成为一个国际标准。在进行FPGA设计时,经常需要和外围提供I2C接口的芯片通信。例如低功耗的CMOS实时时钟/日历芯片PCF8563、LCD驱动芯片PCF8574、键盘/LED驱动器ZLG7290等都提供I2C接口。因此在FPGA中模拟I2C接口已成为FPGA开发必要的步骤。本章将详细讲

2、解在FPGA芯片中使用VHD/Verilog HDL模拟I2C协议,以及编写TestBench仿真和测试程序的方法。4.1 I2C总线解析下面先对I2C协议中有关数据格式和时序的内容进行介绍,这里没有涉及的地方请参考THE I2C-SPECIFICATION VERSION2.1 JANUARY 2000.4.1.1 I2C总线概述I2C协议作为一个串行总线标准尽管没有并行总线的数据吞吐能力,但是它的以下特点使其有着广泛的应用。 只需要两条总线串行数据线SDA和串行时钟线SCL; 每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主/从节点关系软件设定地址,主节点可以发送数据或接收数据

3、; 是真正的多主总线,当两个或更多主节点同时初始化数据传输时,可以通过冲突检测和仲裁防止数据被破坏; 串行的8位双向数据传输位速率在标准模式下可达100kbit/s,快速模式下可达400kbit/s,高速模式下可达3.4Mbit/s; 片上的滤波器可以滤去总线数据线上的毛刺波,保证数据完整; 连接到相同总线的IC数量只受到总线的最大电容(400pF)限制。总线不仅仅是互连的线,还包含系统通信的所有格式和过程。I2C总线结构上的特点保证了其应用时的简洁,另外其完备的协议避免了所有混乱、数据丢失和妨碍信息的可能性。4.1.2 I2C协议的基本概念I2C总线支持任何IC生产过程(NMOS、CMOS和

4、双极性)。串行数据线SDA和串行时钟线SCL在连接到总线的器件间传递信息。每个器件都有一个唯一的地址作为识别的标志(无论是微控制器、LCD驱动器存储器还是键盘接口),并且都可以发送数据和接收数据。很明显LCD驱动器只需要接收数据,而存储器需要接收和发送数据。图4-1所示的是一个高性能集成电视的例子。PLL芯片TSA5512颜色解码器TDA9160A图像增强器TDA4670视频处理器TDA4685SCLSDA微控制器PCB83C528非失效内存PCF8582E立体声解码器TDA9840HI-FI音频处理器TDA9860文本处理芯片SAA52XX图4-1 高性能集成电视从图4-1可以看到,应用I2

5、C总线是非常方便的。用通俗的话讲I2C总线的硬件设计工作就是连接SDA和SCL两条线,依靠I2C协议完成软件工作。在I2C协议中应理解如下的概念。1. 主/从节点主节点负责初始化总线的数据传输,并产生允许传输的时钟信号。此时任何被寻址的器件都被认为是从节点。当有多个主节点在总线上传输数据时,每个主节点产生自己的时钟信号。挂接到总线上的所有外围器件、外设接口都是总线上的节点。2. 总线上节点的寻址方式在任何时刻总线上只有一个主控器件(主节点)实现总线的控制操作,对总线上的其他节点寻址,可分时实现点-点的数据传送。因此总线上每个节点都有一个固定的节点地址。I2C总线上主节点的地址由软件给定,此地址

6、存放在I2C总线的地址寄存器中。I2C总线上所有的外围器件都有规范的器件地址。器件地址由7位数字组成,它和1位方向位构成了I2C总线器件的寻址字节SLA(Slave address)。器件地址是I2C总线外围接口器件固有的地址编码,器件出厂时就已给定。数据方向位规定了总线上主节点对从节点的数据传送方向。4.1.3 I2C协议的时序要求1.总线上数据传递时序I2C总线上数据传递时序如图4-2所示,具体步骤如下。 首先主节点器件发送一个起始信号。 接下来主节点器件发送从节点地址和读写方式,一共8位。其中从节点地址7位,读写方式1位。 与传输地址一致的从节点器件应答(即ACK)。 开始数据传输,传输

7、数据数量不限。每个字节(八位)后面跟接收数据方的应答位。例如主节点器件读取从节点数据,从节点发送数据,主节点应答;主节点器件写数据到从节点,主节点发送数据,从节点应答。 数据传输结束,主节点器件发送一个终止信号结束整个过程。采用I2C总线后对传送的字节数没有限制,只要求每传送一个字节后对方回应一个应答位。在发送时首先发送的是数据的最高位(MSB,Most Singnificant Bit)。每次传送开始有起始信号,结束时有停止信号。在总线传送完一个字节后,可以通过对时钟线(SCL)的控制使传送暂停。例如当某个外围器件接收N个字节数据后需要一段处理时间以使继续接收以后的字节数据,这时可在应答信号

8、后使SCL变为低电平控制总线暂停。如果主节点要求总线暂停也可使时钟线保持低电平控制总线暂停。2.总线上的时序信号I2C总线为同步传输总线,总线信号完全与时钟同步。I2C总线上与数据传送有关的信号有起始信号S、终止信号P、应答信号A以及位传送信号。下面将对这些信号一一介绍。(1) 起始信号起始信号(Start Condition)如图4-3所示。当时钟线SCL为高电平时,数据线SDA从高电平向低电平变化将形成起始信号,启动I2C总线。(2) 终止信号终止信号(Stop Condition)如图4-3所示。当时钟线SCL为高电平时,数据线SDA从低电平向高电平变化将形成终止信号,停止I2C总线。(

9、3) 应答信号如图4-3所中ACK第9个时钟脉冲对应应答位,相应数据线上低电平时为应答信号,高电平时为非应答信号。(4) 位传送信号在I2C总线启动后或应答信号后的第18个时钟脉冲对应于一个字节的8位数据传送。脉冲高电平期间,数据串行传送;低电平期间为数据准备,允许总线上数据电平变换。4.2 模拟I2C接口程序的基本框架图4-4 模拟I2C接口程序的基本框架1. 程序接口用于和应程序连接的接口,将应用程序的按照I2C协议的方式通过SDA传递给外部器件。包括下列内容: clk_I FPGA外部时钟信号。 rst_I 同步重起信号。 arst_I 异步重起信号。 adr_I 从节点地址。 dat_

10、I 输入数据。 dat_o 输出数据。 we_I 写有效信号。 stb_I 接口有效信号。 cyc_I 有效总线周期输入。 ack_o 应答信号输出。 inta_o 中断信号输出。2. 时钟设置寄存器I2C协议提供了3种速度模式:正常速度模式100kbit/s、快速模式400kbit/s、高速模式3.5Mbit/s。SCL输出的时钟信号频率和速度模式一致。程序内部使用5倍SCL信号作为时钟,而FPGA外部时钟需要经过分频行到程序内部使用的时钟。例如:采用正常速度100kbit/s,FPGA外部时钟为50MHz,则时钟设置寄存器需要设置为(50MHz/5*100kHz=99)。3. 时钟产生模块

11、时钟产生模块产生4倍SCL频率的时钟信号,它为位传输控制模块中所有同步动作提供触发信号。4. 命令寄存器倒序寄存器共8位,它决定是否在总线上产生各种时序信号、是否读/写数据,各位表示的含义如表4-1所示。表4-1 命令寄存器内容位内容描述7STA,产生起始信号6STO,产生终止信号5RD,从节点读取数据4WR,往从节点写数据3ACK,应答信号2:1保留位0IACK,中断应信号5. 状态寄存器状态寄存器用来显示当前总线的状态,例如是否接收到从节点的应答信号、是否忙、是否在传递数据等,具体内容如表4-2所示。表4-2 状态寄存器内容位内容描述7RxACK,获得从节点的应答信号。“1”代表没有获得应

12、答信号,“0”代表获得应答信号6STO,产生终止信号5RD,从从节点读取数据4WR,往从节点写数据3ACK,应答信号2:1保留位0IACK,中断应答信号6. 数据传输寄存器数据传输寄存器用于保存等待传输的数据。当传递从节点地址信息时,前7位保存从节点地址,最后一位保存读写命令;当传递普通数据时,8位保存一个字节数据。数据传输寄存器具体内容如表4-3所示。表4-3 数据传输寄存器内容位内容描述7:1传输的下一个内容0传输地址时是读写位,其他时候是数据7. 数据接收寄存器数据接收寄存器用于保存通过I2C总线接收到的最后一个字节内容,具体内容如表4-4所示。表4-4 数据接收寄存器内容位内容描述7:

13、0接收到的最后一个字节内容8. 字节传输控制模块字节传输控制模块以字节为单位控制I2C总线的数据传输。这个模块按照命令寄存器设置的内容将数据传输寄存器内容传递到I2C总线的接收端,或者从I2C总线发关端接收数据并保存到数据接收寄存器中。9. 位传输控制模块位传输控制模块以痊为单位I2C总线的数据传输和产生各个I2C协议命令(如开始、停止、重复开始等)。字节传输控制模块控制位传输控制模块的各种动作。例如读取一个字节数据,位传输控制模块需要执行8个读的命令。10. 数据移位寄存器数据移位寄存器保存的数据总是和当前的数据传输相关的。例如在进行读操作时,主节点通过移位寄存器依次通过SDA获得来自I2C

14、发送端的数据,完成后数据拷贝到数据接收寄存器中。在写操作时,数据传输寄存器中的数据拷贝到数据移位寄存器中,然后依次通过SDA将数据传输到I2C总线的接收端。4.3 I2C协议的具体实现FPGA设计一般按照从顶向下的模式进行:首先设计芯片功能,规划各个模块功能;然后按照规划实现各个模块。本实例由3个代码文件组成:i2c_master_bit_ctrl.v完成位传输的功能、i2c_master_byte_ctrl.v完成字节传输的功能、i2c_master_top.v完成整个程序的控制功能,并提供给外部程序的接口。在ISE中创建一个项目,然后加入上面3个文件。下面依次介绍3个文件的内容。4.3.1

15、 位传输的实现i2c_master_bit_ctrl.v完成位传输的功能。位传输的功能包括数据按位传输的实现和I2C协议各个命令的实现两部分。如图4-5所示开始和重复开始命令的产生包括5个阶段:idle和A、B、C、D等。读、写一个字节通过8次位操作完成,实现代码如下:includetimescale.vincludei2c_master_defines.v/模块名称及IOmodule i2c_master_bit_ctrl( clk,rst,nReset, clk_cnt,ena,cmd,cmd_ack,busy,al,din,dout, scl_i,scl_o,sel_oen,sda_i,

16、sda_o,sda_oen );图4-5 位传输完成数据的传输和各个命令的实现/输入、输出input clk;input rst;input nReset;input ena; /模块使用信号input15:0 clk_cnt, /时钟分频系数input 3:0 cmd;output cmd_ack; /命令完成应答reg cmd_ack;output busy; /总线忙reg busy;output al; /总线仲裁丢失reg al;input din;output dout;reg dout;/I2C连线input scl_i; /I2C时钟输入output scl_o; /I2C时钟

17、输出output scl_oen; /I2C时钟输出使能reg scl_oen;/ variabl declarationsreg sSCL,sSDA; /同步后的SCL和SDA输入teg dscl_oen; /延迟后的scl_oenreg sda_chk; /检查后的SDA output(Multi-master arbitration)reg clk_en; /时钟产生信号wire slave_wait;reg 15:0 ent; /时钟分频计数器/模块主体/当从节点没有准备好时,下拉SCL来延迟周期/延迟 scl_oenalways (posedge clk) dscl_oen=#1 s

18、cl_oen;assign slave_wait=dscl_oen&!sSCL;/产生时钟使能信号always (posedge clk or negedge nReset) if(nReset) begin cnt =#1 16h0; clk_en=#1 1b1; end else begin cnt =#1 cnt; clk_en=#1 1b0; end else begin cnt =#1 cnt-16h1; clk_en=#1 1b0; end/产生总线状态控制信号reg dSCL,dSDA;reg sta_condition;reg sto_condition;/同步SCL和SDA输

19、入信号,减少不稳定风险always (posedge clk or negedge nReset) if(nReset) begin sSCL=#1 1b1; sSDA=#1 1b1; dSCL=#1 1b1; dSDA=#1 1b1; end else begin sSCL=#1 scl_i; sSDA=#1 sda_i; dSCL=#1 sSCL; dSDA=#1 sSDA; end/SCL处于高时检测到SDA的下降沿,即检测开始状态信号/SCL处于高时检测到SDA的上升沿,即检测停止状态信号always (posedge clk or negedge nReset) if(nReset)

20、 begin sta_condition=#1 1b0; sto_condition=#1 1b0; end else if(rst) begin sta_condition=#1 1b0; sto_condition=#1 1b0; end else begin sta_condition=#1sSDA & dSDA&sSCL; sto_condition=#1 sSDA &dSDA&sSCL; end/产生I2C总线忙信号always(posedge clk or negedge nReset) if(!nReset) busy=#1 1b0; else if(rst) busy=#1 1

21、b0; else busy=#1(sta_conditionbusy)&sto_condition;/产生仲裁丢失信号generate arbitration lost signal/仲裁丢失发生在:/1)主节点驱动SDA处于高,但是I2C总线一直处于低/2)没有请求时却检测到停止状态信号reg cmd_stop,dcmd_stop;always(posedge clk or negedge nReset) if(nReset) begin cmd_stop =#1 1b0; dcmd_stop=#1 1b0; al =#1 1b0; end else if(rst) begin cmd_st

22、op =#1 1b0; dcmd_stop=#1 1b0; al =#1 1b0; end else begin cmd_stop =#1 cmd=12C_CMD_STOP; dcmd_stop=#1 cmd_stop; al =#1(sda_chk & sSDA & sda_oen)(sto_condition & dcmd_stop end/产生数据输出信号,在SCL信号的上升沿保存SDAalways(posedge clk) if(sSCL & dSCL) dout=#1 sSDA;/产生状态机/状态译码parameter16:0idle =17b0_0000_0000_0000_000

23、0;parameter16:0start_a=17b0_0000_0000_0000_0001;parameter16:0start_b=17b0_0000_0000_0000_0010;parameter16:0start_c=17b0_0000_0000_0000_0100;parameter16:0start_d=17b0_0000_0000_0000_1000;parameter16:0start_e=17b0_0000_0000_0001_0000;parameter16:0stop_a=17b0_0000_0000_0010_0000;parameter16:0stop_b=17b

24、0_0000_0000_0100_0000;parameter16:0stop_c=17b0_0000_0000_1000_0000;parameter16:0stop_d=17b0_0000_0001_0000_0000;parameter16:0rd_a =17b0_0000_0010_0000_0000;parameter16:0rd_b =17b0_0000_0100_0000_0000;parameter16:0rd_c =17b0_0000_1000_0000_0000;parameter16:0rd_a =17b0_0001_0000_0000_0000;parameter16:

25、0wr_a =17b0_0010_0000_0000_0000;parameter16:0wr_b =17b0_0100_0000_0000_0000;parameter16:0wr_c =17b0_1000_0000_0000_0000;parameter16:0wr_d =17b1_0000_0000_0000_0000;reg16:0c_state;/状态机always(posedge clk or negedge nReset) if(!nReset) begin c_state=#1 idle; cmd_ack=#1 1b0; scl_oen=#1 1b1; sda_oen=#1 1

26、b1; sda_chk=#1 1b0; end else if(rstal) begin c_state=#1 idle; cmd_ack=#1 1b0; scl_oen=#1 1b1; sda_oen=#1 1b1; sda_chk=#1 1b0; end else begin cmd_ack =#1 1b0; if(clk_en) case(c_state) /idle状态 idle: begin case(cmd) 12C_CMD_START: c_state=#1 start_a;12C_CMD_STOP: c_state=#1 stop_a;12C_CMD_WRITE: c_stat

27、e=#1 wr_a;12C_CMD_READ: c_state=#1 rd_a; default: c_state=#1 idle; endcase scl_oen=#1 scl_oen; /保持SCL在同一状态 sda_oen=#1 sda_oen; /保持SDA在同一状态 sda_chk=#1 1b0; /不检查SDA输出 end /开始状态 start_a: begin c_state=#1 start_b; scl_oen=#1scl_oen; /保持SCL在同一状态 sda_oen=#1 1b1; /保持SDA处于高 sda_chk=#1 1b0; /不检查SDA的输出 end st

28、art_b:begin c_state=#1 start_c; scl_oen=#1 1b1; sda_oen=#1 1b1; sda_chk=#1 1b0; endstart_c:begin c_state=#1 start_d; scl_oen=#1 1b1; sda_oen=#1 1b0; sda_chk=#1 1b0; endstart_d:begin c_state=#1 start_e; scl_oen=#1 1b1; sda_oen=#1 1b0; sda_chk=#1 1b0; endstart_e:begin c_state=#1 idle; cmd_ack=#1 1b1; scl_oen=#1 1b0; sda_oen=#1 1b0; sda_c

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1