安德鲁

[笔记].74HC595驱动实验,Veilog版本

0
阅读(3450)

接线映射

To,         Location
	CLOCK_50,   PIN_23
	nRST,       PIN_4
	//
	SER,        PIN_48
	nG,         PIN_47
	RCK,        PIN_46
	SCK,        PIN_45
	nCLR,       PIN_44
	//
	Q[0],       PIN_114
	Q[1],       PIN_116
	Q[2],       PIN_118
	Q[3],       PIN_128
	Q[4],       PIN_134
	Q[5],       PIN_137
	Q[6],       PIN_139
	Q[7],       PIN_142
	//
	//
	VCC,        V3_3DC
	GND,        GND

74HC595之内部框图


74HC595之时序图


驱动思路


测试源代码

顶层模块

module _74hc595_test
	(
	    // 全局时钟及复位信号
	    input CLOCK_50,
	    input nRST,
	    // 74HC595接口
	    output wire SER,
	    output wire nG,
	    output wire RCK,
	    output wire SCK,
	    output wire nCLR,
	    // 将74HC595 QA~QH接至FPGA
	    input [7:0] Q
	);
	 
	function integer log2(input integer n);
	    integer i;
	    for(i=0; 2**i <=n; i=i+1) log2=i+1;
	endfunction
	 
	localparam N_500ns=25;
	reg [log2(N_500ns):1] cnt_500ns;
	always@(posedge CLOCK_50, negedge nRST)
	    if(!nRST) cnt_500ns <= 0;
	    else if(cnt_500ns < N_500ns-1)
	        cnt_500ns <= cnt_500ns + 1'b1;
	    else cnt_500ns <= 0;
	wire tick_500ns = (N_500ns-1 == cnt_500ns) ? 1 : 0;
	 
	reg [3:0] updata_cnt;
	reg [7:0] tx_data;
	reg _74hc595_enable;
	always@(posedge CLOCK_50, negedge nRST)
	    if(!nRST) updata_cnt <= 0;
	    else if(tick_500ns) begin
	        updata_cnt <= updata_cnt + 1'b1;
	        case(updata_cnt)
	            0: begin tx_data <= 8'h1; _74hc595_enable = 1; end
	            2: begin tx_data <= 8'h2; _74hc595_enable = 1; end
	            4: begin tx_data <= 8'h4; _74hc595_enable = 1; end
	            6: begin tx_data <= 8'h8; _74hc595_enable = 1; end
	            8: begin tx_data <= 8'h10; _74hc595_enable = 1; end
	            10: begin tx_data <= 8'h20; _74hc595_enable = 1; end
	            12: begin tx_data <= 8'h40; _74hc595_enable = 1; end
	            14: begin tx_data <= 8'h80; _74hc595_enable = 1; end
	            default : begin tx_data <= 8'h0; _74hc595_enable <= 0; end
	        endcase
	    end
	       
	 
	_74hc595_driver _74hc595_driver_inst(
	    .CLOCK_50(CLOCK_50),
	    .nRST(nRST),
	     
	    ._74hc595_enable(_74hc595_enable),
	    .output_enable(1'b1),
	    .tx_data(tx_data),
	 
	    .SER(SER),
	    .nG(nG),
	    .RCK(RCK),
	    .SCK(SCK),
	    .nCLR(nCLR)
	);
	 
	endmodule

驱动模块

module _74hc595_driver(
	    // 输入时钟及异步复位(上电复位)信号
	    input CLOCK_50,
	    input nRST,
	    // 74HC595控制及数据信号
	    input _74hc595_enable,
	    input output_enable,
	    input [7:0] tx_data,
	    // 74HC595接口
	    output reg SER,
	    output reg nG,
	    output reg RCK,
	    output reg SCK,
	    output reg nCLR
	);
	 
	function integer log2(input integer n);
	    integer i;
	    for(i=1'b0; 2**i <=n; i=i+1) log2=i+1'b1;
	endfunction
	 
	reg [log2(17):1] cnt_20ns;
	always@(posedge CLOCK_50, negedge nRST)
	    if(!nRST)
	        cnt_20ns <= 0;
	    else if(_74hc595_enable) begin
	        if(cnt_20ns < 16) cnt_20ns <= cnt_20ns + 1'b1;
	        else cnt_20ns <= 0;
	    end else cnt_20ns <= 0;
	     
	     
	always@(posedge CLOCK_50, negedge nRST)
	    if(!nRST) begin
	        SER <= 0;
	        nG <= 1;
	        RCK <= 0;
	        SCK <= 0;
	        nCLR <= 0; // 低电平复位
	    end else begin
	        nCLR <= 1; // 解除复位
	         
	        if(output_enable) nG <= 0;
	        else nG <= 1;
	         
	        if(_74hc595_enable) begin
	         
	            // 产生SCK信号
	            case(cnt_20ns)
	                0,2,4,6,8,10,12,14 : SCK <= 0;
	                1,3,5,7,9,11,13,15: SCK <= 1;
	                16 : SCK <= 0;
	                default : ; // 缺省不操作
	            endcase
	             
	            // 产生RCK信号
	            case(cnt_20ns)
	                16: RCK <= 1;
	                default: RCK <= 0;           
	            endcase
	             
	            // 送出串型数据
	            case(cnt_20ns)
	                0,1 : SER <= tx_data[7];
	                2,3 : SER <= tx_data[6];
	                4,5 : SER <= tx_data[5];
	                6,7 : SER <= tx_data[4];
	                8,9 : SER <= tx_data[3];
	                10,11 : SER <= tx_data[2];
	                12,13 : SER <= tx_data[1];
	                14,15 : SER <= tx_data[0];
	                default: SER <= 0;
	            endcase
	        end else begin
	            SCK <= 0;
	            RCK <= 0;
	            SER <= 0;
	        end       
	    end
	 
	endmodule

 

SignalTap硬件仿真