ZYNQ学习之按键消抖

可紊 提交于 2019-12-17 05:49:50

参考链接:米联客教程:https://blog.csdn.net/jinry001/article/details/9969498

按键消抖子程序:

module key #
(
    parameter CLK_FREQ = 100000000
)
(
input clk_i,
input key_i,
output key_cap
);

//10ms,100MHz时钟对应计数值,1/100_000_000*val=10*10^-3
parameter CNT_10MS = (CLK_FREQ/100 - 1'b1);

parameter KEY_S0 = 2'd0;
parameter KEY_S1 = 2'd1;
parameter KEY_S2 = 2'd2;
parameter KEY_S3 = 2'd3;

reg [24:0] cnt10ms = 25'd0;
reg [1:0] key_s = 2'b0;
 reg [1:0] key_s_r = 2'b0;
 wire en_10ms ;
//产生10ms计数时钟
assign en_10ms = (cnt10ms == CNT_10MS);
//按键按下的检测逻辑,
assign key_cap = (key_s==KEY_S2)&&(key_s_r==KEY_S1);

always @(posedge clk_i)begin   //计数10ms
    if(cnt10ms < CNT_10MS)
        cnt10ms <= cnt10ms + 1'b1;
    else
        cnt10ms <= 25'd0;
end

always @(posedge clk_i)begin   //key_s_r相对key_s延迟一个时钟,决定检测逻辑的写法
    key_s_r <= key_s;
end
//消抖状态机,实质是在en_10ms计数时钟下的状态转移
always @(posedge clk_i)
begin
    if(en_10ms)
        begin
        case(key_s)
        KEY_S0:
            begin
               if(!key_i)
                   key_s <= KEY_S1;
            end  
        KEY_S1:
            begin
               if(!key_i)
                  key_s <= KEY_S2;
              else
                   key_s <= KEY_S0;
            end
        KEY_S2:
            begin
               if(key_i)
                   key_s <= KEY_S3;
            end  
        KEY_S3:
            begin
               if(key_i)
                  key_s <= KEY_S0;
                else   
                  key_s <= KEY_S2;
            end
        endcase                  
    end
end

endmodule

顶层程序,点亮LED灯。

module Key_debounce(
input clk_i,
input rst_n_i,
input key_i,
output [3:0] led
);
 reg [3:0] led;
 wire key_cap;

always @(posedge clk_i)begin
    if(!rst_n_i)begin
        led <= 4'b0000;
    end
   else if(key_cap)begin
        led <= ~led;  
    end
end

key#
(
.CLK_FREQ(100000000)
)
key0
(
.clk_i(clk_i),
.key_i(key_i),
.key_cap(key_cap)
);
endmodule

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!