【数码管】— 静态数码管按键控制大小
上午学了使用2片74HC595芯片控制数码管静态显示
吃午饭时和我对象聊起时,他建议我使用3个按键分别控制数码管:+1、-1、清零
于是吃完午饭回到实验室尝试做了出来,并上板验证成功
设计的框图:

一、设计文件
模块1:按键消抖
注意:之前在检测到按键下降沿后,计时20ms后将按键信号拉高,在上板验证时发现不够稳定
于是将时间延长到50ms
// ---------------------------- // 功能:按键消抖 // 细节:下降沿稳定50ms // ---------------------------- module key_filter ( input wire Clk, input wire Rst_n, input wire key_in, output reg key_flag ); parameter MAX = 22'd2499_999; reg [21:0] Count;//计数器:999_999 always @(posedge Clk or negedge Rst_n)begin if(Rst_n == 1'b0) Count <= 22'd0; else if(key_in == 1'b1) Count <= 22'd0; else if(Count == MAX) Count <= MAX; else Count <= Count + 22'd1; end always @(posedge Clk or negedge Rst_n)begin if(Rst_n == 1'b0) key_flag <= 1'b0; else if(Count == (MAX-22'd1)) key_flag <= 1'b1; else key_flag <= 1'b0; end endmodule
模块2:位选、段选驱动模块
module seg_01 ( input sys_clk, input sys_rst_n, input key_flage_01,//加1按键 input key_flage_02,//减1按键 output reg [5:0]wei, output reg[7:0]duan ); //reg [25:0] cnt_wait ; //时钟分频计数器 reg [3:0] num ; //数码管显示的十六进制数 parameter CNT_WAIT_MAX = 26'd49_999_999; //计数器最大值(1s) parameter SEG_0 = 8'b1100_0000, SEG_1 = 8'b1111_1001, SEG_2 = 8'b1010_0100, SEG_3 = 8'b1011_0000, SEG_4 = 8'b1001_1001, SEG_5 = 8'b1001_0010, SEG_6 = 8'b1000_0010, SEG_7 = 8'b1111_1000, SEG_8 = 8'b1000_0000, SEG_9 = 8'b1001_0000, SEG_A = 8'b1000_1000, SEG_B = 8'b1000_0011, SEG_C = 8'b1100_0110, SEG_D = 8'b1010_0001, SEG_E = 8'b1000_0110, SEG_F = 8'b1000_1110; parameter IDLE = 8'b1111_1111; //不显示状态 // 共阳极数码管,位选需要让6位拉高,段选低电平有效 //wei:选中六个数码管 always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) wei <= 6'b000000; else wei <= 6'b111111; //显示什么 always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) duan <= IDLE; else case(num) 4'd0: duan <= SEG_0; 4'd1: duan <= SEG_1; 4'd2: duan <= SEG_2; 4'd3: duan <= SEG_3; 4'd4: duan <= SEG_4; 4'd5: duan <= SEG_5; 4'd6: duan <= SEG_6; 4'd7: duan <= SEG_7; 4'd8: duan <= SEG_8; 4'd9: duan <= SEG_9; 4'd10: duan <= SEG_A; 4'd11: duan <= SEG_B; 4'd12: duan <= SEG_C; 4'd13: duan <= SEG_D; 4'd14: duan <= SEG_E; 4'd15: duan <= SEG_F; default:duan <= IDLE ; //闲置状态,不显示 endcase //num:从 4'h0 加到 4'hf 循环 always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) num <= 4'd0; else if(key_flage_01 == 1'b1) num <= num + 1'b1; else if(key_flage_02 == 1'b1) num <= num - 1'b1; endmodule
模块3:74HC595芯片
module seg_595 ( input clk , input rst_n , input [5:0] wei , input [7:0] duan , output reg ds , output reg shcp , output reg stcp , output oe ); wire [13:0] data ; reg [1:0] cnt_4 ; reg [3:0] cnt_bit_14 ; assign data = {duan[0],duan[1],duan[2],duan[3],duan[4],duan[5],duan[6],duan[7],wei}; assign oe = 1'b0; // 4分频计数器 always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) cnt_4 <= 2'b0 ; else if(cnt_4 == 2'd3) cnt_4 <= 2'b0 ; else cnt_4 <= cnt_4 + 2'b1 ; end // 传输14位计数器 always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) cnt_bit_14 <= 4'b0; else if(cnt_bit_14 == 4'd13 && cnt_4 == 2'd3) cnt_bit_14 <= 4'b0; else if(cnt_4 == 2'd3) cnt_bit_14 <= cnt_bit_14 + 4'b1; else cnt_bit_14 <= cnt_bit_14; end // -------------------- 输出信号 ---------------------------------- always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) shcp <= 1'b0; else if(cnt_4>=2'd2) shcp <= 1'b1; else shcp <= 1'b0; end always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) stcp <= 1'b0; else if(cnt_bit_14 == 4'd0 && cnt_4 == 2'd0) stcp <= 1'b1; else stcp <= 1'b0; end always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) ds <= 1'b0; else if(cnt_4 == 1'b0) ds <= data[cnt_bit_14]; else ds <= ds; end endmodule
顶层模块
module seg_key ( input clk , input rst_n , input key_01 , input key_02 , output ds , output shcp , output stcp , output oe ); wire[5:0]wei; wire[7:0]duan; wire key_flage_01; wire key_flage_02; key_filter c1 ( .Clk(clk), .Rst_n(rst_n), .key_in(key_01), .key_flag(key_flage_01) ); key_filter c2 ( .Clk(clk), .Rst_n(rst_n), .key_in(key_02), .key_flag(key_flage_02) ); seg_01 //# //( // .CNT_WAIT_MAX(24'd24) // 减小仿真时间 //) a1 ( .sys_clk(clk), .sys_rst_n(rst_n), .key_flage_01(key_flage_01), .key_flage_02(key_flage_02), .wei(wei), .duan(duan) ); seg_595 a2 ( .clk(clk) , .rst_n(rst_n) , .wei(wei) , .duan(duan) , .ds(ds) , .shcp(shcp) , .stcp(stcp) , .oe(oe) ); endmodule
二、测试文件
module tb_seg_key; reg clk; reg rst_n; reg key_01; reg key_02; wire ds; wire shcp; wire stcp; wire oe; initial begin clk = 1'b0; rst_n = 1'b0; #20; rst_n = 1'b1; key_01 = 1'b1; key_02 = 1'b1; end always #10 clk = ~ clk; always #10 key_01 = {$random}%2; always #10 key_02 = {$random}%2; seg_key out ( .clk(clk) , .rst_n(rst_n) , .key_01(key_01) , .key_02(key_02) , .ds(ds) , .shcp(shcp) , .stcp(stcp) , .oe(oe) ); endmodule
三、波形图
由于需要的时间太长,因此不方便查看仿真图
四、RTL图
五、上板验证


浙公网安备 33010602011771号