文章目录
- 一、按键入门
-
- 1.1、实验原理
- 1.2、程序设计
- 1.3、对应的PDS工程分析
- 1.4、实验现象
- 二、按键消抖
-
- 2.1、实验原理
- 2.2、程序设计
一、按键入门
1.1、实验原理
PGL22G 上含有 4 个用户按键 KEY1~KEY4, 其中 KEY1/RST 按键为后续程序中会用到的复位按键, 与其他三个按键无本质区别, 四个按键都连接到 FPGA 的普通的 IO 上,按键低电平有效,当按键按下, FPGA 的 IO 输入电压为低,当没有按键按下时, FPGA的 IO 输入电压为高。 按键与FPGA连接示意图如下:
1.2、程序设计
这个程序没有设计的很复杂,通过简单的硬件描述语言看透硬件描述语言和 FPGA 硬件的联系。首先我们将按键输入经过一个非门后再经过 2 组 D 触发器。经过 D 触发器的信号,会在 D 触发器时钟输入的上升沿锁存然后再送到输出。
在进行硬件描述语言编码之前,我们已经把硬件构建完成,这是一个正常的开发流程。有了硬件设计思路无论是通过画图还是通过 Verilog HDL、VHDL 都能完成设计,根据设计的复杂程序和对某种语言的熟悉程序来选择工具。
1.3、对应的PDS工程分析
(1)首先建立按键的测试工程,添加 verilog 测试代码,完成编译分配管脚等流程。
(2)使用 View RTL Schematic 工具查看设计
(3)分析 RTL 图,可以看出第一级 D 触发器经过取反后输入,第二级直接输入,和预期设计一致
1.4、实验现象
程序下载到开发板以后, “LED1”、“LED2”、“LED3”、"LED4"都处于亮状态,按键“KEY1”按下“LED1” 灭,按键“KEY2”按下“LED2” 灭,按键“KEY3”按下“LED3” 灭, 按键“KEY4”按下“LED4”灭。
二、按键消抖
2.1、实验原理
按键做作为基本的人机输入接口,在很多电子设计中都能见到,由于机械特性,在按键按下或松开的时候**,按键输入值是有抖动的**,无论按下去是多平稳,都难以消除抖动,按键消抖方式有很多,本实验主要是通过 FPGA 计时来消抖。实验中设计了一个计数器,当按键输入有变化时,计时器清零,否则就累加,直到加到一个预定值(例如 10ms),就认为按键稳定,输出按键值,这样就得到以后没有抖动的按键值。由于在很多地方需要用到按键下降沿或上升沿的检测,按键消抖模块直接集成了上升沿和下降沿检测的功能。
2.2、程序设计
如下图所示,通过按键消抖后,在按键按下时,十进制计数器加 1,通过数码管译码扫描后显示出来。
按键消抖部分的原理在上节已经讲过,按键消抖部分代码写的非常精炼,阅读起来稍显费解,建议结合仿真波形去读代码。按键消抖模块(ax_debounce
)端口定义如下:
信号名称 | 方向 | 说明 |
---|---|---|
clk | in | 时钟输入 |
rst_n | in | 异步复位输入,低复位 |
button_in | in | 按键输入 |
button_posedge | out | 消抖后按键上升沿,高有效,1 个时钟周期 |
button_negedge | out | 消抖后按键下升沿,高有效,1 个时钟周期 |
button_out | out | 消抖后按键输出 |
LED 显示部分在本章不做说明,就例程中按键消抖模块“ax_debounce
”模块做一些讲解。
模块中通过了两级 D 触发器来寄存键值,只有当键值稳定时才将键值输出。我们可以看到在 assign赋值语句中有一条“assign a_reset=(DFF1 ^ DFF2)
”,学过数字电路的应该都知道“ ^
”是异或运算符,运算符两边相同运算结果为 0, 不同运算结果为 1。在程序中 DFF1 和 DFF2 异或运算后的值通过“assign”赋给“a_reset”表示比较锁存键值的前后两级寄存器的值是否一致,只有前后两级寄存器的值一致,也就是 a_reset
的值为 0 时才表示当前锁存的键值没有变化。当计数器累加到“TIMER_MAX_VAL
”,表示锁存的键值已经稳定可以输出。
另外在模块中我们可以看到“{...}
”符号,要注意这可不是大括号,这表示位拼接运算符,其作用是将运算符内的两位,或是多位信号拼接在一起,具体用法请参考例程。
最后,程序中需要说明的是“button_posedge
”和“button_negedge
”两个输出信号,这是一种常用的上升沿和下降沿的采集方法,其描述的 RTL 视图如下:
当然还有其他的边沿检测电路的描述方法,但是其基本原理都是在逻辑时序电路里先将需要检测的信号作为输入非阻塞赋值给一个自定义寄存器,通过判断前后两级寄存器的值来判断是上升沿或是下降沿,由 0 ->1
变化是上升沿,由 1 -> 0
变化是下降沿;