状态机的练习:按键控制led灯

文章详细描述了一个设计,使用状态机控制LED输出,通过按键消抖处理后,通过流水灯、跑马灯和闪烁模块生成信号,然后在state_led_ctrl模块中进行LED输出控制。代码展示了按键消抖逻辑和LED状态切换的计数器实现。

设计思路:

三个按键控制led输出。

三个按键经过滤波(消抖),产生三个按键标志信号。

三个led数据的产生模块(流水,跑马,闪烁模块),分别产生led信号。

这六路信号(三路按键信号,三路led信号),接入state_led_ctrl模块,进行led_out的控制。

状态机:

 

模块框图:

代码:

/*
    1位按键消抖
*/ 
module key_filter (
    input       wire            sys_clk     ,
    input       wire            sys_rst_n   ,
    input       wire            key_in      ,

    output      reg             key_flag    
);
    // 参数定义
    parameter   MAX_CNT_10MS = 500_000   ;
    localparam  IDLE         = 4'b0001   ,
                FILTER_UP    = 4'b0010   ,
                SAMPLING     = 4'b0100   ,
                FILTER_BACK  = 4'b1000   ;
    // reg signal define 
    reg                 key_in_r1 ;  
    reg                 key_in_r2 ;
    reg     [18:0]      cnt_core  ;
    reg     [3:0]       state_c   ;
    reg     [3:0]       state_n   ;
    // wire signal define 
    wire                nege                  ;
    wire                pose                  ;
    wire                IDLEtoFILTER_UP       ;
    wire                FILTER_UPtoIDLE       ;
    wire                FILTER_UPtoSAMPLING   ;
    wire                SAMPLINGtoFILTER_BACK ;
    wire                FILTER_BACKtoIDLE     ;
    wire                filter_done           ; 
    /******************************************************************/
    // reg                 key_in_r1 ; 
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            key_in_r1 <= 1'b1 ;
        else
            key_in_r1 <= key_in ;
    end 
    // reg                 key_in_r2 ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            key_in_r2 <= 1'b1 ;
        else
            key_in_r2 <= key_in_r1 ;
    end 
    // wire                nege      ;
    assign  nege = ~key_in_r1 &&  key_in_r2 ;
    // wire                pose      ;  
    assign  pose =  key_in_r1 && ~key_in_r2 ;
    // reg     [3:0]       state_c   ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            state_c <= IDLE ;
        else
            state_c <= state_n ;
    end
    // reg     [3:0]       state_n   ;
    always @(*) begin
        case(state_c)
        IDLE      : if(IDLEtoFILTER_UP)
                        state_n = FILTER_UP ;
                    else 
                        state_n = IDLE ;
        FILTER_UP : if(FILTER_UPtoIDLE)
                        state_n = IDLE ;
                    else if(FILTER_UPtoSAMPLING)
                        state_n = SAMPLING ;
                    else 
                        state_n = FILTER_UP ;
        SAMPLING  : if(SAMPLINGtoFILTER_BACK)
                        state_n = FILTER_BACK ;
                    else 
                        state_n = SAMPLING ;
        FILTER_BACK:if(FILTER_BACKtoIDLE)
                        state_n = IDLE ;
                    else
                        state_n = FILTER_BACK ;
        default   :     state_n = IDLE ;
        endcase
    end
    assign  IDLEtoFILTER_UP         = (state_c == IDLE)       && (nege) ;
    assign  FILTER_UPtoIDLE         = (state_c == FILTER_UP)  && (pose) ;
    assign  FILTER_UPtoSAMPLING     = (state_c == FILTER_UP)  && (filter_done) ;
    assign  SAMPLINGtoFILTER_BACK   = (state_c == SAMPLING)   && (pose) ;
    assign  FILTER_BACKtoIDLE       = (state_c == FILTER_BACK)&& (filter_done) ;
    // reg     [18:0]      cnt_core  ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            cnt_core <= 19'd0 ;
        else
        case (state_c)
        IDLE       :cnt_core <= 19'd0 ; 
      
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值