[笔记].74HC595驱动实验,Veilog版本
0赞
发表于 5/16/2011 12:23:05 PM
阅读(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