FPGA Verilog 编写的 可调时 数字钟

改进的可调分秒的数字钟

经过上一篇文章改进而来

module CLK(
input sys_clk,
input rst_n,
input key,//分+
input key1,//秒+
output reg [5:0]sel_seg,//位选
output reg [7:0]seg_led//段选
);

localparam MAX_NUM = 14'd5000;
reg [7:0]sec;
reg [7:0]min;
reg [7:0]hour;
reg flag_sec;//秒进位信号
reg flag_min;//分进位信号
//分频模块
parameter CLK_DIV=4'd10;//分频系数
reg dri_clk;//5MHz数码管驱动时钟
reg [3:0]div_cnt;//分频计数
reg [23:0]sec_cnt;//秒计数,sec_cnt计满5M次为1s
wire [3:0]data0;//秒个位
wire [3:0]data1;//秒十位
wire [3:0]data2;//分个位
wire [3:0]data3;//分十位
wire [3:0]data4;//时个位
wire [3:0]data5;//时十位
assign data5=hour/4'd10;
assign data4=hour%4'd10;
assign data3=min/4'd10;
assign data2=min%4'd10;
assign data1=sec/4'd10;
assign data0=sec%4'd10;

wire key_value;
wire key_flag;
wire key_value1;
wire key_flag1;
key_debounce u_key_debounce(
.sys_clk(dri_clk),.sys_rst_n(rst_n),
.key(key),.key_flag(key_flag),.key_value(key_value));//消抖模块,借鉴的是正点原子的例程

key_debounce u_key_debounce1(
.sys_clk(dri_clk),.sys_rst_n(rst_n),
.key(key1),.key_flag(key_flag1),.key_value(key_value1)); 

always @(posedge sys_clk or negedge rst_n)begin
    if(!rst_n)begin
        div_cnt<=1'b0;
        dri_clk<=1'b0;
    end
    else if(div_cnt==CLK_DIV/2-1)begin
        dri_clk<=~dri_clk;
        div_cnt<=4'd0;
    end
    else begin
        div_cnt<=div_cnt+1'b1;
        dri_clk<=dri_clk;
    end
end

//秒计数模块
always @(posedge dri_clk or negedge rst_n)begin
    if(!rst_n)begin
        sec_cnt<=1'b0;
        sec<=8'd0;
        flag_sec<=1'b0;
        
    end
    else if(key_flag1&&(~key_value1))begin
         if(sec==8'd59)
        begin
            sec<=8'd0;
            flag_sec<=1'b1;
        end
        else begin
            flag_sec<=1'b0;
            sec<=sec+1'b1;
        end
    end
    else if(sec_cnt==24'd500_0000)begin
        if(sec==8'd59)begin
            sec_cnt<=24'd0;
            sec<=8'd0;
            flag_sec<=1'b1;    			
        end
        else begin
	    flag_sec<=1'b0;
        sec_cnt<=24'd0;
        sec<=sec+1'b1;	    
        end
    end
    
    else begin
	    flag_sec<=1'b0;
        sec<=sec;
        sec_cnt<=sec_cnt+1'b1;
    end
end

//分计数模块
always @(posedge dri_clk or negedge rst_n)begin
    if(!rst_n)begin
        min<=8'd0;
        flag_min<=1'b0;
    end
    else if(key_flag&&(~key_value)) begin
    if(min==8'd59)
        begin
            min<=8'd0;
            flag_min<=1'b1;
        end
        else begin
            flag_min<=1'b0;
            min<=min+1'b1;
        end
    end
    else if(flag_sec)begin    
    if(min==8'd59)begin
            flag_min<=1'b1;
            min<=8'd0;
        end        
        else begin
            flag_min<=1'b0;
            min<=min+1'b1;
        end
    end
    
    else begin 
        flag_min<=1'b0;
        min<=min;
        end
end
//时计数模块
always @(posedge dri_clk or negedge rst_n)begin
    if(!rst_n)begin
        hour<=8'd0;
    end
    else if(flag_min)begin
        if(hour==8'd24)
           hour<=8'd0;
        else hour<=hour+1'b1;
    end
    else  hour<=hour;
end

reg [3:0]display_num;
reg [2:0]cnt0;//位选计数
reg [13:0]cnt1;
//数码管位选
reg flag;
always @(posedge dri_clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt1<=14'd0;
        flag<=1'b0;
    end
    else if(cnt1==MAX_NUM-1)begin
        cnt1<=14'd0;
        flag<=1'b1;    
    end
    else begin
        flag<=1'b0;
        cnt1<=cnt1+1'b1;
    end
end

always @(posedge dri_clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt0<=3'd0;
        end
    else if(flag)begin
        if(cnt0==3'd5)
            cnt0<=3'd0;
        else cnt0<=cnt0+1'b1;
    end
    else cnt0<=cnt0;
end


always @(posedge dri_clk or negedge rst_n)begin
    if(!rst_n)begin
        sel_seg<=6'b111111;
        display_num<=4'd0;
    end
    else begin
        case(cnt0)
        3'd0:begin
            sel_seg<=6'b111110;
            display_num<=data0;
            end
        3'd1:begin
            sel_seg<=6'b111101;
            display_num<=data1;
            end
        3'd2:begin
            sel_seg<=6'b111011;
            display_num<=data2;
            end
        3'd3:begin
            sel_seg<=6'b110111;
            display_num<=data3; 
            end   
        3'd4:begin
            sel_seg<=6'b101111;
            display_num<=data4;
            end
        3'd5:begin
            sel_seg<=6'b011111;
            display_num<=data5;

            end
        default:begin
                sel_seg<=6'b111111;
                display_num<=4'd0;
                end
        endcase
    end
end
//数码管显示
always@(posedge dri_clk or negedge rst_n)begin
    if(!rst_n)
    seg_led<=8'd1111111;
    else begin
        case(display_num)
        4'd0:begin
            if(cnt0==3'd2||cnt0==3'd4)
            seg_led<=8'b01000000;
            else seg_led<=8'b11000000;
            end
        4'd1:begin           
             if(cnt0==3'd2||cnt0==3'd4) seg_led<=8'b01111001;
             else  seg_led<=8'b11111001;
             end
        4'd2:begin
             if(cnt0==3'd2||cnt0==3'd4)
             seg_led<=8'b00100100;
             else seg_led<=8'b10100100;
             end
        4'd3:begin
             if(cnt0==3'd2||cnt0==3'd4)
             seg_led<=8'b00110000;
             else seg_led<=8'b10110000;
             end   
        4'd4:begin
              if(cnt0==3'd2||cnt0==3'd4)
             seg_led<=8'b00011001;
             else  seg_led<=8'b10011001;
             end
        4'd5:begin
            if(cnt0==3'd2||cnt0==3'd4)
            seg_led<=8'b00010010;   
            else
            seg_led<=8'b10010010; 
            end
        4'd6:begin
             if(cnt0==3'd2||cnt0==3'd4)
             seg_led<=8'b00000010;
             else  seg_led<=8'b10000010;
             end
        4'd7:begin
             if(cnt0==3'd2||cnt0==3'd4)
             seg_led<=8'b01111000;
             else  seg_led<=8'b11111000;
             end
        4'd8:begin
             if(cnt0==3'd2||cnt0==3'd4)
             seg_led<=8'b00000000;
             else  seg_led<=8'b10000000;
             end
        4'd9:begin
             if(cnt0==3'd2||cnt0==3'd4)
             seg_led<=8'b00010000;
             else  seg_led<=8'b10010000;
             end
        default:seg_led<=8'b1111111;
        endcase
    end
end

endmodule
  • 2
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值