按键控制led变化

news2024/12/27 11:16:09

文章目录

  • 按键控制led变化
    • 一、简介
    • 二、代码
    • 三、仿真代码
    • 四、仿真结果
    • 五、总结

按键控制led变化

一、简介

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

二、代码

module key_led (
    input wire clk,
    input wire rst_n,
    input wire[3:0] key,
     
    output reg[3:0] led
);
parameter TIME_0_2S = 10_000_000;  //
reg[24:0] cnt_0_2S;
reg[1:0] state;
//=================0.2s计时====================//
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        cnt_0_2S<=24'd0;
    end
    else if(cnt_0_2S == TIME_0_2S - 1)begin
        cnt_0_2S<=24'd0;
    end
    else begin
        cnt_0_2S<=cnt_0_2S+1'b1;
    end
end


//=================state=================//
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        state<=2'b00;
    end
    else if(cnt_0_2S == TIME_0_2S - 1) begin
        state<=state+1'b1;
    end
    else begin
        state<=state;
    end
end
//================按键控制流水灯===============//
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        led<=4'b0000;
    end
    else if(~key[0]) begin
        case (state)
            2'd0:led<=4'b0001;
            2'd1:led<=4'b0010;
            2'd2:led<=4'b0100;
            2'd3:led<=4'b1000;
        endcase
    end
    else if(~key[1]) begin
        case (state)
            2'd0:led<=4'b1000;
            2'd1:led<=4'b0100;
            2'd2:led<=4'b0010;
            2'd3:led<=4'b0001;
        endcase
    end
    else if(~key[2]) begin
        case (state)
            2'd0:led<=4'b1111;
            2'd1:led<=4'b0000;
            2'd2:led<=4'b1111;
            2'd3:led<=4'b0000;
        endcase
    end
    else if(~key[3]) begin
        case (state)
            2'd0:led<=4'b1111;
            2'd1:led<=4'b1111;
            2'd2:led<=4'b1111;
            2'd3:led<=4'b1111;
        endcase
    end
    else begin
        led<=4'b0000;
    end
end

endmodule
// -----------------------------------------------------------------------------
// Copyright (c) 2014-2023 All rights reserved
// -----------------------------------------------------------------------------
// Author : 辣子鸡味的句橘子,331197689@qq.com
// File   : key_debounce.v
// Create : 2023-07-14 10:36:44
// Revise : 2023-07-14 10:36:44
// Editor : sublime text4, tab size (4)
// -----------------------------------------------------------------------------
module key_debounce(
    input wire clk,
    input wire rst_n,
    input wire[3:0] key_in,//四个按键信号输入

    output reg[3:0] key_out//四个按键信号消抖输出
);

parameter TIME_20MS = 1000_000;
reg[19:0] cnt;//20ms计数器
wire add_cnt;//计数开始
wire ent_cnt;//计数终止
wire nedge;//下降沿检测

reg[3:0] key_in_r0;//同步key_in输入信号
reg[3:0] key_in_r1;//延迟一个周期
reg[3:0] key_in_r2;//延迟两个周期

reg flag;//消抖开始标志信号

//计数器模块,当addent满足时开始计数,检测到下降沿重新计数,end_ent满足时停止计数,消抖完成
always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin
       cnt<=20'd0;
    end
    else if(add_cnt)begin
        if(ent_cnt)begin
            cnt<=20'd0;
        end
        else if(nedge)begin
            cnt<=20'd0;
        end
        else begin
            cnt<=cnt+1;
        end
    end
    else begin
        cnt<=cnt;
    end
end

assign add_cnt = flag;//计数开始条件
assign end_cnt = (cnt == TIME_20MS - 1)&&add_cnt;//终止结束条件,当满足计时到20ms,且满足计时条件时成立

//信号延时模块
always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        key_in_r0<=4'b1111;
        key_in_r1<=4'b1111;
        key_in_r2<=4'b1111;
    end
    else begin
        key_in_r0<=key_in;
        key_in_r1<=key_in_r0;
        key_in_r2<=key_in_r1;
    end
end

//检测下降沿,当任意一个按键出现下降沿都会被检测到
assign nedge = (~key_in_r1[0]&key_in_r2[0])||(~key_in_r1[1]&key_in_r2[1])||(~key_in_r1[2]&key_in_r2[2])||(~key_in_r1[3]&key_in_r2[3]);

//消抖开始模块
always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin
       flag<=1'b0;
    end
    else if(nedge)begin//当出现下降沿开始消抖
        flag<=1'b1;
    end
    else if(end_cnt)begin//当end_cnt满足时停止消抖
        flag<=1'b0;
    end
    else begin
        flag<=flag;
    end
end

//输出信号赋值模块,当消抖完毕标志按键按下,出现一个脉冲信号表示按键按下
always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin
       key_out<=4'b1111;//默认为高电瓶
    end
    else if(end_cnt)begin
        key_out<=key_in;//稳定信号赋值
    end
    else begin
       key_out<=4'b1111;//其他信号默认为高电平
    end
end

endmodule
module key_top(
    input wire clk,
    input wire rst_n,
    input wire[3:0] key,

    output wire[3:0] led
);
wire[3:0] key_r;

key_debounce inst_key_debounce (
	.clk(clk), 
	.rst_n(rst_n), 
	.key(key), 
	.key_r(key_r));
key_led inst_key_led (
	.clk(clk), 
	.rst_n(rst_n), 
	.key(key_r), 
	.led(led));

endmodule

三、仿真代码

module key_top_tb();
reg clk;
reg rst_n;
reg[3:0] key;
wire[3:0] led;
wire[3:0] key_r;

parameter SYS_CLK = 20;
parameter TIME = 100;
always #(SYS_CLK/2) clk = ~clk;
initial begin
	clk=1'b0;
	rst_n=1'b0;
	#(2*SYS_CLK);
	rst_n=1'b1;
	key = 4'b1111;
	#(2*SYS_CLK);
	repeat (19) begin
   		key[0] = ~key[0];
   		#(2*SYS_CLK);
	end
	key[0] = 1'b0;
	#(400*SYS_CLK);
	$stop;
end
key_debounce #(.TIME_20MS(TIME)) inst_key_bounce (
	.clk(clk), 
	.rst_n(rst_n), 
	.key(key), 
	.key_r(key_r));

key_led #(.TIME_0_2S(TIME)) inst_key_led (
	.clk(clk), 
	.rstn(rstn), 
	.key(key), 
	.led(led));


endmodule

四、仿真结果

在这里插入图片描述

五、总结

总的来说编写不算复杂,需要注意的是模块之间的连接和按键消抖模块

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/758278.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux中常见命令(1)

目录 1. less命令 2. cut 命令 3. head和tail命令 4. awk命令 5. tr命令 6. sed 命令 7. uniq 命令 1. less命令 用法&#xff1a;less [option]<filename>##同时打开多个文件 less <filename1> <filename2> <filename3> 点按“q”退出less。利…

再开源一款轻量内存池

前两天已开源线程池&#xff0c;开源一款轻量线程池项目&#xff0c;本节继续开源另一个孪生兄弟&#xff1a;内存池。 本节的线程池与内存池代码解析会在我的星球详细讲解。 内存池&#xff1a;https://github.com/Light-City/light-memory-pool 线程池&#xff1a;https://gi…

Vue-组件基础(上)

一、目标 能够说出什么是单页面应用程序和组件化开发能够说出.vue单文件组件的组成部分能够知道如何注册vue的组件能够知道如何声明组件的props属性能够知道如何在组件中进行样式绑定 二、目录 单页面应用程序vite的基本使用组件化开发思想vue组件的构成组件的基本使用封装组…

await、async、事件循环(宏任务、微任务队列执行顺序)

1 async、await 2 浏览器进程、线程 3 宏任务、微任务队列 4 Promise面试题解析 5 throw、try、catch、finally 异步函数-异步函数的写法 // 普通函数// function foo() {}// const bar function() {}// const baz () > {}// 生成器函数// function* foo() {}// 异步函…

效果超过deepsort,yolov5+bytetrack

目录 1. Motivation 2. BYTE 3. ByteTrack 4.完整代码实现 ByteTrack: Multi-Object Tracking by Associating Every Detection Box 沿着多目标跟踪&#xff08;MOT&#xff09;中tracking-by-detection的范式&#xff0c;我们提出了一种简单高效的数据关联方法BYTE。 利用…

git : 从入门到进阶(实战问题对策)

目录 0. 前言 1. git stash: 暂时保存本地修改 0. 前言 记录日常git使用过程中碰到的一些常见问题的解决&#xff0c;以及一些常用技巧。作为自己作为git使用者的从入门到进阶的成长过程。不求完备但求简洁实用。动态更新。。。 1. git stash: 暂时保存本地修改 多人工作的项…

Linux自主学习 - 多线程的创建(#include<pthread.h>)

备注&#xff1a;vscode通过ssh连接虚拟机中的ubuntu&#xff0c;ubuntu-20.04.3-desktop-amd64.iso 函数pthread_create() // pthread.h中的函数pthread_create()extern int pthread_create (pthread_t *__restrict __newthread, // 线程标识符const pthread_attr_t *…

【039】掌握Vector容器:C++中最强大的动态数组

掌握Vector容器&#xff1a;C中最强大的动态数组 引言一、vector容器概述二、vector的数据结构三、vector常用的API操作3.1、vector构造函数3.2、vector常用的赋值操作3.3、vector的大小操作3.4、vector存取数据操作3.5、vector插入和删除操作 四、vector的未雨绸缪机制五、巧用…

数据库应用:CentOS 7离线安装PostgreSQL

目录 一、理论 1.PostgreSQL 2.PostgreSQL离线安装 3.PostgreSQL初始化 4.PostgreSQL登录操作 二、实验 1.CentOS 7离线安装PostgreSQL 2.登录PostgreSQL 3.Navicat连接PostgreSQL 三、总结 一、理论 1.PostgreSQL &#xff08;1&#xff09;简介 PostgreSQL 是一个…

vue3 -- mitt 插件使用

介绍 mitt插件是Vue3中的一种第三方总线插件,它可以用于在组件之间进行通信。相比于Vue实例上的EventBus,mitt.js足够小,仅有200bytes,支持全部事件的监听和批量移除,它还不依赖Vue实例,所以可以跨框架使用,React或者Vue,甚至jQuery项目都能使用同一套库 . 使用 1:下载插…

Interactive Image Segmentation

Focused and Collaborative Feedback Integration for Interactive Image Segmentation CVPR 2023 清华 Interactive image segmentation aims at obtaining a segmentation mask for an image using simple user annotations. During each round of interaction, the segment…

windows打开此类文件前总是询问怎么解决

打开此类文件前总是询问怎么解决这个一直提示的问题呢&#xff1f; 下面来教大家一个方法杜绝再提示&#xff1a; 开始 --> 运行 --> gpedit.msc (组策略) --> 用户配置 --> 管理模板 --> windows组件 --> 附件管理器 --> 右击 "中等危险文件类型的包…

再学JavaScript

九、常见的运算符 两个等号只判断值&#xff0c;三个等号判断值和类型是否相等 逻辑运算符 注意&&和& ||和| 短路 赋值运算符 自加自减运算符 三目运算符 移位运算符 十、JavaScript的数据类型转换 假如用默认值10&#xff0c;控制台结果就是1035&#xff08…

学生管理系统--java+mysql

学生管理系统 简介 练习&#xff1a;完成学生信息的增删查改&#xff08;根据id&#xff09;&#xff0c;项目进行了三层架构进行创建。 pojo层&#xff0c;dao层&#xff0c;service层&#xff0c;utils层&#xff0c;程序入口&#xff1b; 1.pojo层 实体层 数据库在项目…

基于linux下的高并发服务器开发(第一章)- dup,dup2函数

int dup(int oldfd);复制文件描述符 /*#include <unistd.h>int dup(int oldfd);作用&#xff1a;复制一个新的文件描述符fd3, int fd1 dup(fd),fd指向的是a.txt, fd1也是指向a.txt从空闲的文件描述符表中找一个最小的&#xff0c;作为新的拷贝的文件描述符*/#include &…

80C51定时/计数器的应用之实现PWM(脉冲宽度调制)

知识来源于链接&#xff1a;https://www.bilibili.com/video/BV1eT4y1J7wB/?spm_id_from333.880.my_history.page.click&vd_sourceb91967c499b23106586d7aa35af46413 这种模拟实现 PWM 波的应用只能应用于对波形精度和频率要求不高的情况下。 一、程序思路分析 这里想要…

Redis缓存雪崩、穿透、击穿原因分析和解决方案,附Redis管道使用技巧

先给大家附上其他几篇文章&#xff0c;感兴趣的自行开车导航 Redis过期策略和持久化机制全面揭秘&#xff0c;教你如何合理配置 【深入浅出Redis 一】从版本特性到数据类型到线程模型&#xff0c;带你了解Redis的核心特性和应用场景&#xff01; 一次redis OOM问题分析解决&…

PyTorch深度学习——Anaconda和PyTorch安装

一、Anaconda安装 前言 安装anaconda后主要有一下3点好处&#xff1a; 1.包含环境管理器conda。 2.大量安装基于python的工具包。 3.可以创建使用和管理不同的python版本。 附上百度百科的解释&#xff1a; 下载步骤&#xff1a; 1.官网下载anaconda 2.双击之后安装即可 …

【Linux】进程间通信——管道与共享内存

文章目录 前言 1、三个问题1-1、什么是通信&#xff1f;1-2、为什么要有通信1-3、怎么进行通信&#xff1f;1-4、进程间通信分类 2、管道2-1、匿名管道2-1-1、理解通信本质问题2-1-2、进一步理解管道2-1-3、代码实现pipe函数 2-1-4、读写特征2-1-5、管道的特点&#xff08;重点…

MQTT springboot + idea

参考链接&#xff1a;&#xff08;第一个是理论 第二个是代码 我是直接cv的 我就不贴代码了&#xff09; MQTT协议基本流程、原理_mqtt协议工作原理_Nimrod__的博客-CSDN博客 SpringBoot整合MQTT_springboot mqtt_N_P_E的博客-CSDN博客 EMQX 入门教程③——默认端口、端口策…