Verilog实现按键计数器
一、简介
计数器我们都知道,这里我们旨在使用Verilog HDL 来实现按键计数器的操作,功能有:
1、按下一个键,计数加一(+1);
2、按下另一个键,计数减一(-1);
3、按下复位键,则计数清零。
4、最多计数60次。
二、 代码实现
我们使用了两个模块,第一个是按键消抖模块,第二个是实现计数器的功能。因为,我们都知道,用按键,必消抖。
1、按键消抖模块:
// ********************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// ********************************************************************
// File name : debounce.v
// Module name : debounce
// Author : STEP
// Description :
// Web : www.stepfpga.com
//
// --------------------------------------------------------------------
// Code Revision History :
// --------------------------------------------------------------------
// Version: |Mod. Date: |Changes Made:
// V1.0 |2017/03/02 |Initial ver
// --------------------------------------------------------------------
// Module Function:按键消抖
module debounce_button (clk,rst,key,key_pulse);
parameter N = 1; //要消除的按键的数量
input clk;
input rst;
input [N-1:0] key; //输入的按键
output [N-1:0] key_pulse; //按键动作产生的脉冲
reg [N-1:0] key_rst_pre; //定义一个寄存器型变量存储上一个触发时的按键值
reg [N-1:0] key_rst; //定义一个寄存器变量储存储当前时刻触发的按键值
wire [N-1:0] key_edge; //检测到按键由高到低变化是产生一个高脉冲
//利用非阻塞赋值特点,将两个时钟触发时按键状态存储在两个寄存器变量中
always @(posedge clk or negedge rst)
begin
if (!rst) begin
key_rst <= {N{1'b1}}; //初始化时给key_rst赋值全为1,{}中表示N个1
key_rst_pre <= {N{1'b1}};
end
else begin
key_rst <= key; //第一个时钟上升沿触发之后key的值赋给key_rst,同时key_rst的值赋给key_rst_pre
key_rst_pre <= key_rst; //非阻塞赋值。相当于经过两个时钟触发,key_rst存储的是当前时刻key的值,key_rst_pre存储的是前一个时钟的key的值
end
end
assign key_edge = key_rst_pre & (~key_rst);//脉冲边沿检测。当key检测到下降沿时,key_edge产生一个时钟周期的高电平
reg [17:0] cnt; //产生延时所用的计数器,系统时钟12MHz,要延时20ms左右时间,至少需要18位计数器
//产生20ms延时,当检测到key_edge有效是计数器清零开始计数
always @(posedge clk or negedge rst)
begin
if(!rst)
cnt <= 18'h0;
else if(key_edge)
cnt <= 18'h0;
else
cnt <= cnt + 1'h1;
end
reg [N-1:0] key_sec_pre; //延时后检测电平寄存器变量
reg [N-1:0] key_sec;
//延时后检测key,如果按键状态变低产生一个时钟的高脉冲。如果按键状态是高的话说明按键无效
always @(posedge clk or negedge rst)
begin
if (!rst)
key_sec <= {N{1'b1}};
else if (cnt==18'h3ffff)
key_sec <= key;
end
always @(posedge clk or negedge rst)
begin
if (!rst)
key_sec_pre <= {N{1'b1}};
else
key_sec_pre <= key_sec;
end
assign key_pulse = key_sec_pre & (~key_sec);
endmodule
2、按键计数器的模块:
module btncounter(clk,rst, btn1, btn2,seg_led_1,seg_led_2);
input clk;
input rst;
input btn1;
input btn2;
// input [3:0] seg_data_1;
//数码管需要显示0~9十个数字,所以最少需要4位输入做译码
// input [3:0] seg_data_2;
output [8:0] seg_led_1;
//在小脚丫上控制一个数码管需要9个信号 MSB~LSB=DIG、DP、G、F、E、D、C、B、A
output [8:0] seg_led_2;
//在小脚丫上第二个数码管的控制信号 MSB~LSB=DIG、DP、G、F、E、D、C、B、A
reg [8:0] seg [9:0];
//定义了一个reg型的数组变量,相当于一个10*9的存储器,存储器一共有10个数,每个数有9位宽
wire key_pulse1;
wire key_pulse2;
reg [5:0] counting = 2'd00;
reg [3:0] seg_data_1= 1'd0;
reg [3:0] seg_data_2= 1'd0;
initial
//在过程块中只能给reg型变量赋值,Verilog中有两种过程块always和initial
begin
seg[0] = 9'h3f;
//对存储器中第一个数赋值9'b00_0011_1111,相当于共阴极接地,DP点变低不亮,7段显示数字 0
seg[1] = 9'h06;
//7段显示数字 1
seg[2] = 9'h5b;
//7段显示数字 2
seg[3] = 9'h4f;
//7段显示数字 3
seg[4] = 9'h66;
//7段显示数字 4
seg[5] = 9'h6d;
//7段显示数字 5
seg[6] = 9'h7d;
//7段显示数字 6
seg[7] = 9'h07;
//7段显示数字 7
seg[8] = 9'h7f;
//7段显示数字 8
seg[9] = 9'h6f;
//7段显示数字 9
end
debounce_button u1 (
.clk (clk),
.rst (rst),
.key (btn1),
.key_pulse (key_pulse1)
);
//按键1对应于加一
debounce_button u2 (
.clk (clk),
.rst (rst),
.key (btn2),
.key_pulse (key_pulse2)
);
//按键2对应于减一
always@(posedge clk or negedge rst)
begin
if(~rst)
begin
counting <= 0;
end
else
begin
if(key_pulse1)
begin
counting <= (counting + 1) % 60;
end
else
begin
if(key_pulse2)
begin
counting <= (counting -1 + 60) % 60;
end
else
begin
counting <= counting;
end
end
seg_data_1 <= counting / 10;
if(counting % 10 == 0)
begin
seg_data_2 <= 0;
end
else
begin
seg_data_2 <= counting - 10 * seg_data_1;
end
end
end
assign seg_led_1 = seg[seg_data_1];
assign seg_led_2 = seg[seg_data_2];
endmodule
然后进行,设置引脚以及烧录:
三、效果
我们使用如下所示的视频来展示具体的效果:
https://www.bilibili.com/video/BV1f34y1R7Wm?spm_id_from=333.999.0.0
按键计数器的视频文章来源:https://www.toymoban.com/news/detail-445076.html
以上就是使用Verilog HDL来实现计数器的功能的基本操作了,如果有帮助的话就点个赞吧,谢谢大家的阅读与支持了啦,(づ ̄3 ̄)づ╭❤~。文章来源地址https://www.toymoban.com/news/detail-445076.html
到了这里,关于Verilog实现按键计数器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!