数码管实现电子时钟

一.模块设计图

在这里插入图片描述

二.设计思路

2.1计数器设计

  • 设计四个计数器,第一个计50_000_000,表示计满1s;第二个计数器计数秒位;第三个计数器计数分钟位;第四个计数器计数小时位。
  • 计数器+1标志:秒计数器当计满一秒+1,分钟计数器当秒计数器计满60时+1,小时计数器当分钟计数器计满60时+1;所有计数器当计满清零。

2.2时序图

在这里插入图片描述

2.3传输数据

  • time_count模块有三个输出:[4:0]hour、[5:0]min、[5:0]sec。传输给seg_dirver模块。每一位数据如下:
    在这里插入图片描述

2.4余晖效应

  • 计数器计1ms,数码管每隔1ms做位拼接,肉眼无法分辨1ms的数码管位选变化,在视觉上就是数码管全亮的状态。

2.5设定小数点位

  • point_n可以在顶层模块例化模块是直接给它赋值,将数值位设为7位,考察data时(case(data))将小数点位和数值位拼接起来。可以实现小数点固定位亮。
    在这里插入图片描述

在这里插入图片描述

三.代码

  • time_count.v
/**************************************功能介绍***********************************
Date	: 2023年8月2日11:17:33
Author	: Alegg xy.
Version	: 1.0
Description: 
*********************************************************************************/
    
//---------<模块及端口声名>------------------------------------------------------
module time_count( 
    input				clk		,
    input				rst_n	,
    output      [4:0]   hour    ,
    output	    [5:0]	min	    ,
    output	    [5:0]	sec	    
);								 
//---------<参数定义>--------------------------------------------------------- 
    parameter MAX = 26'd50_000_000;//1s
    parameter MAX_sec = 6'd59;//一分钟60秒
    parameter MAX_min = 6'd59;//1小时60分钟
    parameter MAX_hour = 5'd23;//1天24小时
//---------<内部信号定义>-----------------------------------------------------
    reg			[25:0]	cnt	   	;
    wire				add_cnt	;
    wire				end_cnt	;

    reg			[5:0]	cnt_sec	   	;
    wire				add_cnt_sec	;
    wire				end_cnt_sec	;

    reg			[5:0]	cnt_min	   	;
    wire				add_cnt_min	;
    wire				end_cnt_min	;

    reg			[4:0]	cnt_hour	;
    wire				add_cnt_hour;
    wire				end_cnt_hour;
    
    always @(posedge clk or negedge rst_n)begin 
       if(!rst_n)begin
            cnt <= 'd0;
        end 
        else if(add_cnt)begin 
            if(end_cnt)begin 
                cnt <= 'd0;
            end
            else begin 
                cnt <= cnt + 1'd1;
            end 
        end
    end 
    
    assign add_cnt = 1'b1;
    assign end_cnt = add_cnt && cnt == MAX - 1'd1;
    

    //秒计数器
    always @(posedge clk or negedge rst_n)begin 
       if(!rst_n)begin
            cnt_sec <= 'd0;
        end 
        else if(add_cnt_sec)begin 
            if(end_cnt_sec)begin 
                cnt_sec <= 'd0;
            end
            else begin 
                cnt_sec <= cnt_sec + 1'd1;
            end 
        end
    end 
    
    assign add_cnt_sec = end_cnt;
    assign end_cnt_sec = add_cnt_sec && cnt_sec == MAX_sec;
    
    //分计数器
    always @(posedge clk or negedge rst_n)begin 
       if(!rst_n)begin
            cnt_min <= 'd0;
        end 
        else if(add_cnt_min)begin 
            if(end_cnt_min)begin 
                cnt_min <= 'd0;
            end
            else begin 
                cnt_min <= cnt_min + 1'd1;
            end 
        end
    end 
    
    assign add_cnt_min = end_cnt_sec;
    assign end_cnt_min = add_cnt_min && cnt_min == MAX_min;
    
    //小时计数器
    always @(posedge clk or negedge rst_n)begin 
       if(!rst_n)begin
            cnt_hour <= 'd0;
        end 
        else if(add_cnt_hour)begin 
            if(end_cnt_hour)begin 
                cnt_hour <= 'd0;
            end
            else begin 
                cnt_hour <= cnt_hour + 1'd1;
            end 
        end
    end 
    
    assign add_cnt_hour = end_cnt_min;
    assign end_cnt_hour = add_cnt_hour && cnt_hour == MAX_hour;
    
    
    assign hour = cnt_hour;
    assign min = cnt_min;
    assign sec = cnt_sec;
endmodule
  • seg_dirver.v
/**************************************功能介绍***********************************
Date	: 2023年8月2日13:44:09
Author	: Alegg xy.
Version	: 1.0
Description: 
*********************************************************************************/
    
//---------<模块及端口声名>------------------------------------------------------
module seg_driver( 
    input				clk		,
    input				rst_n	,
    input		[4:0]	hour	,
    input		[5:0]	min		,
    input		[5:0]	sec		,
    input       [5:0]   point_n ,

    output	reg	[5:0]	sel	    ,
    output	reg	[7:0]	seg	    
);								 
//---------<参数定义>--------------------------------------------------------- 
    parameter MAX_1ms = 50_000;//1ms
//---------<内部信号定义>-----------------------------------------------------
    reg [3:0]   data;//存数据
    reg [5:0]   point_n_r;//存小数点位

    reg			[15:0]	cnt_1ms	   	;
    wire				add_cnt_1ms	;
    wire				end_cnt_1ms	;
    
    always @(posedge clk or negedge rst_n)begin 
       if(!rst_n)begin
            cnt_1ms <= 'd0;
        end 
        else if(add_cnt_1ms)begin 
            if(end_cnt_1ms)begin 
                cnt_1ms <= 'd0;
            end
            else begin 
                cnt_1ms <= cnt_1ms + 1'b1;
            end 
        end
    end 
    
    assign add_cnt_1ms = 1'b1;
    assign end_cnt_1ms = add_cnt_1ms && cnt_1ms == MAX_1ms - 1'd1;
    
    always @(posedge clk or negedge rst_n)begin 
        if(!rst_n)begin
            sel <= 6'b111_110;
        end  
        else if (end_cnt_1ms) begin
             sel <= {sel[4:0],sel[5]};
        end 
    end

    always @(*)begin 
        case (sel)
            6'b111_110:begin data = hour / 10;   point_n_r = point_n[0]; end
            6'b111_101:begin data = hour % 10;   point_n_r = point_n[1]; end
            6'b111_011:begin data = min / 10 ;   point_n_r = point_n[2]; end
            6'b110_111:begin data = min % 10 ;   point_n_r = point_n[3]; end
            6'b101_111:begin data = sec / 10 ;   point_n_r = point_n[4]; end
            6'b011_111:begin data = sec % 10 ;   point_n_r = point_n[5]; end
            default: data = 4'd0;
        endcase
    end
    
    always @(*)begin 
        case (data)
            4'h0:seg = {point_n_r,7'b100_0000};
            4'h1:seg = {point_n_r,7'b111_1001};
            4'h2:seg = {point_n_r,7'b010_0100};
            4'h3:seg = {point_n_r,7'b011_0000};
            4'h4:seg = {point_n_r,7'b001_1001};
            4'h5:seg = {point_n_r,7'b001_0010};
            4'h6:seg = {point_n_r,7'b000_0010};
            4'h7:seg = {point_n_r,7'b111_1000};
            4'h8:seg = {point_n_r,7'b000_0000};
            4'h9:seg = {point_n_r,7'b001_0000};
            default: seg = 8'b1100_0000;
        endcase
    end
    
endmodule

  • top_clock.v
/**************************************功能介绍***********************************
Date	: 2023年8月2日13:58:10
Author	: Alegg xy.
Version	: 1.0
Description: 
*********************************************************************************/
    
//---------<模块及端口声名>------------------------------------------------------
module top_clock( 
    input				clk		,
    input				rst_n	,
    input       [5:0]   point_n ,
    output		[5:0]	sel 	,
    output		[7:0]	seg	
);								 
//---------<参数定义>--------------------------------------------------------- 
    wire [4:0] hour_link;
    wire [5:0] min_link;
    wire [5:0] sec_link;
//---------<内部信号定义>-----------------------------------------------------
    time_count u_time_count(
        .clk		(clk),
        .rst_n	    (rst_n),
        .hour       (hour_link),
        .min	    (min_link),
        .sec	    (sec_link) 
    );
    
    seg_driver u_seg_dirver(
        .clk		(clk),
        .rst_n	    (rst_n),
        .hour	    (hour_link),
        .min		(min_link),
        .sec		(sec_link),
        .point_n    (6'b110101),
        .sel	    (sel),
        .seg	    (seg)
    );    
    
    
endmodule
eg_dirver(
        .clk		(clk),
        .rst_n	    (rst_n),
        .hour	    (hour_link),
        .min		(min_link),
        .sec		(sec_link),
        .point_n    (6'b110101),
        .sel	    (sel),
        .seg	    (seg)
    );    
    
    
endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值