您的位置:首页 > 科技 > IT业 > 湖北网页设计师培训_指纹定制网站_2022十大热点事件及评析_seo和sem的区别与联系

湖北网页设计师培训_指纹定制网站_2022十大热点事件及评析_seo和sem的区别与联系

2025/4/8 1:18:38 来源:https://blog.csdn.net/qq_73050400/article/details/146922873  浏览:    关键词:湖北网页设计师培训_指纹定制网站_2022十大热点事件及评析_seo和sem的区别与联系
湖北网页设计师培训_指纹定制网站_2022十大热点事件及评析_seo和sem的区别与联系

基于 FPGA 的分秒计数器

文章目录

  • 基于 FPGA 的分秒计数器
    • 一、设计原理
      • (一)分频器
      • (二)按键控制
      • (三)分秒计时器
    • 二、设计实现
      • (一)分频器模块(clock_divider.v)
      • (二)按键控制模块
      • (三)分秒计时器模块
      • (四)顶层模块(top.v)
    • 三、实现效果
    • 四、总结

一、设计原理

(一)分频器

FPGA 开发板通常提供 50MHz 的时钟信号,但分秒计数器仅需 1Hz 的时钟来实现每秒计数一次的效果。分频器模块的作用就是将 50MHz 的高频时钟分频为 1Hz 的低频时钟。其核心原理是通过一个计数器对输入时钟进行计数,当计数值达到分频系数的一半(对于 50MHz 到 1Hz 的分频,分频系数为 50000000 ,即计数到 25000000)时,翻转输出时钟信号的电平,同时将计数器清零,重新开始计数。

(二)按键控制

  1. 按键消抖:机械按键在按下和松开时会产生抖动,导致按键信号不稳定,可能出现多次触发的情况。为解决这一问题,采用延时消抖的方法。当按键状态保持 20ms 以上时,才认为按键状态稳定,锁存该状态并产生一个脉冲信号。在 50MHz 时钟下,1ms 对应 50000 个时钟周期,因此使用一个 20 位的计数器,计数到 1000000(50000×20)即达到 20ms。
  2. 按键暂停计时:将按键消抖后产生的脉冲信号转换为一个稳定的切换信号。每当检测到有效的按键脉冲时,翻转暂停状态信号,从而实现暂停和继续计时的功能。

(三)分秒计时器

  1. 计时器逻辑:分秒计数器遵循特定的计数规则。秒个位从 0 计数到 9,满 9 后归零并向秒十位进位;秒十位从 0 计数到 5,满 59 秒后归零并向分个位进位;分个位从 0 计数到 9,满 9 后归零并向分十位进位;分十位从 0 计数到 5,满 59 分后归零,最大显示 59:59。
  2. 显示模块:七段数码管有共阳极和共阴极两种类型。共阳极数码管在笔段电极接低电平、公共阳极接高电平时发光;共阴极数码管则相反,驱动信号为高电平、公共阴极接低电平时发光。通过将计数器的输出值转换为对应的七段数码管显示代码,实现时间的可视化。

二、设计实现

(一)分频器模块(clock_divider.v)

module clock_divider #(parameter DIVISOR = 50000000  
)(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;endendend
endmodule

(二)按键控制模块

  1. 按键消抖模块(debounce.v)
module debounce(input clk,input reset_n,input key_in,output reg key_pulse
);reg [19:0] count;  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 beginkey_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  count <= count + 1'b1;endelse beginkey_pulse <= key_in_sync2 & ~key_stable;  endendend
endmodule
  1. 按键暂停计时模块(pause_control.v)
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;endend
endmodule

(三)分秒计时器模块

  1. 计时器逻辑模块(min_sec_counter.v)
module min_sec_counter(input clk,input reset_n,input pause,output reg [3:0] sec_ones,output reg [3:0] sec_tens,output reg [3:0] min_ones,output reg [3:0] min_tens
);always @(posedge clk or negedge reset_n) beginif (!reset_n) beginsec_ones <= 4'd0;sec_tens <= 4'd0;min_ones <= 4'd0;min_tens <= 4'd0;endelse if (!pause) begin  if (sec_ones == 4'd9) beginsec_ones <= 4'd0;if (sec_tens == 4'd5) beginsec_tens <= 4'd0;if (min_ones == 4'd9) beginmin_ones <= 4'd0;if (min_tens == 4'd5) beginmin_tens <= 4'd0;endelse beginmin_tens <= min_tens + 4'd1;endendelse beginmin_ones <= min_ones + 4'd1;endendelse beginsec_tens <= sec_tens + 4'd1;endendelse beginsec_ones <= sec_ones + 4'd1;endendend
endmodule
  1. 显示模块(seven_seg_display.v)
module seven_seg_display(input [3:0] digit,output reg [6:0] seg
);always @(*) begincase (digit)4'h0: seg = 7'b1000000;  4'h1: seg = 7'b1111001;  4'h2: seg = 7'b0100100;  4'h3: seg = 7'b0110000;  4'h4: seg = 7'b0011001;  4'h5: seg = 7'b0010010;  4'h6: seg = 7'b0000010;  4'h7: seg = 7'b1111000;  4'h8: seg = 7'b0000000;  4'h9: seg = 7'b0010000;  default: seg = 7'b1111111;  endcaseend
endmodule

(四)顶层模块(top.v)

module top(input clk_50m,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  
);wire clk_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)) 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));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

三、实现效果

通过综合、编译和下载到 FPGA 开发板后,分秒计数器能够准确计时。按下复位按键,计数器归零;按下暂停按键,计时暂停,再次按下则继续计时。七段数码管实时显示当前的分钟和秒数,范围为 00:00 至 59:59,实现了预期的计时功能。
在这里插入图片描述

四、总结

本设计成功利用 Verilog 语言在 FPGA 上实现了分秒计数器,通过多个功能模块的协同工作,完成了时钟分频、按键控制、计时和显示等功能。在设计过程中,各模块之间的信号连接和逻辑关系是关键,需要仔细规划和调试。同时,这种模块化的设计方法提高了代码的可读性和可维护性,为后续功能扩展和优化奠定了基础。

版权声明:

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

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