您的位置:首页 > 科技 > 能源 > 全网覆盖推广_在线制作网页系统_网站设计与实现毕业设计_唐山seo快速排名

全网覆盖推广_在线制作网页系统_网站设计与实现毕业设计_唐山seo快速排名

2025/4/6 18:35:40 来源:https://blog.csdn.net/weixin_74345079/article/details/146925109  浏览:    关键词:全网覆盖推广_在线制作网页系统_网站设计与实现毕业设计_唐山seo快速排名
全网覆盖推广_在线制作网页系统_网站设计与实现毕业设计_唐山seo快速排名

任务目标

分秒计数器核心功能:实现从00:00到59:59的循环计数,通过四个七段数码管显示分钟和秒。

复位功能:支持硬件复位,将计数器归零并显示00:00。

启动/暂停控制:通过按键控制计时的启动和暂停。

消抖处理:消除按键抖动对计时逻辑的影响,确保按键响应稳定。

实现思路

核心功能

计数逻辑:

使用两个BCD(二进制编码的十进制)计数器分别存储分钟和秒:

秒计数器:个位(0-9)和十位(0-5)。

分钟计数器:个位(0-9)和十位(0-5)。

每秒递增秒计数器:

当秒的个位达到9时,十位加一,个位归零。

当秒的十位达到5且个位达到9时,分钟计数器加一,秒计数器归零。

当分钟的个位达到9且十位达到5时,计数器归零。

显示逻辑:

将BCD计数器的值转换为七段数码管的段码。

使用查找表(case语句)将每个数字映射到对应的段码。

确保数码管的段码格式正确(共阳极或共阴极)。

边界条件:

秒从59递增到0(即60)时,分钟加一。

分钟从59递增到0(即60)时,计数器归零。

七段数码管

数码管的一种是半导体发光器件,数码管可分为七段数码管和八段数码管,区别在于八段数码管比七段数码管多一个用于显示小数点的发光二极管单元DP(decimal point),其基本单元是发光二极管。

七段数码管分为共阳极及共阴极,共阳极的七段数码管的正极(或阳极)为八个发光二极管的共有正极,其他接点为独立发光二极管的负极(或阴极),使用者只需把正极接电,不同的负极接地就能控制七段数码管显示不同的数字。共阴极的七段数码管与共阳极的只是接驳方法相反而已。

如图是数码管显示编码表,包含了共阳和共阴两种不同的极性。

复位功能

复位信号:

使用一个硬件按键作为复位输入,按下时复位信号激活。

复位信号为低电平有效或高电平有效,需根据具体硬件设计确定。

复位逻辑:

当复位信号激活时,将所有计数器清零。

同时将状态机重置到初始状态(暂停状态)。

确保复位信号优先级高于其他操作,避免复位过程中计数器继续运行。

启动/暂停控制功能

状态管理:

使用状态机管理计时逻辑,定义两个状态:

IDLE(暂停状态)。

RUNNING(运行状态)。

按键按下时,状态在IDLE和RUNNING之间切换。

按键检测:

使用边沿检测识别按键的按下事件,避免误触发。

在状态机中,根据当前状态和按键输入更新下一个状态。

状态输出:

在RUNNING状态下,每秒递增计数器。

在IDLE状态下,计数器保持不变。

消抖功能

抖动特性:

按键抖动会导致信号短时间内多次变化,需要通过延时采样消除抖动。

消抖逻辑:

使用一个计时器检测按键状态的稳定性:

当检测到按键状态变化时,启动计时器。

如果在设定时间(如20ms)内状态保持稳定,则更新按键状态。

计时器的位宽需足够大,确保能够覆盖设定的延时。

稳定输出:

只有当按键状态稳定后,才输出有效的控制信号。

确保消抖后的信号与原始按键信号的极性一致。

思考

为什么要消抖?

机械按键在按下或释放的瞬间,由于物理触点的弹性作用,会产生一系列快速的开闭跳变,这种现象称为按键抖动。抖动信号表现为一系列短暂的高低电平变化,而不是理想的单一电平变化。

抖动信号可能导致电路误判按键状态,例如,一次按键可能被误认为多次按键。同时抖动信号会导致输出不稳定,影响后续逻辑电路的正常工作;频繁的信号变化可能增加电路的功耗和资源占用等。

因此消抖处理在数字电路设计中至关重要。

如下是按键原理图

状态机思想

状态机思想是一种用于设计和分析数字系统行为的模型,通过定义一系列状态、输入信号和状态转移规则来描述系统的动态行为。状态机的核心在于将复杂的行为分解为若干个简单的状态,并根据输入信号触发状态之间的转移,每个状态对应特定的输出或行为。状态机通常分为Moore型(输出仅取决于当前状态)和Mealy型(输出取决于当前状态和输入信号),具有模块化设计、清晰逻辑和高效资源利用的优点。

在本次任务中我们可以设置IDLE(暂停状态,计数器停止运行)RUNNING(运行状态,计数器每秒递增)两个状态。

代码实现

在这里我们采用分模块化编写代码,具体使用为:在Visual Studio Code中分模块化编写代码,然后编译(配置verilog语言编写环境,可以参考上期报告),编写无误后,使用Quartus 烧录下载,进行实现。

这里分为分频模块、消抖模块、暂停模块、计数器模块、显示模块、顶层模块

分频模块

module clock_divider #(parameter DIVISOR = 50000000  // 默认50MHz->1Hz)(input clk_in,input reset_n,output reg clk_out);reg [31:0] counter;always @(posedge clk_in or negedge reset_n) beginif (!reset_n) begincounter <= 0;clk_out <= 0;endelse beginif (counter >= (DIVISOR/2 - 1)) begincounter <= 0;clk_out <= ~clk_out;endelse begincounter <= counter + 1;endendendendmodule

消抖模块

module debounce(input clk,input reset_n,input key_in,output reg key_pulse);reg [19:0] count;  // 20ms 消抖计数器 (50MHz时钟下,1ms=50000个周期)reg key_in_sync1, key_in_sync2;reg key_stable;always @(posedge clk or negedge reset_n) beginif (!reset_n) beginkey_in_sync1 <= 1'b1;key_in_sync2 <= 1'b1;key_stable <= 1'b1;count <= 20'd0;key_pulse <= 1'b0;endelse begin// 同步输入信号key_in_sync1 <= key_in;key_in_sync2 <= key_in_sync1;// 检测按键状态变化if (key_in_sync2 != key_stable) beginkey_stable <= key_in_sync2;count <= 20'd0;endelse if (count < 20'd1000000) begin  // 20ms (50MHz * 0.02s)count <= count + 1'b1;endelse beginkey_pulse <= key_in_sync2 & ~key_stable;  // 产生上升沿脉冲endendendendmodule

暂停模块

module pause_control(input clk,input reset_n,input pause_pulse,output reg pause_toggle);always @(posedge clk or negedge reset_n) beginif (!reset_n) beginpause_toggle <= 1'b0;endelse if (pause_pulse) beginpause_toggle <= ~pause_toggle;endendendmodule

计数器模块

module top(input clk_50m,         // 50MHz 时钟输入input reset_n,         // 复位按键 (低电平有效)input pause_key,       // 暂停/继续按键output [6:0] hex0,     // 秒个位数码管output [6:0] hex1,     // 秒十位数码管output [6:0] hex2,     // 分个位数码管output [6:0] hex3,     // 分十位数码管output [7:0] ledg      // LED 显示秒数 (可选));// 内部信号定义wire clk_1hz;             // 1Hz 时钟wire pause_pulse;         // 消抖后的暂停脉冲信号wire pause_toggle;        // 暂停状态信号wire [3:0] sec_ones;      // 秒个位wire [3:0] sec_tens;      // 秒十位wire [3:0] min_ones;      // 分个位wire [3:0] min_tens;      // 分十位// 时钟分频模块clock_divider #(.DIVISOR(50000000)    // 50MHz -> 1Hz) clk_div (.clk_in(clk_50m),.reset_n(reset_n),.clk_out(clk_1hz));// 按键消抖模块debounce debounce_pause (.clk(clk_50m),.reset_n(reset_n),.key_in(pause_key),.key_pulse(pause_pulse));// 暂停控制模块 (将脉冲信号转换为 toggle 信号)pause_control pause_ctrl (.clk(clk_50m),.reset_n(reset_n),.pause_pulse(pause_pulse),.pause_toggle(pause_toggle));// 分秒计数器模块min_sec_counter counter (.clk(clk_1hz),.reset_n(reset_n),.pause(pause_toggle),.sec_ones(sec_ones),.sec_tens(sec_tens),.min_ones(min_ones),.min_tens(min_tens));// 数码管显示模块seven_seg_display seg0 (.digit(sec_ones), .seg(hex0));seven_seg_display seg1 (.digit(sec_tens), .seg(hex1));seven_seg_display seg2 (.digit(min_ones), .seg(hex2));seven_seg_display seg3 (.digit(min_tens), .seg(hex3));endmodule

显示模块

module seven_seg_display(input [3:0] digit,output reg [6:0] seg);always @(*) begincase (digit)4'h0: seg = 7'b1000000;  // 04'h1: seg = 7'b1111001;  // 14'h2: seg = 7'b0100100;  // 24'h3: seg = 7'b0110000;  // 34'h4: seg = 7'b0011001;  // 44'h5: seg = 7'b0010010;  // 54'h6: seg = 7'b0000010;  // 64'h7: seg = 7'b1111000;  // 74'h8: seg = 7'b0000000;  // 84'h9: seg = 7'b0010000;  // 9default: seg = 7'b1111111;  // 全灭endcaseendendmodule

顶层模块

module top(input clk_50m,         // 50MHz 时钟输入input reset_n,         // 复位按键 (低电平有效)input pause_key,       // 暂停/继续按键output [6:0] hex0,     // 秒个位数码管output [6:0] hex1,     // 秒十位数码管output [6:0] hex2,     // 分个位数码管output [6:0] hex3,     // 分十位数码管output [7:0] ledg      // LED 显示秒数 (可选));// 内部信号定义wire clk_1hz;             // 1Hz 时钟wire pause_pulse;         // 消抖后的暂停脉冲信号wire pause_toggle;        // 暂停状态信号wire [3:0] sec_ones;      // 秒个位wire [3:0] sec_tens;      // 秒十位wire [3:0] min_ones;      // 分个位wire [3:0] min_tens;      // 分十位// 时钟分频模块clock_divider #(.DIVISOR(50000000)    // 50MHz -> 1Hz) clk_div (.clk_in(clk_50m),.reset_n(reset_n),.clk_out(clk_1hz));// 按键消抖模块debounce debounce_pause (.clk(clk_50m),.reset_n(reset_n),.key_in(pause_key),.key_pulse(pause_pulse));// 暂停控制模块 (将脉冲信号转换为 toggle 信号)pause_control pause_ctrl (.clk(clk_50m),.reset_n(reset_n),.pause_pulse(pause_pulse),.pause_toggle(pause_toggle));// 分秒计数器模块min_sec_counter counter (.clk(clk_1hz),.reset_n(reset_n),.pause(pause_toggle),.sec_ones(sec_ones),.sec_tens(sec_tens),.min_ones(min_ones),.min_tens(min_tens));// 数码管显示模块seven_seg_display seg0 (.digit(sec_ones), .seg(hex0));seven_seg_display seg1 (.digit(sec_tens), .seg(hex1));seven_seg_display seg2 (.digit(min_ones), .seg(hex2));seven_seg_display seg3 (.digit(min_tens), .seg(hex3));endmodule

顶层模块是整个分秒计数器系统的集成中心,它负责协调各个子模块的工作,实现从时钟输入到数码管显示的完整功能链路。

编译无误过后就可以通过Quartus 烧录了。

实物效果

分秒计数器

总结

通过这次分秒计时器的设计实践,我对数字电路的模块化设计和状态机思想有了更深刻的理解。模块化设计将复杂系统分解为分频、消抖、暂停控制、计数器和显示等独立模块,不仅降低了设计难度,还提高了代码的可维护性和可扩展性。状态机的应用则通过定义IDLE和RUNNING两种状态,清晰地实现了计时器的启动和暂停功能。此外,硬件设计中的细节处理,如按键消抖和七段数码管的显示逻辑,让我认识到细节对系统稳定性的重要性。通过延时采样和段码转换,我解决了抖动和显示错误的问题,确保了计时器的准确性和可靠性。

这次实践让我更加体会到硬件设计是一个不断试错和优化的过程。从分频模块的调试到显示模块的优化,每一步都需要反复测试和调整。通过逐步集成和模块化测试,我不仅成功解决了多个技术难题,还积累很多经验。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com