FPGA学习——按键控制LED流水灯(附源码 无按键消抖版本)

文章目录

  • 一、前言
  • 二、开发板按键原理图
  • 三、源码
  • 四、实现效果

一、前言

在博主的cyclone4开发板上一共有4个按键,本次实验的目的是为了实现每按下一次按键,都会使开发板上的4个LED灯切换一次状态,博主一共设计了四种状态,分别是:

按键 状态
按键1按下 自右向左的流水灯
按键2按下 自左向右的流水灯
按键3按下 四灯常亮
按键4按下 四灯闪烁

二、开发板按键原理图

FPGA学习——按键控制LED流水灯(附源码 无按键消抖版本)_第1张图片

  • 由原理图可以看出,开发板按键按下代表低电平

三、源码

在源码中博主设计了一个0.2s的计数器和两位的cstate状态寄存器,用来控制LED的状态及流水灯闪烁。同时可以看出博主设计了一个flag寄存器,由于本次实验未添加按键消抖模块,因此按键按下后需要一直按住才能实现效果,而引入flag后,我们便可以通过按键按下后一瞬间的电平改变从而改变flag的状态,再由flag的状态控制LED的状态,以此算是一种无按键消抖的平替。

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

    output  reg     [3:0]   led
);
    parameter MAX = 10_000_000;
    reg [23:0]  cnt;
    reg [1:0]   cstate;
    reg [3:0]   flag;

//0.2s计数器
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)begin
            cnt <= 1'b0;
        end
        else if(cnt == MAX - 1'b1)begin
            cnt <= 1'b0;
        end
        else begin
            cnt <= cnt + 1'b1;
        end
    end

//状态控制 之所以不需要在状态计满后清零,是因为后续在计数至11后再加1值来到100
//而我们的状态设置为两位寄存器,因此只取后两位变为00,相当于清零
    always @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cstate <= 2'd0;
        end
        else if(cnt == MAX - 1'b1)begin
            cstate <= cstate + 1'b1;
        end
        else begin
            cstate <= cstate;
        end
    end
//根据按键状态改变flag状态
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            flag <= 4'b0000;
        end
        else if(key[0] == 1'b0)begin
            flag <= 4'b0001;
        end
        else if(key[1] == 1'b0)begin
            flag <= 4'b0010;
        end
        else if(key[2] == 1'b0)begin
            flag <= 4'b0100;
        end
        else if(key[3] == 1'b0)begin
            flag <= 4'b1000;
        end
        else begin
            flag <= flag;
        end
    end
//根据flag状态改变led状态
    always @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            led <= 4'b0000;
        end
        else if(flag == 4'b0001)begin
            case (cstate)
               2'd0 : led <= 4'b0001;
               2'd1 : led <= 4'b0010;
               2'd2 : led <= 4'b0100;
               2'd3 : led <= 4'b1000;
                default: led <= 4'b0000;
            endcase
        end
        else if(flag == 4'b0010)begin
            case (cstate)
               2'd0 : led <= 4'b1000;
               2'd1 : led <= 4'b0100;
               2'd2 : led <= 4'b0010;
               2'd3 : led <= 4'b0001;
                default: led <= 4'b0000;
            endcase
        end
        else if(flag == 4'b0100)begin
            case (cstate)
               2'd0 : led <= 4'b1111;
               2'd1 : led <= 4'b0000;
               2'd2 : led <= 4'b1111;
               2'd3 : led <= 4'b0000;
                default: led <= 4'b0000;
            endcase
        end
        else if(flag == 4'b1000)begin
            case (cstate)
               2'd0 : led <= 4'b1111;
               2'd1 : led <= 4'b1111;
               2'd2 : led <= 4'b1111;
               2'd3 : led <= 4'b1111;
                default: led <= 4'b0000;
            endcase
        end
        else begin
            led <= 4'b0000;
        end
    end

endmodule

四、实现效果

你可能感兴趣的:(fpga开发,学习)