FPGA数字电子钟

举报
莫言2021 发表于 2021/12/10 14:53:15 2021/12/10
【摘要】 将时间拆分为6个参数:        second_1  -> 秒个位        second_10 -> 秒十位        minute_1  -> 分个位        minute_10 -> 分十位        hour_1;   -> 时个位        hour_10;  -> 时十位在异步复位的时候为上述六个参数赋初始值。然后对50Mhz系统时钟进行计数,计数50M...

将时间拆分为6个参数:

        second_1  -> 秒个位
        second_10 -> 秒十位
        minute_1  -> 分个位
        minute_10 -> 分十位
        hour_1;   -> 时个位
        hour_10;  -> 时十位

在异步复位的时候为上述六个参数赋初始值。
然后对50Mhz系统时钟进行计数,计数50M次(即为1s)。然后对六个参数的当前值做出判断,并在下一个clk做出改变。

当计满一秒,且秒的个位大于0时,——》秒的个位减1
当计满一秒,且秒的个位等于0,秒的十位大于0时,——》秒的十位减1,秒的个位变9
当计满一秒,且秒为00,并且分的个位大于0时,——》分的个位减1,秒由00变为59
当计满一秒,且秒为00,并且分的个位等于0,分的十位大于0时,——》分的十位减1,个位变为9,秒由00变为59
当计满一秒,且秒为00,分也为00,时的个位大于0时,——》时的个位减1,分由00变为59,秒也由00变为59
当计满一秒,且秒为00,分也为00,时的个位等于0,时的十位大于0时,——》时的十位减1,个位变9,分由00变为59,秒也由00变为59
当计满一秒,且时分秒为:00 00 00时,——》还原为预设值

仅当【suspend】状态值为1的时候才会对50Mhz系统时钟进行计数,为0时暂停计数,这样就实现了计数器的暂停。

CODE

module down_cnt(
                clk,
                rst,
                suspend,
                second_1,
                second_10,
                minute_1,
                minute_10,
                hour_1,
                hour_10
);
 

        input clk;
        input rst;
        input suspend; //当suspend为状态量,为0时计时暂停,为1时计时继续。
        output reg [3:0] second_1; //秒个位
        output reg [2:0] second_10;//秒十位
        output reg [3:0] minute_1; //分个位
        output reg [2:0] minute_10;//分十位
        output reg [3:0] hour_1;   //时个位
        output reg [1:0] hour_10;  //时十位

        reg [31:0] cnt;//50M -> 1s (50M时钟进行50M次计数得到一秒,)

always@(posedge clk or negedge rst)
        begin
                if(!rst)//复位时设置倒计时初始值
                    begin
                            cnt <= 32'd0;
                            second_1 <= 4'd0;
                            second_10 <= 3'd0;
                            minute_1 <= 4'd1;
                            minute_10 <= 3'd0;
                            hour_1 <= 4'd0;
                            hour_10 <= 2'd0;
                    end    
                    //当计满一秒,且秒的个位大于0时,——》秒的个位减1
                    else if(cnt == 32'd5000_0000 && second_1>4'd0)
                        begin
                            second_1 <= second_1 - 4'd1;
                            cnt <= 32'd0;
                        end
                    //当计满一秒,且秒的个位等于0,秒的十位大于0时,——》秒的十位减1,秒的个位变9
                    else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10>3'd0 )
                        begin
                            second_10 <= second_10 - 3'd1;
                            second_1 <= 4'd9;
                            cnt <= 32'd0;
                        end
                    //当计满一秒,且秒为00,并且分的个位大于0时,——》分的个位减1,秒由00变为59
                    else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10==3'd0 && minute_1>4'd0 )
                        begin
                            minute_1 <= minute_1 - 4'd1;    
                            second_10 <= 3'd5;
                            second_1 <= 4'd9;
                            cnt <= 32'd0;
                        end
                    //当计满一秒,且秒为00,并且分的个位等于0,分的十位大于0时,——》分的十位减1,个位变为9,秒由00变为59
                    else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10==3'd0 && minute_1==4'd0 && minute_10 > 3'd0)
                        begin
                           minute_10 <= minute_10 - 3'd1;
                            minute_1 <= 4'd9;
                            second_10 <= 3'd5;
                            second_1 <= 4'd9;
                            cnt <= 32'd0;
                        end
                    //当计满一秒,且秒为00,分也为00,时的个位大于0时,——》时的个位减1,分由00变为59,秒也由00变为59
                    else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10==3'd0 && minute_1==4'd0 && minute_10 ==3'd0 && hour_1 >4'd0)
                        begin
                            hour_1 <= hour_1 - 4'd1;
                            minute_10 <= 3'd5;
                            minute_1 <= 4'd9;
                            second_10 <= 3'd5;
                            second_1 <= 4'd9;
                            cnt <= 32'd0;
                        end
                    //当计满一秒,且秒为00,分也为00,时的个位等于0,时的十位大于0时,——》时的十位减1,个位变9,分由00变为59,秒也由00变为59
                    else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10==3'd0&& minute_1==4'd0 && minute_10 ==3'd0 && hour_1 == 4'd0 && hour_10 > 2'd0 && hour_10< 2'd2 )
                        begin
                            hour_10 <= hour_10 - 2'd1;
                           hour_1 <= 4'd9;
                            minute_10 <= 3'd5;
                            minute_1 <= 4'd9;
                            second_10 <= 3'd5;
                            second_1 <= 4'd9;
                            cnt <= 32'd0;
                        end
                    //当计满一秒,且时分秒为:00 00 00时,——》还原为预设值
                    else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10==3'd0 && minute_1==4'd0 && minute_10 ==3'd0 && hour_1 == 4'd0 && hour_10 == 2'd0 )
                        begin
                            hour_10 <= 2'd0;
                            hour_1 <= 4'd0;
                            minute_10 <= 3'd0;
                            minute_1 <= 4'd0;
                            second_10 <= 3'd0;
                            second_1 <= 4'd0;
                            cnt <= 32'd0;
                        end                       
                    else if(suspend == 1'b1)
                        begin
                            cnt <= cnt + 32'd1;
                        end
                    else
                        begin
                            cnt <= cnt;
                        end

        end
endmodule

顶层CODE

使用六个数码管来显示六个时间参数,下为顶层文件。(数码管的驱动见:链接

module top(
                clk,
                rst,
                dig,
                suspend,
                dict
                );
    input clk;
    input rst;
    input suspend;
    output  [5:0] dig;  //六个数码管片选
    output  [7:0] dict; //动态数码管段选
    
    wire [23:0] set_data;//数码管显示的内容:4bit*6 
 down_cnt f1(
            .clk(clk),
            .rst(rst),
            .suspend(suspend),
            .second_1(set_data[3:0]),
            .second_10(set_data[7:4]),
            .minute_1(set_data[11:8]),
            .minute_10(set_data[15:12]),
            .hour_1(set_data[19:16]),
            .hour_10(set_data[23:20])
);
                
        dig8_6 f2(
                 .clk(clk),
                 .rst(rst),
                 .set_data(set_data),
                 .dig(dig), 
                 .dict(dict)
               );
               
            
endmodule

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。