您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 销售管理 > 验证成功的iic-verilog-代码
`timescale1ns/1ps//////////////////////////////////////////////////////////////////////////////////Company:kuayuanelectronicandteclonogy//Engineer:xiao;////CreateDate:2012/11/15//DesignName:cycloneIV//ModuleName:iic_top//ProjectName:iic_project//TargetDevice:cycloneIV//Toolversions:Quartus12.0//Dependencies:verilog////Revision:V1.0//RevisionFileCreated////////////////////////////////////////////////////////////////////////////////moduleiic_project(clk,rst_n,bu1,bu2,scl,sda,LED);inputclk;//50MHzinputrst_n;//复位信号,低有效inputbu1,bu2;//按键1、2,(1按下执行写入操作,2按下执行读操作)outputscl;//24C02的时钟端口inoutsda;//24C02的数据端口output[7:0]LED;//数码管显示的数据//按键检测regsw1_r,sw2_r;//键值锁存寄存器,每20ms检测一次键值reg[19:0]cnt_20ms;//20ms计数寄存器always@(posedgeclkornegedgerst_n)if(!rst_n)cnt_20ms=20'd0;elsecnt_20ms=cnt_20ms+1'b1;//不断计数always@(posedgeclkornegedgerst_n)if(!rst_n)beginsw1_r=1'b1;//键值寄存器初始化为高电平;sw2_r=1'b1;endelseif(cnt_20ms==20'hfffff)beginsw1_r=bu1;//按键1值锁存sw2_r=bu2;//按键2值锁存end//分频部分reg[2:0]cnt;//cnt=0:scl上升沿,cnt=1:scl高电平中间,cnt=2:scl下降沿,cnt=3:scl低电平中间reg[8:0]cnt_delay;//500循环计数,产生iic所需要的时钟regscl_r;//时钟脉冲寄存器always@(posedgeclkornegedgerst_n)if(!rst_n)cnt_delay=9'd0;elseif(cnt_delay==9'd499)cnt_delay=9'd0;//周期为20us,即100KHzelsecnt_delay=cnt_delay+1'b1;//时钟计数;always@(posedgeclkornegedgerst_n)beginif(!rst_n)cnt=3'd5;elsebegincase(cnt_delay)9'd124:cnt=3'd1;//cnt=1:scl高电平中间,用于数据采样9'd249:cnt=3'd2;//cnt=2:scl下降沿9'd374:cnt=3'd3;//cnt=3:scl低电平中间,用于数据变化9'd499:cnt=3'd0;//cnt=0:scl上升沿default:cnt=3'd5;endcaseendend`defineSCL_POS(cnt==3'd0)//cnt=0:scl上升沿`defineSCL_HIG(cnt==3'd1)//cnt=1:scl高电平中间,用于数据采样`defineSCL_NEG(cnt==3'd2)//cnt=2:scl下笛?`defineSCL_LOW(cnt==3'd3)//cnt=3:scl偷缙街屑?用于数据变化always@(posedgeclkornegedgerst_n)if(!rst_n)scl_r=1'b0;elseif(cnt==3'd0)scl_r=1'b1;//scl信号上升沿elseif(cnt==3'd2)scl_r=1'b0;//scl信号下降沿assignscl=scl_r;//产生iic所需要的时钟//需要写入24C02的地址和数据`defineDEVICE_READ8'b1010_0001//被寻址器件地址(读操作)`defineDEVICE_WRITE8'b1010_0000//被寻址器件地址(写操作)`defineWRITE_DATA8'b1001_1010//写入EEPROM的数据`defineBYTE_ADDR8'b0000_0011//写入/读出EEPROM的地址寄存器reg[7:0]db_r;//在IIC上传送的数据寄存器reg[7:0]read_data;//读出EEPROM的数据寄存器//读、写时序parameterIDLE=4'd0;parameterSTART1=4'd1;parameterADD1=4'd2;parameterACK1=4'd3;parameterADD2=4'd4;parameterACK2=4'd5;parameterSTART2=4'd6;parameterADD3=4'd7;parameterACK3=4'd8;parameterDATA=4'd9;parameterACK4=4'd10;parameterSTOP1=4'd11;parameterSTOP2=4'd12;reg[3:0]cstate;//状态寄存器regsda_r;//输出数据寄存器regsda_link;//输出数据sda信号inout方向控莆?reg[3:0]num;always@(posedgeclkornegedgerst_n)beginif(!rst_n)begincstate=IDLE;sda_r=1'b1;sda_link=1'b0;num=4'd0;read_data=8'b0000_0000;endelsecase(cstate)IDLE:beginsda_link=1'b1;//数据线sda为inputsda_r=1'b1;if(!sw1_r||!sw2_r)begin//SW1,SW2键有一个被按下db_r=`DEVICE_WRITE;//送器件地址(写操作)cstate=START1;endelsecstate=IDLE;//没有任何键被按下endSTART1:beginif(`SCL_HIG)begin//scl为高电平期间sda_link=1'b1;//数据线sda为outputsda_r=1'b0;//拉低数据线sda,产生起始位信号cstate=ADD1;num=4'd0;//num计数清零endelsecstate=START1;//等待scl高电平中间位置到来endADD1:beginif(`SCL_LOW)beginif(num==4'd8)beginnum=4'd0;//num计数清零sda_r=1'b1;sda_link=1'b0;//sda置为高阻态(input)cstate=ACK1;endelsebegincstate=ADD1;num=num+1'b1;case(num)4'd0:sda_r=db_r[7];4'd1:sda_r=db_r[6];4'd2:sda_r=db_r[5];4'd3:sda_r=db_r[4];4'd4:sda_r=db_r[3];4'd5:sda_r=db_r[2];4'd6:sda_r=db_r[1];4'd7:sda_r=db_r[0];default:;endcase//sda_r=db_r[4'd7-num];//送器件地址,从高位开始endend//elseif(`SCL_POS)db_r={db_r[6:0],1'b0};//器件地址左移1bitelsecstate=ADD1;endACK1:beginif(/*!sda*/`SCL_NEG)begin//注:24C01/02/04/08/16器件可以不考虑应答位cstate=ADD2;//从机响应信号db_r=`BYTE_ADDR;//1地址endelsecstate=ACK1;//等待从机响应endADD2:beginif(`SCL_LOW)beginif(num==4'd8)beginnum=4'd0;//num计数清零sda_r=1'b1;sda_link=1'b0;//sda置为高阻态(input)cstate=ACK2;endelsebeginsda_link=1'b1;//sda作为outputnum=num+1'b1;case(num)4'd0:sda_r=db_r[7];4'd1:sda_r=db_r[6];4'd2:sda_r=db_r[5];4'd3:sda_r=db_r[4];4'd4:sda_r=db_r[3];4'd5:sda_r=db_r[2];4'd6:sda_r=db_r[1];4'd7:sda_r=db_r[0];default:;endcase//sda_r=db_r[4'd7-num];//送EEPROM地址(高bit开始)cstate=ADD2;endend//elseif(`SCL_POS)db_r={db_r[6:0],1'b0};//器件地址左移1bitelsecstate=ADD2;endACK2:beginif(/*!sda*/`SCL_NEG)begin//从机响应信号if(!sw1_r)begincstate=DATA;//写操作db_r=`WRITE_DATA;//写入的数据endelseif(!sw2_r)begindb_r=`DEVICE_READ;//送器件地址(读操作),特定地址读需要执行该步骤以下操作cstate=START2;//读操作endendelsecstate=ACK2;//等待从机响应endSTART2:begin//读操作起始位if(`SCL_LOW)beginsda_link=1'b1;//sda作为outputsda_r=1'b1;//拉高数据线sdacstate=START2;endelseif(`SCL_HIG)begin//scl为高电平中间sda_r=1'b0;//拉低数据线sda,产生起始位信号cstate=ADD3;endelsecstate=START2;endADD3:begin//送读操作地址if(`SCL_LOW)beginif(num==4'd8)beginnum=4'd0;//num计数清零sda_r=1'b1;sda_link=1'b0;//sda置为高阻态(input)cstate=ACK3;endelsebeginnum=num+1'b1;case(num)4'd0:sda_r=db_r[7];4'd1:sda_r=db_r[6];4'd2:sda_r=db_r[5];4'd3:sda_r=db_r[4];4'd4:sda_r=db_r[3];4'd5:sda_r=db_r[2];4'd6:sda_r=db_r[1];4'd7:sda_r=db_r[0];default:;endcase//sda_r=db_r[4'd7-num];//送EEPROM地址(高bit开始)cstate=ADD3;endend//elseif(`SCL_POS)db_r={db_r[6:0],1'b0};//器件地址左移1bitelsecstate=ADD3;endACK3:beginif(/*!sda*/`SCL_NEG)begincstate=DATA;//从机响应信号sda_link=1'b0;en
本文标题:验证成功的iic-verilog-代码
链接地址:https://www.777doc.com/doc-5374238 .html