**这是本文档旧的修订版!**

按键消抖

====硬件平台====

设计要求


  1. 掌握FPGA边沿检测的设计
  2. 掌握按键消抖的原理
  3. 基于小脚丫STEP-MXO2第一代开发平台实现按键消抖的功能,实现脉冲和状态翻转输出。

====工作原理====

抖动原理

  • 抖动的产生 :通常的按键所用的开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖。
  • 消除抖动的措施:在按键按下的时刻,会出现波形的抖动,在之后的一段时间内,才会出现平稳的波形。我们舍弃了刚刚检测到按键按下的时刻,读取这一时刻之后20ms左右的按键信息,这样可以防止一次按键被误读多次。

根据上面的原理描述,我们可以对按键的输入管脚进行下降沿检测,当检测到下降沿后计数开始,计数到20ms时进行采样,然后再对每次采样的值进行下降沿检测,检测的结果作为按键消抖的脉冲输出,然后每次检测到下降沿时让状态输出进行翻转并输出。

====硬件连接====

结合实验平台STEP-Baseboard的硬件配置,我们使用8个LED灯作为流水灯的输出

LED模块电路连接

====代码设计====

设计文件

流水灯程序设计

为了实现对8个LED的控制,我们设计了25位的计数器cnt进行1s周期的循环计数,同时我们定义了一个4位寄存器led_cnt作为状态机的状态控制流水灯的闪烁。状态机共有8个状态,每一个状态对应点亮一个LED灯。

首先是计数器的设计,计数器的计数范围为0~CNTNUM-1,为了实现每个LED灯1秒的点亮时间,设计文件代码中我们定义参数CNTNUM为25000000,但是在仿真文件调用设计文件时,为了方便仿真,我们会将参数CNT_NUM重新赋值为10.

reg [24:0] cnt = 25'd0;
always@(posedge clk_in or negedge rst_n_in) begin
	if(!rst_n_in) begin
		cnt <= 25'd0;
	end else if(cnt>=CNT_NUM-1) begin
		cnt <= 25'd0;
	end else begin
		cnt <= cnt + 25'd1;
	end
end

然后我们需要对状态机的状态进行控制,使得作为状态的寄存器led_cnt实现从0到7的循环加一操作。

reg [3:0] led_cnt = 4'd0;
always@(posedge clk_in or negedge rst_n_in) begin
	if(!rst_n_in) begin
		led_cnt <= 4'd0;
	end else if(cnt==CNT_NUM-1) begin
		if(led_cnt==4'd7) led_cnt <= 4'd0;
		else led_cnt <= led_cnt + 4'd1;
	end
end

最后是组合逻辑,根据led_cnt的不同状态控制不同的LED点亮。

always@(led_cnt) begin
	case(led_cnt)
		4'd0: led_out = 8'b1111_1110;
		4'd1: led_out = 8'b1111_1101;
		4'd2: led_out = 8'b1111_1011;
		4'd3: led_out = 8'b1111_0111;
		4'd4: led_out = 8'b1110_1111;
		4'd5: led_out = 8'b1101_1111;
		4'd6: led_out = 8'b1011_1111;
		4'd7: led_out = 8'b0111_1111;
		default: led_out = 8'b1111_1111;
	endcase
end

测试文件

测试文件中我们需要对设计文件中的参数CNT_NUM进行重新赋值

parameter CNT_NUM = 10;
Water_led #(.CNT_NUM(CNT_NUM))
Water_led_uut
(
.clk_in(sys_clk),
.rst_n_in(sys_rst_n),
.led_out(led_out)
);

引脚分配如下:

管脚名称 clkin| rstnin | ledout[0] ledout[1] |ledout[2] ledout[3] |ledout[4] ledout[5] |ledout[6] led_out[7]
FPGA管脚 C1 A2 B14 C14 E14 F14 G14 J14 K14 L14

仿真结果

流水灯仿真

资源报告

资源 数量 比例 说明
LUTs 28 4%
寄存器 33 2%
存储器 0 0%
IO管脚 10
时钟频率 25MHz

知识点

  • 分频设计
  • 时序控制
  • 简单状态机

参考文档

相关文档

文件名称 功能
Water_led.v 流水灯
Water_led_test.v 测试文件