FPGA零基础学习之Vivado-按键使用教程
作者:李西锐校对:陆辉
大侠好,欢迎来到FPGA技术江湖。本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白及打算进阶提升的职业开发者都可以有系统性学习的机会。
(资料图片)
系统性的掌握技术开发以及相关要求,对个人就业以及职业发展都有着潜在的帮助,希望对大家有所帮助。本次带来Vivado系列,按键的使用教程。话不多说,上货。
按键的使用教程
按键是我们使用比较多的器件之一,其结构简单,使用方便。在玩具、家电等方面有广泛的应用。
按键是一种应用比较多的一种电子开关,在我们开发板上有两种按键开关:第一种是本章节需要讲解的轻触开关,第二种是自锁按键,按键按下后保持自锁状态,整个按键处于一直连通状态,再次按下,开关断开,同时开关按钮弹出。
本次我们实验任务,将使用按键控制LED灯点亮,当按键按下时,LED灯亮,松开熄灭。
我们的按键是共阴极设计,电路图如下:
分析电路可知,当我们的按键没有按下时,FPGA管脚为高电平,按键按下,FPGA管脚被短路,电平为低电平。所以我们的按键按下为低松开为高。那么在我们设计实验逻辑时,可以用按键的低电平控制LED灯点亮。
对应的XDC约束语句如下:
我们按键信号作为控制信号来使用,但是我们不能直接去使用,因为轻触按键在按下或者松开时,信号非常不稳定,会导致在按键没有完全按下或者松开时,信号出现很多的毛刺,这样的信号不能作为我们的控制信号,所以我们在写控制逻辑之前,我们首先需要对按键做一下消抖处理,实现信号稳定。我们处理的原理是,当信号一直处于低电平或者高电平一段时间后,我们默认信号处于稳定状态,这个时间我们暂定为10ms。
接下来我们先进行新建工程,首先点击create project。
然后在打开的界面修改工程名字为key_led。
保存位置确定后,点击next。
我们选择RTL Project,点击next。
我们在搜索窗口搜索我们板子的芯片型号,确定好之后点击next。
点击Finish完成新建工程。新建完成之后,我们开始根据前面我们所讲的理论开始写代码。
点击上图红色方框的加号开始新建代码文件。
点击next。选择创建文件。
比如我们新建顶层文件,名字为key_led。
点击OK之后开始写代码,代码内容如下:
01 module jitter(0203 input wire clk,04 input wire rst_n,05 input wire key,0607 output reg flag08 );0910 parameter t = 500_000;1112 reg [18:0] cnt;13 reg state;1415 always @ (posedge clk, negedge rst_n)16 begin17 if(rst_n == 1"b0)18 begin19 cnt <= 19"d0;20 state <= 1"d0;21 flag <= 1"d1;22 end23 else24 case(state)25 1"d0 : begin26 if(key == 1"b0)27 begin28 if(cnt == t - 1)29 begin30 cnt <= 19"d0;31 state <= 1"d1;32 flag <= 1"b0;33 end34 else35 begin36 cnt <= cnt + 1"b1;37 state <= 1"d0;38 flag <= 1"b1;39 end40 end41 else42 begin43 cnt <= 19"d0;44 state <= 1"d0;45 flag <= 1"b1;46 end47 end48 1"d1 : begin49 if(key == 1"b1)50 begin51 if(cnt == t - 1)52 begin53 cnt <= 19"d0;54 state <= 1"d0;55 flag <= 1"b1;56 end57 else58 begin59 cnt <= cnt + 1"b1;60 state <= 1"b1;61 flag <= 1"b0;62 end63 end64 else65 begin66 cnt <= 19"d0;67 state <= 1"b1;68 flag <= 1"b0;69 end70 end71 endcase72 end73 endmodule74
接下来是按键控制LED的逻辑,当按键为低电平时,LED灯点亮。代码如下:
01 module key_ctrl(0203 input wire clk,04 input wire rst_n,05 input wire flag,0607 output reg led08 );0910 always @ (posedge clk, negedge rst_n)11 begin12 if(rst_n == 1"b0)13 led <= 1"b0;14 else if(flag == 1"b0)15 led <= 1"b1;16 else17 led <= 1"b0;18 end19 endmodule
两个模块做好之后,我们在顶层文件中例化子模块:
01 module key_led(0203 input wire clk,04 input wire rst_n,05 input wire key,0607 output wire led08 );0910 wire flag;1112 jitter jitter_inst(1314 .clk (clk),15 .rst_n (rst_n),16 .key (key),1718 .flag (flag)19 );2021 key_ctrl key_ctrl_inst(2223 .clk (clk),24 .rst_n (rst_n),25 .flag (flag),2627 .led (led)28 );2930 endmodule
逻辑控制写好之后,我们做一下仿真,在仿真中,我们为了快速看到现象,我们将参数修改的小一些。代码如下:
01 `timescale 1ns / 1ps0203 module key_led_tb;0405 reg clk;06 reg rst_n;07 reg key;0809 wire led;1011 defparam key_led_inst.jitter_inst.t = 100;1213 initial begin14 clk = 0;15 rst_n = 0;16 key = 1;17 #105;18 rst_n = 1;19 #1000;2021 //模拟按键按下时的抖动22 key = 0;23 #20;24 key = 1;25 #30;26 key = 0;27 #30;28 key = 1;29 #10;30 key = 0;3132 #5000;3334 //模拟按键松开时的抖动35 key = 1;36 #30;37 key = 0;38 #30;39 key = 1;40 #10;41 key = 0;42 #50;43 key = 1;4445 #1000;46 $stop;47 end4849 always #10 clk = ~clk;5051 key_led key_led_inst(5253 .clk (clk ),54 .rst_n (rst_n ),55 .key (key ),5657 .led (led )58 );5960 endmodule
仿真波形:
Flag信号等效按键,flag拉低时,LED灯为高电平,此时灯亮。






























































































































