首页 > 其他分享 >FPGA开发——按键控制LED的实现

FPGA开发——按键控制LED的实现

时间:2024-07-31 20:26:48浏览次数:13  
标签:LED FPGA clk key 按键 rst input led

一、概述

在上一篇文章中我们学习了按键的相关消抖及其使用,在这篇文章当中我们就针对通过按键实现LED的控制。

1、按键原理图

2、基本框架

通过我们前面编写的按键消抖的文件和LED文件将按键和LED两个模块进行交互,从而达到按键控制LED的目的。

 二、代码编写

1、首先是按键相关设计文件的编写,新建key.v,如下:

//状态机实现
module key (
    input           clk     ,
    input           rst_n   ,
    input           key_in  ,   //输入原始的按键信号
    output  reg     key_out     //输出处理之后的按键信号
);
//参数定义
    localparam  IDLE        = 4'b0001,//空闲
                JITTLE0     = 4'b0010,//滤除第一次抖动
                DOWN        = 4'b0100,//稳定
                JITTLE1     = 4'b1000;//滤除第二次抖动

    parameter   TIME_20MS = 1_000_000;//需要计数的值,20ms

//内部信号
    reg  [3:0]   state_c;//现态
    reg  [3:0]   state_n;//次态

    reg  [19:0] cnt_20ms;//计数20ms
    wire        add_cnt_20ms;
    wire        end_cnt_20ms;

    wire        nedge   ;//下降沿信号
    wire        pedge   ;//上升沿信号
    reg         key_in_r1  ;//  同步打拍



//状态转移 同步时序逻辑描述状态转移
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)
            state_c <= IDLE;
        else
            state_c <= state_n;
    end

//状态转移条件 组合逻辑
    always @(*) begin
        case (state_c)//一定是case  现态
            IDLE:begin
                if(nedge)
                    state_n = JITTLE0;
                else
                    state_n = state_c;
            end
            JITTLE0:begin
                if(end_cnt_20ms)
                    state_n = DOWN;
                else
                    state_n = state_c; 
            end
            DOWN:begin
                if(pedge)
                    state_n = JITTLE1;
                else
                    state_n = state_c;
            end
            JITTLE1  :begin
                if(end_cnt_20ms)
                    state_n = IDLE;
                else
                    state_n = state_c;  
            end   
            default: state_n = IDLE;
        endcase
    end

//20ms计数器
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        cnt_20ms <= 0;
    else if(add_cnt_20ms)begin
        if(end_cnt_20ms)
            cnt_20ms <= 0;
        else
            cnt_20ms <= cnt_20ms + 1;
    end
end

assign add_cnt_20ms = (state_c == JITTLE0) || (state_c == JITTLE1);
assign end_cnt_20ms = add_cnt_20ms && cnt_20ms == TIME_20MS - 1;

//下降沿  上升沿
//同步  打拍
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        key_in_r1 <= 2'b11;
       
    end 
    else begin 
        key_in_r1 <= key_in;      //同步按键输入信号
         
    end 
end
    //r1当前状态
assign nedge = ~key_in_r1 && key_in;
assign pedge = key_in_r1 && ~key_in;

//key_out
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)
            key_out <= 0;
        else if(end_cnt_20ms &&(state_c== JITTLE1))
            key_out <= ~key_in_r1;//有效脉冲 20ns
        else 
            key_out <= 0;
    end

endmodule

2、LED相关设计文件编写

新建led_ctrl.v文件

module led_ctrl(
    input               clk         ,
    input               rst_n       ,
    input          key_flag    ,//输入原始的按键信号
    output  reg    led     //输出处理之后的按键信号
);
always @(posedge clk or negedge rst_n )begin
    if(!rst_n)
        led<=1'b0;
    else if(key_flag)
        led<=~led;
end
endmodule

3、顶层文件编写

在顶层文件中,使用一个中间变量key_out将按键中的输出赋值给LED模块中的按键标志位输入key_flag。

module top(
    input  clk,
    input  rst_n,
    input  key_in,
    output  led

);
wire   key_out;
key key_inst(
    /*input          */ .clk     (clk   ),
    /*input          */ .rst_n   (rst_n ),
    /*input          */ .key_in  (key_in),   //输入原始的按键信号
    /*output  reg    */ .key_out (key_out)    //输出处理之后的按键信号
);

led_ctrl led_inst(
    /*input          */ .clk     (clk   ),
    /*input          */ .rst_n   (rst_n ),
    /*input          */ .led     (led),   //输入原始的按键信号
    /*output  reg    */ .key_flag (key_out)    //输出处理之后的按键信号
);
endmodule

4、测试文件编写

`timescale 1ns/1ns

module top_tb ;

    reg         clk    ;
    reg         rst_n  ;
    reg         key_in ;
    wire        led    ;

defparam top_inst.key_inst.TIME_20MS = 1000;

top top_inst(
    .clk            (clk        ),
    .rst_n          (rst_n      ),
    .key_in         (key_in     ),   //输入原始的按键信号
    .led            (led    )    //输出处理之后的按键信号
);
//激励信号产生
parameter CLK_CLY = 20;
//时钟
initial clk=1;
always #(CLK_CLY/2)clk=~clk;

//复位
initial begin
    rst_n= 1'b0;
    #(CLK_CLY*3);
    #5;//复位结束避开时钟上升沿
    rst_n= 1'b1;
end

//激励
integer i;
initial repeat(5)begin
    key_in = 1;//模拟按键未按下
    i ={$random}%6;//给i赋值0-5
    #(CLK_CLY*500);//等待复位时间结束
    #3;
    repeat (3)begin 
        key_in = 0;//前按键抖动开始
        #(CLK_CLY*1);
        //一个5-10ms的抖动时间
        repeat ((i+5)*50)begin
            key_in = $random;
            #(CLK_CLY*1);
        end 
        key_in = 0;//按键稳定
        #(CLK_CLY*100*50);

        //后抖动开始
        key_in = 1;
        #(CLK_CLY*1);
        repeat ((i+5)*50)begin
            key_in = $random;
            #(CLK_CLY*1);
        end 
        key_in = 1;//按键稳定
        #(CLK_CLY*10*500);
    end
    
    //模拟意外抖动
    repeat (3)begin 
        repeat ((i+5)*50)begin
            key_in = $random;
            #(CLK_CLY*1);
        end 
        key_in = 1;//按键稳定
        #(CLK_CLY*500);

    end 
    $stop;
end
endmodule

三、仿真波形图

通过波形图我们可以看见当按键按下一次,LED状态切换一次,实现了按键控制LED的功能实现。 

标签:LED,FPGA,clk,key,按键,rst,input,led
From: https://blog.csdn.net/weixin_63553972/article/details/140763172

相关文章

  • FPGA开发——数码管的使用(二)
    一、概述   在上一篇文章中我们针对单个数码管的静态显示和动态显示进行了一个设计和实现,这篇文章中我们针对多个数码管同时显示进行一个设计。这里和上一篇文章唯一不同的是就是数码管位选进行了一个改变,原来是单个数码管的显示,所以位选就直接赋值就可以了,但在本篇文章......
  • FPGA开发——按键控制数码管的设计
    一、概述按键控制数码管是一种常见的电子显示技术,它结合了按键输入与数码管显示的功能。在这一设计中,用户通过按下不同的按键来发送指令,这些指令随后被处理并转换为数码管上显示的数字或字符。按键通常作为输入设备,通过电路连接到微控制器(如FPGA、单片机等)的输入引脚,而数码管......
  • [米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-26 RS485串口程序收发环路设计
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 1概述在前面的课程中,我......
  • [米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-25 ADC模块FEP-DAQ9248采集显示波形方案
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 1概述本方案通过把DAQ9......
  • [米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-23 RGB转HDMI显示方案
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 1概述本实验通过FPGA内......
  • [米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-24 基于FPGA简易示波器显示驱动设计
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 1概述FPGA在数据采集,数据处理......
  • [米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-22 TPG图像测试数据发生器设计
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 1概述TPG(video_test_pa......
  • [米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-21 VTC视频时序控制器设计
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 1概述VideoTimingCont......
  • P1.53和P1.86的LED显示屏什么区别
    我们的夏游记有些客户在采购LED显示屏时,对点间距或其它的参数不是很了解,如P1.53和P1.86之间有什么区别,选择哪一款性价高更高呢?业角度为大家分析,希望能对大家提供到一些帮助。目前,LED显示屏在室内场合的应用中,P1.53和P1.86是应用比较广泛的两款小间距LED系列,它们在分辨率......
  • led显示屏p2和p2.5区别,看完你就知道【深圳播报】
    L2024LPL春季赛led显示屏p2和p2.5区别,LED显示屏作为现代信息显示的重要工具,其规格和性能对于用户体验至关重要。在LED显示屏的规格中,P2和P2.5是两个常见的像素间距标准。虽然它们只有微小的数值差异,但在实际应用中,两者却存在显著的差异。下面跟着迈普光彩小编一起来看看吧......