按键消抖+点亮led灯


前言

  本课程是按键消抖的一个扩展内容,主要是通过实验观察按键消抖和不消抖的一个区别。


一、按键消抖

  按键抖动:按键抖动通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动。当按下一次按键,可能在A点检测到一次低电平,在B点检测到一次高电平,在C点又检测到一次低电平。同时抖动是随机,不可测的。那么按下一次按键,抖动可能会误以为按下多次按键。

1.按键消抖目的:消除按键抖动对我们程序的影响。

真实按键

图1. 按键特写
2.
按键消抖解决方案1:延迟采样。

延迟采样1

图2. 延迟采样

3.
按键消抖解决方案2:信号变化频率平稳后并且持续20ms则采样。

延迟采样2

图3. 信号平稳后采样


二、任务描述

  使用按键控制开发板上一个led灯的亮灭,当按键按下的时候led灯就亮,当再一次按下按键的时候led就不亮了。由于按键存在抖动,按键松开的时候led灯就不亮,所以需要一个消抖模块对按键消抖。通过实验来观察消抖和不消抖的一个区别。


三、系统框图

在这里插入图片描述

图4. 系统框图


四、模块描述

在这里插入图片描述

图5. 模块关系示意图


五、模块代码

  1. 创建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  
  1. 创建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 
  1. 新建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

生成海报
点赞 0

stark-lin

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐