前言
本课程是按键消抖的一个扩展内容,主要是通过实验观察按键消抖和不消抖的一个区别。
一、按键消抖
按键抖动:按键抖动通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动。当按下一次按键,可能在A点检测到一次低电平,在B点检测到一次高电平,在C点又检测到一次低电平。同时抖动是随机,不可测的。那么按下一次按键,抖动可能会误以为按下多次按键。
1.按键消抖目的:消除按键抖动对我们程序的影响。
图1. 按键特写
2.
按键消抖解决方案1:延迟采样。
图2. 延迟采样
3.
按键消抖解决方案2:信号变化频率平稳后并且持续20ms则采样。
图3. 信号平稳后采样
二、任务描述
使用按键控制开发板上一个led灯的亮灭,当按键按下的时候led灯就亮,当再一次按下按键的时候led就不亮了。由于按键存在抖动,按键松开的时候led灯就不亮,所以需要一个消抖模块对按键消抖。通过实验来观察消抖和不消抖的一个区别。
三、系统框图
图4. 系统框图
四、模块描述
图5. 模块关系示意图
五、模块代码
- 创建single_led文件,编写single_led模块代码。
module single_led(
input clk ,//开发板晶振频率50MHz
input rst_n ,//复位下降沿有效
input flag ,//消抖完成标志
input key_value,//稳定按键信号
output reg led //led灯
);
//计时器模块
always@(negedge rst_n or posedge clk)begin
if(!rst_n)begin
led <= 1'b0;//初始化led灯,高电平有效
end
else if(flag && ~key_value)begin
led <= ~led;//稳定电平对led取反
end
else begin
led <= led;//其他时刻,led等于其自身
end
end
endmodule
- 创建key_debounce文件,编写key_debounce模块代码。
module key_debounce(
input wire clk ,//时钟50MHz
input wire rst_n,//复位信号,下降沿有效
input wire key ,//按键
output reg flag ,//消抖完成标志,0表示还在抖动,1表示抖动结束
output reg key_value//消抖完的有效电平
);
parameter DELAY = 20'd1000_000;//20ms
reg [19:0] delay_cnt ;//延迟计数器
reg key_reg ;//中间按键寄存器,存放当前按键信号,用于和下次按键信号做比较
//延迟计数器模块
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin//按键复位
delay_cnt <= 20'd0;//初始延迟计数器默认为0
key_reg <= 1'b1;//初始中间按键寄存器为高电平,按键高电平无效
end
else begin
key_reg <= key;
if(key_reg ==1 && key == 0)begin//如果抖动
delay_cnt <= DELAY;//开始设置延迟计数器初值
end
else begin//没有抖动
if(delay_cnt > 20'd0)begin//如果延迟计数器大于0
delay_cnt <= delay_cnt - 20'd1;//开始倒数计时
end
else begin
delay_cnt <= 20'd0;//如果延迟计数器小于等于0,延迟计数器清0
end
end
end
end
//根据延迟计数器获取状态以及稳定的按键信号
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin//复位信号
flag <= 1'b0;//抖动标志,初始为抖动
key_value <= 1'b1;//记录按键稳定信号
end
else if(delay_cnt == 1'd1)begin//计数从0包括999_999一共1_000_000个数
flag <= 1'b1;//条件满足,改变抖动标志
key_value <= key;//key_value将稳定信号输出
end
else begin
flag <= 1'b0;//计数器没有记满1_000_000个数,始终为抖动
key_value <= key_value;//key_value保持不变
end
end
endmodule
- 新建top_key_led文件,编写top_key_led模块代码。
module top_key_led(
input wire clk ,//时钟50MHz
input wire rst_n,//复位信号,下降沿有效
input wire key ,//按键信号
output wire led//led灯信号
);
wire flag ;
wire key_value;
key_debounce u_key_debounce(//实例化按键消抖模块
.clk (clk) ,//时钟信号
.rst_n (rst_n),//复位信号
.key (key) ,//按键信号
.flag (flag) ,//消抖信号
.key_value (key_value)//按键稳定信号
);
single_led u_single_led(//实例化led控制模块
.clk (clk ) ,//时钟信号
.rst_n (rst_n) ,//复位信号
.flag (flag) ,//消抖信号
.key_value (key_value),//按键稳定信号
.led (led)//led灯信号
);
endmodule
六、管脚信息
图6. pin planner
元件 | 管脚 |
---|---|
LED0 | G15 |
LED1 | F16 |
LED2 | F15 |
LED3 | D16 |
KEY0 | E15 |
KEY1 | E16 |
KEY2 | M16 |
KEY3 | M15 |
COLOCK(时钟) | E1 |
表1. 管脚信息表
七、运行效果
按键控制led+按键消抖
总结
消抖前的按键控制led和消抖后的按键控制led,效果是不一样的。按键的物理特性导致按键存在抖动,我们不能改变按键的物理特性,但是可以通过代码,来消除按键抖动带来的负面影响。下期课程——按键控制蜂鸣器,将加入同样的按键消抖模块,使用消抖的按键控制蜂鸣器名叫。敬请期待!
版权声明:本文为CSDN博主「stark-lin」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43828944/article/details/122360794
暂无评论