注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
jiajie270的个人空间 https://home.eeworld.com.cn/space-uid-422029.html [收藏] [复制] [分享] [RSS]
日志

按键消抖程序

已有 1237 次阅读2017-5-5 18:37 |个人分类:FPGA| false

//在学习Verilog 按键消抖的时候,花费了很多时间来理解这个过程。下面是根据自己的理解,写的一个按键消抖的程序。一开始写的时候,没有定义key_s_r寄存器,想着利用key_skey_s_n取亦或来判断是否有按键变化,但是key_s_n只有在计时满20ms时才等于key_in,而不是按键变化后开始计时,所以出现错误。而判断哪一路按键发生变化,用的是将key_skey_s_n取合集,观察每一位的变化来判断是哪一个按键发生变化,以及是发生H2L还是L2H的变化。

module test_key1(rst,clk,led_out,key_in);

 

input rst;

input clk;

input [3:0]key_in;

output reg  [3:0]led_out;

 

parameter T20MS=21'd1_000_000;                 //20ms,用于延时消抖

 

reg  [3:0]key_s;

reg  [3:0]key_s_n;

reg  [3:0]key_s_r;

reg  [20:0]timer;

wire [3:0]key_s_or;

 

//按键消抖

always @ (posedge clk or negedge rst)          //key_in寄存于key_s_r用于判断按键是否发生变化

begin

         if(!rst)

                   key_s_r<=4'b1111;

         else

                   key_s_r<=key_in;

end

 

always @ (posedge clk or negedge rst)

begin

         if(!rst)

                   begin

                            key_s<=4'b1111;

                   end

         else

                   key_s<=key_s_n;

end

 

always @ (*)

begin

         if(!rst)

                   begin

                            key_s_n<=4'b1111;

                   end

         else

                   if(timer==T20MS)

                            key_s_n<=key_s_r;

                   else

                            key_s_n<=key_s;

end

 

wire [7:0]judge;

assign  judge={key_s,key_s_n};              //用于判断是哪一个按键发生变化

assign key_s_or=key_s_r^key_in;            //检测是否有按键发生变化

 

always @ (posedge clk or negedge rst)

begin

         if(!rst)

                   timer<=21'd0;

         else if(timer==T20MS||key_s_or)           //判断时间有没有到、是否有按键变化

                                     begin

                                               timer<=21'd0;

                                     end

                            else

                                     timer<=timer+1'b1;

end

 

//led 控制

always @ (posedge clk or negedge rst)

begin

         if(!rst)

                   led_out<=4'b0000;

         else case(judge)       //根据判断出的按键变化,实现功能

                            8'b11111110:led_out[0]<=~led_out[0];

                            8'b11111101:led_out[1]<=~led_out[1];

                            8'b11111011:led_out[2]<=~led_out[2];

                            8'b11110111:led_out[3]<=~led_out[3];

                            default:led_out<=led_out;

                            endcase

end

 

endmodule

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章