基于FPGA的I2C实验Verilog源代码说明书.docx

上传人:h**** 文档编号:139938 上传时间:2018-07-10 格式:DOCX 页数:39 大小:70.26KB
下载 相关 举报
基于FPGA的I2C实验Verilog源代码说明书.docx_第1页
第1页 / 共39页
基于FPGA的I2C实验Verilog源代码说明书.docx_第2页
第2页 / 共39页
基于FPGA的I2C实验Verilog源代码说明书.docx_第3页
第3页 / 共39页
基于FPGA的I2C实验Verilog源代码说明书.docx_第4页
第4页 / 共39页
基于FPGA的I2C实验Verilog源代码说明书.docx_第5页
第5页 / 共39页
点击查看更多>>
资源描述

1、 1 timescale 1ns / 1ps module i2c_drive( clk,rst_n, sw1,sw2, scl,sda, dis_data ); input clk; / 50MHz input 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 值

3、锁存 sw2_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 所需要的时钟 2 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

4、 为 scl 的周期,即 100KHz else cnt_delay = 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

5、上升沿 default: cnt = 3d5; endcase end end 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) s

6、cl_r = 1b1; /scl 信号上升沿 else if(cnt=3d2) scl_r = 1b0; /scl 信号下降沿 assign scl = scl_r; /产生 iic 所需要的时钟 /- /需要写入 24C02 的地址和数据 3 define DEVICE_READ 8b1010_0001 /被寻址器件地址(读操作) define DEVICE_WRITE 8b1010_0000 /被寻址器件地址(写操作) define WRITE_DATA 8b0000_0111 /写入 EEPROM 的数据 define BYTE_ADDR 8b0000_0100 /写入 /读出 EEPR

7、OM 的地址寄存器 reg7:0 db_r; /在 IIC 上传送的数据寄存器 reg7:0 read_data; /读出 EEPROM 的数据寄存器 /- /读、写时序 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 DA

8、TA = 4d9; parameter ACK4 = 4d10; parameter STOP1 = 4d11; parameter STOP2 = 4d12; reg3:0 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_dat

9、a = 8b0000_0000; end else case (cstate) IDLE: 4 begin sda_link = 1b1; /数据线 sda 为 input sda_r = 1b1; 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

10、为 output sda_r = 1b0; /拉低数据线 sda,产生起始位信号 cstate = ADD1; num = 4d0; /num 计数清零 end else cstate = START1; /等待 scl 高电平中间位置到来 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+1

11、b1; 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; 5 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 cst

12、ate = ADD1; end ACK1: begin if(/*!sda*/SCL_NEG) begin /注: 24C01/02/04/08/16 器件可以不考虑应答位 cstate = ADD2; /从机响应信号 db_r = 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 = ACK

13、2; 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_r = db_r5; 4d3: sda_r = db_r4; 4d4: sda_r = db_r3; 6 4d5: sda_r = db_r2; 4d6: sda_r = db_r1; 4d7: sda_r = db_r0; default: ; endcase / sda_r = db_r4d7-num; /送 EEPROM 地址(高bit 开始)

14、 cstate = ADD2; end end / else if(SCL_POS) db_r = db_r6:0,1b0; /器件地址左移 1bit else cstate = ADD2; end ACK2: begin if(/*!sda*/SCL_NEG) begin /从机响应信号 if(!sw1_r) begin cstate = DATA; /写操作 db_r = WRITE_DATA; /写入的数据 end else if(!sw2_r) begin db_r = DEVICE_READ; /送器件地址(读操作),特定地址读需要执行该步骤以下操作 cstate = START2;

15、 /读操作 end end else cstate = ACK2; /等待从机响应 end START2: begin /读操作起始位 if(SCL_LOW) begin sda_link = 1b1; /sda 作为 output sda_r = 1b1; /拉高数据线 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

16、_LOW) begin if(num=4d8) begin 7 num = 4d0; /num 计数清零 sda_r = 1b1; sda_link = 1b0; /sda 置为高阻态 (input) cstate = ACK3; end else begin 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_r3; 4d5: sda_r = db_r2; 4d6: sda_r = db_r1; 4d7

17、: 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; /器件地址左移 1bit else cstate = ADD3; end ACK3: begin if(/*!sda*/SCL_NEG) begin cstate = DATA; /从机响应信号 sda_link = 1b0; end else cstate = ACK3; /等待从机响应 end DATA: b

18、egin 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 = sda; 4d2: read_data5 = sda; 8 4d3: read_data4 = sda; 4d4: read_data3 = sda; 4d5: read_data2 = sda; 4d6: read_data1 = sda; 4d7: read_data0 = sda; default: ;

19、 endcase / read_data4d7-num = sda; /读数据(高 bit 开始) end / else if(SCL_NEG) read_data = read_data6:0,read_data7; /数据循环右移 end else if(SCL_LOW) /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

20、; /数据线 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_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

21、:0,1b0; / 写入数据左移 1bit end 9 else if(SCL_LOW) sda_r = 1b1; sda_link = 1b0; /sda 置为高阻态 cstate = ACK4; 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 = ST

22、OP1; 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; endcase end assign sda = sda_link ? sda_r:1bz; assign dis_data = read_data; /- endmodule 10

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 学术论文资料库 > 毕业论文

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。