当前位置: 首页 > news >正文

DE2-115分秒计数器

一、模块设计

如若不清楚怎么模块化,请看https://blog.csdn.net/szyugly/article/details/146379170?spm=1001.2014.3001.5501

1.1顶层模块

module top_counter(
    input  wire       CLOCK_50,    // 50MHz时钟
    input  wire       KEY0,        // 暂停/继续按键
    output wire [6:0] HEX3, HEX2, HEX1, HEX0,  // 4位七段数码管
    output wire [3:0] DIGIT_EN     // 数码管位选
);

wire clk_1hz;        // 1Hz时钟
wire clk_scan;       // 扫描时钟(1kHz)
wire pause_pulse;    // 消抖后的暂停信号

// 模块实例化
clk_div u_clk_div(
    .clk_50m(CLOCK_50),
    .clk_1hz(clk_1hz),
    .clk_1k(clk_scan)
);

debounce u_debounce(
    .clk(CLOCK_50),
    .key_in(KEY0),
    .key_out(pause_pulse)
);

time_counter u_time_counter(
    .clk(clk_1hz),
    .pause(pause_pulse),
    .min_ten(min_ten),
    .min_unit(min_unit),
    .sec_ten(sec_ten),
    .sec_unit(sec_unit)
);

display u_display(
    .clk(clk_scan),
    .min_ten(min_ten),
    .min_unit(min_unit),
    .sec_ten(sec_ten),
    .sec_unit(sec_unit),
    .seg_data({HEX3, HEX2, HEX1, HEX0}),
    .digit_en(DIGIT_EN)
);

endmodule

1.2计数器模块

module time_counter(
    input  wire clk,      // 1Hz时钟
    input  wire pause,    // 暂停信号
    output reg [3:0] min_ten,  // 分钟十位
    output reg [3:0] min_unit, // 分钟个位
    output reg [3:0] sec_ten,  // 秒钟十位
    output reg [3:0] sec_unit  // 秒钟个位
);

reg pause_state;  // 暂停状态寄存器

always @(posedge clk) begin
    if(pause) pause_state <= ~pause_state; // 切换暂停状态
end

always @(posedge clk) begin
    if(!pause_state) begin  // 非暂停状态
        // 秒个位计数
        if(sec_unit == 4'd9) begin
            sec_unit <= 0;
            // 秒十位计数
            if(sec_ten == 4'd5) begin
                sec_ten <= 0;
                // 分钟个位计数
                if(min_unit == 4'd9) begin
                    min_unit <= 0;
                    // 分钟十位计数
                    if(min_ten == 4'd5) begin
                        min_ten <= 0;
                    end else begin
                        min_ten <= min_ten + 1;
                    end
                end else begin
                    min_unit <= min_unit + 1;
                end
            end else begin
                sec_ten <= sec_ten + 1;
            end
        end else begin
            sec_unit <= sec_unit + 1;
        end
    end
end

endmodule

1.3按键消抖模块

module debounce(
    input  wire clk,      // 50MHz时钟
    input  wire key_in,   // 原始按键输入
    output reg  key_out   // 消抖后输出
);

reg [19:0] counter;      // 20ms计数器 (50MHz * 0.02s = 1,000,000)
reg key_reg;

always @(posedge clk) begin
    key_reg <= key_in;    // 同步输入
    
    if(key_reg != key_out) begin       // 状态变化
        counter <= 20'd0;
    end else if(counter < 20'd1_000_000) begin
        counter <= counter + 1;
    end else begin
        key_out <= key_reg;           // 稳定后更新输出
    end
end

endmodule

1.4显示驱动模块

module display(
    input  wire clk,          // 扫描时钟(1kHz)
    input  wire [3:0] min_ten,
    input  wire [3:0] min_unit,
    input  wire [3:0] sec_ten,
    input  wire [3:0] sec_unit,
    output reg  [6:0] seg_data,  // 段选信号
    output reg  [3:0] digit_en    // 位选使能
);

reg [1:0] scan_cnt;        // 扫描计数器
reg [3:0] data_temp;       // 当前显示数据

// 七段译码表(共阳极)
parameter [6:0] SEG_BCD [0:9] = {
    7'b1000000, // 0
    7'b1111001, // 1
    7'b0100100, // 2
    7'b0110000, // 3
    7'b0011001, // 4
    7'b0010010, // 5
    7'b0000010, // 6
    7'b1111000, // 7
    7'b0000000, // 8
    7'b0010000  // 9
};

always @(posedge clk) begin
    scan_cnt <= scan_cnt + 1;
    case(scan_cnt)
        2'b00: begin
            digit_en <= 4'b1110;  // 最低位
            data_temp <= sec_unit;
        end
        2'b01: begin
            digit_en <= 4'b1101;
            data_temp <= sec_ten;
        end
        2'b10: begin
            digit_en <= 4'b1011;
            data_temp <= min_unit;
        end
        2'b11: begin
            digit_en <= 4'b0111;  // 最高位
            data_temp <= min_ten;
        end
    endcase
    
    seg_data <= SEG_BCD[data_temp]; // 查表输出
end

endmodule

1.5分频模块

module clk_div(
    input  wire clk_50m,  // 50MHz输入
    output reg  clk_1hz,  // 1Hz输出
    output reg  clk_1k    // 1kHz扫描时钟
);

// 1Hz分频计数器 (50,000,000分频)
reg [25:0] cnt_1hz;
always @(posedge clk_50m) begin
    if(cnt_1hz == 26'd49_999_999) begin
        cnt_1hz <= 0;
        clk_1hz <= ~clk_1hz;
    end else begin
        cnt_1hz <= cnt_1hz + 1;
    end
end

// 1kHz分频计数器 (50,000分频)
reg [15:0] cnt_1k;
always @(posedge clk_50m) begin
    if(cnt_1k == 16'd49_999) begin
        cnt_1k <= 0;
        clk_1k <= ~clk_1k;
    end else begin
        cnt_1k <= cnt_1k + 1;
    end
end

endmodule

二、效果展示

计数器

http://www.dtcms.com/a/112319.html

相关文章:

  • 基于javaweb的SpringBoot图片管理系统图片相册系统设计与实现(源码+文档+部署讲解)
  • 基于javaweb的SSM酒吧后台管理系统设计与实现(源码+文档+部署讲解)
  • 【棒垒球规则】全国幼儿软式棒垒球比赛规则(二)·棒球1号位
  • java流程控制04:if选择结构
  • Python 元组
  • deepseek v3-0324 Markdown 编辑器 HTML
  • uniapp的v-for不显示或者swiper-item的不显示
  • LabVIEW面向对象编程设计方法
  • Git Rebase 操作中丢失提交的恢复方法
  • 目前来讲 有哪些三维重建算法,哪个算法效果好
  • 【QT】获取文件路径中的文件名,去掉后缀,然后提取文件名中的数字
  • 判断HiveQL语句为ALTER TABLE语句的识别函数
  • Hyperlane:高性能 Rust HTTP 服务器框架评测
  • 第一期第9讲21:50
  • 洛谷题单3-P1420 最长连号-python-流程图重构
  • 从上帝视角看函数
  • Opencv计算机视觉编程攻略-第九节 描述和匹配兴趣点
  • vue进度条组件
  • Vue3引入ElementPlus
  • SpringCloud第二篇:注册中心Eureka
  • 二叉树 树 - 问题集合
  • 列表与列表项
  • 爬虫案例:使用webpack爬取批量数据
  • 数据库DBA职业规划与技能提升指南
  • Linux | I.MX6ULL 终结者底板原理图讲解完(6)
  • 【Lua】pcall使用详解
  • PCI与PCIe接口的通信架构是主从模式吗?
  • spring IOC 反射 bean生命周期
  • JAVA实战开源项目:在线问卷调查系统(Vue+SpringBoot) 附源码
  • JavaScript 中常见的鼠标事件及应用