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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

基于FPGA的I2C实验Verilog源代码优选.docx

1、基于FPGA的I2C实验Verilog源代码优选timescale 1ns / 1psmodule i2c_drive( clk,rst_n, sw1,sw2, scl,sda, dis_data );input clk; / 50MHzinput rst_n; /复位信号,低有效input sw1,sw2; /按键1、2,(1按下执行写入操作,2按下执行读操作)output scl; / 24C02的时钟端口inout sda; / 24C02的数据端口output 7:0 dis_data; /输出指定单元的数据/-/按键检测reg sw1_r,sw2_r; /键值锁存寄存器,每20ms检

2、测一次键值 reg19:0 cnt_20ms; /20ms计数寄存器always (posedge clk or negedge rst_n) if(!rst_n) cnt_20ms = 20d0; else cnt_20ms = cnt_20ms+1b1; /不断计数always (posedge clk or negedge rst_n) if(!rst_n) begin sw1_r = 1b1; /键值寄存器复位,没有键盘按下时键值都为1 sw2_r = 1b1; end else if(cnt_20ms = 20hfffff) begin sw1_r = sw1; /按键1值锁存 sw

3、2_r = sw2; /按键2值锁存 end/-/分频部分reg2:0 cnt; / cnt=0:scl上升沿,cnt=1:scl高电平中间,cnt=2:scl下降沿,cnt=3:scl低电平中间reg8:0 cnt_delay; /500循环计数,产生iic所需要的时钟reg scl_r; /时钟脉冲寄存器always (posedge clk or negedge rst_n) if(!rst_n) cnt_delay = 9d0; else if(cnt_delay = 9d499) cnt_delay = 9d0; /计数到10us为scl的周期,即100KHz else cnt_de

4、lay = cnt_delay+1b1; /时钟计数always (posedge clk or negedge rst_n) begin if(!rst_n) cnt = 3d5; else begin case (cnt_delay) 9d124: cnt = 3d1; /cnt=1:scl高电平中间,用于数据采样 9d249: cnt = 3d2; /cnt=2:scl下降沿 9d374: cnt = 3d3; /cnt=3:scl低电平中间,用于数据变化 9d499: cnt = 3d0; /cnt=0:scl上升沿 default: cnt = 3d5; endcase endend

5、define SCL_POS (cnt=3d0) /cnt=0:scl上升沿define SCL_HIG (cnt=3d1) /cnt=1:scl高电平中间,用于数据采样define SCL_NEG (cnt=3d2) /cnt=2:scl下降沿define SCL_LOW (cnt=3d3) /cnt=3:scl低电平中间,用于数据变化always (posedge clk or negedge rst_n) if(!rst_n) scl_r = 1b0; else if(cnt=3d0) scl_r = 1b1; /scl信号上升沿 else if(cnt=3d2) scl_r = 1b0

6、; /scl信号下降沿assign scl = scl_r; /产生iic所需要的时钟/-/需要写入24C02的地址和数据 define DEVICE_READ 8b1010_0001 /被寻址器件地址(读操作)define DEVICE_WRITE 8b1010_0000 /被寻址器件地址(写操作)define WRITE_DATA 8b0000_0111 /写入EEPROM的数据define BYTE_ADDR 8b0000_0100 /写入/读出EEPROM的地址寄存器 reg7:0 db_r; /在IIC上传送的数据寄存器reg7:0 read_data; /读出EEPROM的数据寄存

7、器/- /读、写时序parameter IDLE = 4d0;parameter START1 = 4d1;parameter ADD1 = 4d2;parameter ACK1 = 4d3;parameter ADD2 = 4d4;parameter ACK2 = 4d5;parameter START2 = 4d6;parameter ADD3 = 4d7;parameter ACK3 = 4d8;parameter DATA = 4d9;parameter ACK4 = 4d10;parameter STOP1 = 4d11;parameter STOP2 = 4d12; reg3:0

8、cstate; /状态寄存器reg sda_r; /输出数据寄存器reg sda_link; /输出数据sda信号inout方向控制位 reg3:0 num; /always (posedge clk or negedge rst_n) begin if(!rst_n) begin cstate = IDLE; sda_r = 1b1; sda_link = 1b0; num = 4d0; read_data = 8b0000_0000; end else case (cstate) IDLE: begin sda_link = 1b1; /数据线sda为input sda_r = 1b1;

9、if(!sw1_r | !sw2_r) begin /SW1,SW2键有一个被按下 db_r = DEVICE_WRITE; /送器件地址(写操作) cstate = START1; end else cstate = IDLE; /没有任何键被按下 end START1: begin if(SCL_HIG) begin /scl为高电平期间 sda_link = 1b1; /数据线sda为output sda_r = 1b0; /拉低数据线sda,产生起始位信号 cstate = ADD1; num = 4d0; /num计数清零 end else cstate = START1; /等待s

10、cl高电平中间位置到来 end ADD1: begin if(SCL_LOW) begin if(num = 4d8) begin num = 4d0; /num计数清零 sda_r = 1b1; sda_link = 1b0; /sda置为高阻态(input) cstate = ACK1; end else begin cstate = ADD1; num = num+1b1; case (num) 4d0: sda_r = db_r7; 4d1: sda_r = db_r6; 4d2: sda_r = db_r5; 4d3: sda_r = db_r4; 4d4: sda_r = db_r

11、3; 4d5: sda_r = db_r2; 4d6: sda_r = db_r1; 4d7: sda_r = db_r0; default: ; endcase / sda_r = db_r4d7-num; /送器件地址,从高位开始 end end / else if(SCL_POS) db_r = db_r6:0,1b0; /器件地址左移1bit else cstate = ADD1; end ACK1: begin if(/*!sda*/SCL_NEG) begin /注:24C01/02/04/08/16器件可以不考虑应答位 cstate = ADD2; /从机响应信号 db_r =

12、BYTE_ADDR; / 1地址 end else cstate = ACK1; /等待从机响应 end ADD2: begin if(SCL_LOW) begin if(num=4d8) begin num = 4d0; /num计数清零 sda_r = 1b1; sda_link = 1b0; /sda置为高阻态(input) cstate = ACK2; end else begin sda_link = 1b1; /sda作为output num = num+1b1; case (num) 4d0: sda_r = db_r7; 4d1: sda_r = db_r6; 4d2: sda

13、_r = db_r5; 4d3: sda_r = db_r4; 4d4: sda_r = db_r3; 4d5: sda_r = db_r2; 4d6: sda_r = db_r1; 4d7: sda_r = db_r0; default: ; endcase / sda_r = db_r4d7-num; /送EEPROM地址(高bit开始) cstate = ADD2; end end / else if(SCL_POS) db_r = db_r6:0,1b0; /器件地址左移1bit else cstate = ADD2; end ACK2: begin if(/*!sda*/SCL_NE

14、G) begin /从机响应信号 if(!sw1_r) begin cstate = DATA; /写操作 db_r = WRITE_DATA; /写入的数据 end else if(!sw2_r) begin db_r = DEVICE_READ; /送器件地址(读操作),特定地址读需要执行该步骤以下操作 cstate = START2; /读操作 end end else cstate = ACK2; /等待从机响应 end START2: begin /读操作起始位 if(SCL_LOW) begin sda_link = 1b1; /sda作为output sda_r = 1b1; /

15、拉高数据线sda cstate = START2; end else if(SCL_HIG) begin /scl为高电平中间 sda_r = 1b0; /拉低数据线sda,产生起始位信号 cstate = ADD3; end else cstate = START2; end ADD3: begin /送读操作地址 if(SCL_LOW) begin if(num=4d8) begin num = 4d0; /num计数清零 sda_r = 1b1; sda_link = 1b0; /sda置为高阻态(input) cstate = ACK3; end else begin num = nu

16、m+1b1; case (num) 4d0: sda_r = db_r7; 4d1: sda_r = db_r6; 4d2: sda_r = db_r5; 4d3: sda_r = db_r4; 4d4: sda_r = db_r3; 4d5: sda_r = db_r2; 4d6: sda_r = db_r1; 4d7: sda_r = db_r0; default: ; endcase / sda_r = db_r4d7-num; /送EEPROM地址(高bit开始) cstate = ADD3; end end / else if(SCL_POS) db_r = db_r6:0,1b0;

17、 /器件地址左移1bit else cstate = ADD3; end ACK3: begin if(/*!sda*/SCL_NEG) begin cstate = DATA; /从机响应信号 sda_link = 1b0; end else cstate = ACK3; /等待从机响应 end DATA: begin if(!sw2_r) begin /读操作 if(num=4d7) begin cstate = DATA; if(SCL_HIG) begin num = num+1b1; case (num) 4d0: read_data7 = sda; 4d1: read_data6

18、= sda; 4d2: read_data5 = sda; 4d3: read_data4 = sda; 4d4: read_data3 = sda; 4d5: read_data2 = sda; 4d6: read_data1 = sda; 4d7: read_data0 = sda; default: ; endcase / read_data4d7-num = sda; /读数据(高bit开始) end / else if(SCL_NEG) read_data = read_data6:0,read_data7; /数据循环右移 end else if(SCL_LOW) & (num=4

19、d8) begin num = 4d0; /num计数清零 cstate = ACK4; end else cstate = DATA; end else if(!sw1_r) begin /写操作 sda_link = 1b1; if(num=4d7) begin cstate = DATA; if(SCL_LOW) begin sda_link = 1b1; /数据线sda作为output num = num+1b1; case (num) 4d0: sda_r = db_r7; 4d1: sda_r = db_r6; 4d2: sda_r = db_r5; 4d3: sda_r = db

20、_r4; 4d4: sda_r = db_r3; 4d5: sda_r = db_r2; 4d6: sda_r = db_r1; 4d7: sda_r = db_r0; default: ; endcase / sda_r = db_r4d7-num; /写入数据(高bit开始) end / else if(SCL_POS) db_r = db_r6:0,1b0; /写入数据左移1bit end else if(SCL_LOW) & (num=4d8) begin num = 4d0; sda_r = 1b1; sda_link = 1b0; /sda置为高阻态 cstate = ACK4;

21、end else cstate = DATA; end end ACK4: begin if(/*!sda*/SCL_NEG) begin/ sda_r = 1b1; cstate = STOP1; end else cstate = ACK4; end STOP1: begin if(SCL_LOW) begin sda_link = 1b1; sda_r = 1b0; cstate = STOP1; end else if(SCL_HIG) begin sda_r = 1b1; /scl为高时,sda产生上升沿(结束信号) cstate = STOP2; end else cstate = STOP1; end STOP2: begin if(SCL_LOW) sda_r = 1b1; else if(cnt_20ms=20hffff0) cstate = IDLE; else cstate = STOP2; end default: cstate = IDLE; endcaseendassign sda = sda_link ? sda_r:1bz;assign dis_data = read_data;/-endmodule最新文件- 仅供参考-已改成word文本 - 方便更改

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2