FPGA实战——按键控制LED灯

实验任务

无按键按下时,LED 灯全灭;
按键 key0 按下时,LED 灯显示自左往右的流水;
按键 key1 按下时,LED 灯显示自右往左的流水;
按键 key2 按下时,四个 LED 灯同时闪烁;
按键 key3 按下时,LED 灯全亮。

硬件电路

程序设计

1.RTL文件编写

首先我们要了解一下编程的思路。通过按键来实现灯全亮全灭其实很容易,但是要实现流水灯的效果,这就要结合我们上一节的流水灯的知识,就需要一个计数器。我们的思路是这样的:
(由于初学,我们先不进行消抖;然后按键也要一直按着才一直执行,松开就不再执行对应程序段)

  • 流水灯是需要计数器的,所以我们先定义计数器。这个计数器以0.2s为周期。
  • 如果key0被按下,是需要流水灯的,我们就先设置一个led_ctrl变量,来为led目前的状态编码,这个状态每计数器周期就变化一次(也就是一直在流水,就是我们在硬件电路是否调用的问题,调用它就显示出流水)
  • 我们检测按键是否被按下,当key0被按下的时候,我们就对led_ctrl进行判断,对4个状态进行赋值(led_ctrl有4个状态,分别对应4个流水灯亮的状态),一直按着key0就可以实现流水
  • 同理,剩余3个按键的就很简单了。
  • 总结来就是,我们需要一个计数器(一个always块),一个控制led状态的程序(一个always块),一个检测按键,控制led(一个always块)

程序代码如下:

module key_led(input            sys_clk,input            sys_rst_n,input        [3:0] key,output reg [3:0] led);reg [23:0] cnt;      //计数器
reg [1:0]  led_ctrl; //led状态变量//0.2秒计数器
always @ (posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)cnt <= 24'd0;else if(cnt < 24'd1000_0000)cnt <= cnt + 1'b1;elsecnt <= 24'd0; //这是已经数到最大值了,就赋值0
end//led状态赋值  ,这是控制led的状态的,只有流水的时候有用
always @ (posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)led_ctrl <= 2'b00;else if(cnt == 24'd1000_0000)   //计数器周期0.2s,所以led每0.2s状态加一led_ctrl <= led_ctrl + 1'b1;elseled_ctrl <= led_ctrl;
end//按键控制led状态
always @ (posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)led <= 4'b0000;else if(key[0] == 0)  //如果key0按下,实现从左向右的流水灯case(led_ctrl)   2'b00  :  led <= 4'b0001;2'b01  :  led <= 4'b0010;2'b10  :  led <= 4'b0100;2'b11  :  led <= 4'b1000;default:  led <= 4'b0000;endcaseelse if(key[1] == 0)  //如果key1按下,实现从右向左的流水灯case(led_ctrl)   2'b11  :  led <= 4'b0001;2'b10  :  led <= 4'b0010;2'b01  :  led <= 4'b0100;2'b00  :  led <= 4'b1000;default:  led <= 4'b0000;endcase    else if(key[2] == 0)  //如果key2按下,所有灯同时闪烁case(led_ctrl)   2'b00  :  led <= 4'b1111;2'b01  :  led <= 4'b0000;2'b10  :  led <= 4'b1111;2'b11  :  led <= 4'b0000;default:  led <= 4'b0000;endcase else if(key[3] == 0)  //如果key3按下,所有灯都亮。led <= 4'b1111;else                led <= 4'b0000;
end
endmodule

2.约束文件ucf

NET sys_clk            TNM_NET = sys_clk_pin;
TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 20ns HIGH 50%;NET sys_clk     LOC = T8 | IOSTANDARD = LVCMOS33;
NET sys_rst_n   LOC = L3 | IOSTANDARD = LVCMOS33;NET led<0>     LOC = P4 | IOSTANDARD = LVCMOS33;
NET led<1>    LOC = N5 | IOSTANDARD = LVCMOS33;
NET led<2>    LOC = P5 | IOSTANDARD = LVCMOS33;
NET led<3>    LOC = M6 | IOSTANDARD = LVCMOS33;NET key<0>     LOC = C3 | IOSTANDARD = LVCMOS33;
NET key<1>    LOC = D3 | IOSTANDARD = LVCMOS33;
NET key<2>    LOC = E4 | IOSTANDARD = LVCMOS33;
NET key<3>    LOC = E3 | IOSTANDARD = LVCMOS33;

两次实验都出的一个错误。报错如下
key_led.ucf(1): Syntax error. Ensure that the previous constraint specification was terminated with ‘;’.

实际上,不用看后面的 ;提示,问题出在,没有加等号=
TNM_NET = sys_clk_pin; 被写成了
TNM_NET sys_clk_pin; 就报错了

而且有意思的是,这个错误两次都犯过,都是刚开始没意识到的时候,第一次编译总是没有报错,第二次编译才没通过,很奇怪,如果有大佬看见,希望告诉一下原因。

3.下载程序

编译完成之后,就可以生成bit流文件然后下载到开发板了。

RTL图


综合之后就可以看,但是实验来看,需要编译成功,才能看到我们期望看到的那个图。如下图设置好端口,点击右下角的Create Schematic即可。

生成RTL图如下

仿真tb文件编写

因为按键检测,硬件上需要按键去按下松开,是我们人的操作,那tb文件去仿真的时候如何实现呢。我们的思路就是每延时几秒,通过程序让key[i] = 0,通过软件赋值来实现。
//注意,我们要写的操作是在initial中就完成,而不是在always这里,always这是生成时钟。
//新建文件后, 从头开始修改、编写代码!!!修改模块名,initial语句块的赋值等。。。。

`timescale 1ns / 1nsmodule tb_key_led();// Inputsreg sys_clk;reg sys_rst_n;reg [3:0] key;// Outputswire [3:0] led;// Instantiate the Unit Under Test (UUT)key_led u_key_led (.sys_clk(sys_clk), .sys_rst_n(sys_rst_n), .key(key), .led(led));initial begin// Initialize Inputssys_clk    <= 1'b0;sys_rst_n  <= 1'b0;key        <= 4'b1111;// Wait 100 ns for global reset to finish#100;sys_rst_n  <= 1'b1;// Add stimulus here// 1ns * 800_000_000 = 0.8s #2000_0000 key[0] <= 0;    #2000_0000 key[0] <= 1;key[1] <= 0; #2000_0000 key[1] <= 1;key[2] <= 0; #2000_0000 key[2] <= 1;key[3] <= 0; #2000_0000 key[3] <= 1;      end//注意,我们要写的操作是在initial中就完成,而不是在always这里,always这是生成时钟always #10 sys_clk = ~sys_clk;endmodule

出现了一个错误
(vopt-2133) Instantiating ‘u_key_led’ has exceeded the recursion depth limit of 200.

就是这里重名了,导致嵌套死循环。修改如下
最终1s时间内的仿真如图:

以上就是按键控制LED闪烁的工程,包括例化、按键消抖等还未设计,将在之后的工程练习中学习。

FPGA实战篇——【2】按键控制LED灯闪烁相关推荐

  1. Arduino基础入门篇07—按键控制LED灯

    前面介绍了Arduino数字I/O,通过控制数字引脚输出来控制LED灯亮灭.本篇将介绍数字I/O的输入功能,通过检测按键状态来控制LED灯亮灭,把LED的亮灭变成人为可控制的. 1. 实验材料 Uno ...

  2. FPGA:基础入门按键控制LED灯

    题目概述: 使用按键控制LED灯亮灭. 无按键按下--LED全灭 按下KEYO--从右向左的流水灯效果 按下KEY1--从左向右的流水灯效果 按下KEY2--LED闪烁 按下KEY3--LED全亮 编 ...

  3. led计数电路实验报告_「正点原子FPGA连载」第八章 按键控制LED灯实验

    1)实验平台:正点原子开拓者FPGA开发板 2)本实例源码下载:请移步正点原子官网 第八章 按键控制LED灯实验 按键是常用的一种控制器件.生活中我们可以见到各种形式的按键,由于其结构简单,成本低廉等 ...

  4. FPGA(1)基础入门 -- 按键控制led灯

    目录 效果说明 1.配置输入输出变量 2.变量赋值 3.配置引脚(输入输出变量) 代码 效果说明 key1按键按下,led1被点亮. key2按键按下,led2被点亮. 1.配置输入输出变量 inpu ...

  5. 《STM32从零开始学习历程》——USART串口通讯实验篇2——指令控制LED灯实验

    <STM32从零开始学习历程>@EnzoReventon USART串口通讯实验篇2--指令控制LED灯实验 本实验是在<USART串口通讯实验篇1--中断接收与发送>的基础上 ...

  6. 按键控制led灯python程序_树莓派使用threading函数实现多按键控制LED灯

    讲两个知识点.一个是关于上拉和下拉,另一个是关于threading函数. 1.上拉电阻和下拉电阻 上拉就是把一个不确定的信号通过一个电阻连接到高电位,这样在开关断开是信号为高电位,开关合上时信号为低电 ...

  7. STM32F103系列之按键控制LED灯

    上篇已经介绍了点灯的操作了,本篇主要介绍按键控制LED灯进行相关操作. 同样,我们需要对GPIO进行相关的初始化配置,这里我们将LED相关的代码全部放在LED.C和LED.H文件里面. LED.C文件 ...

  8. 基于Verilog的按键控制LED灯

    按键控制LED灯 原理图 程序设计 `timescale 1ns / 1psmodule key_led( input sys_clk, input sys_rst_n, input [3:0] ke ...

  9. 记录1——stm32f411CEU6之点亮一盏LED灯+按键控制LED灯

    文章目录 前言 一.准备工作 二.点亮一盏LED灯 1.配置工程 2.代码实现 3.程序烧录注意 三.按键控制LED灯 1.配置工程 2.代码实现 按键控制 按键进阶1: 按键进阶2 3.基于自己理解 ...

  10. 51单片机实现独立按键控制LED灯

    本节博客主要实现以下效果: 3-1独立按键控制LED亮灭 本段代码主要使用了if...else...语句实现按下按下灯亮,松开按键时灯灭 #include <REGX51.H>void m ...

最新文章

  1. 面对互联网一线大厂,这些技术你需要了解!
  2. Atitit Java OpenCV 捕获视频
  3. redis 服务器/客户端安装与配置
  4. LoRa创始成员“叛逃” NB-IoT要一统物联网?
  5. Java 数字签名原理及产生
  6. 盘式制动优于鼓式制动吗?
  7. JAVA中“:”的用法详解
  8. android timepicker分割线颜色,关于Android的TimePicker和DatePicker一些简单的使用问题
  9. 【java学习之路】(java框架)006.springIOC
  10. 主流区块链底链技术横评 hyperledger fabric、fisco bcos、chainmaker
  11. win7系统sql连接不上服务器,Win7 安装软件时无法连接sql server解决方法
  12. logit回归怎么看显著性_SPSS:Logistic回归(Logistic regression)概述
  13. linux修改键盘按键
  14. Rocket MQ 问题集
  15. 工程训练大赛物流小车_宁大机械学子在工程训练省赛中斩获佳绩,取得历史性突破...
  16. 麦肯锡精英的39个工作习惯
  17. FOC电流双电阻采样两相电流幅值不等一系列问题
  18. 聚类 轮廓 matlab,聚类分析 - MATLAB Simulink Example - MathWorks 中国
  19. 高中学历的我,为什么放弃医院的工作转行互联网?
  20. 2021面试题(拿到offer版本)

热门文章

  1. 基于linux cli( 命令行) 的翻译工具推荐
  2. float及float浮动坍塌问题
  3. 多线程开发之AsyncTask
  4. 我的大脑越来越喜欢那些碎片化的、不用思考的文章了!
  5. 考研英语七附双语阅读:编程玩具——程序员培养从娃娃抓起
  6. 中科院计算机研究所排名,中国科学院计算技术研究所
  7. 样本量重要,还是测序深度重要?
  8. 《python网络爬虫》1-7章答案
  9. win 10 设置静态ip 子网前缀长度
  10. 回收站的文件删了怎么恢复,回收站文件恢复的两种方法