STM_FPGA 发表于 2010-8-3 15:42:33

4*4矩阵键盘的verilog程序与独立按键的消抖程序,希望做一点点贡献,准备继续深入学习..

4*4矩阵键盘(未消抖):
module Matrix_keyboard(clk,in_s,out_s,num);
//定义模块端口信息
input          clk;
input   in_s;
outputout_s;
outputnum;
//定义输出信号类型及局部变量
reg   num;
reg   cnt = 0;
reg   tmp = 0;
reg   o_ut_st = 0;
wire    dsample;
//将扫描输出和输入信号级联,得到矩阵扫描结果
assigndsample = {o_ut_st, in_s};
assignout_s   = o_ut_st;
//产生按钮矩阵的列扫描信号
always@(posedge clk)
   begin
       cnt <= cnt + 1'b1;
       case (cnt)
          2'b00:   o_ut_st <= 4'b1000;
          2'b01:   o_ut_st <= 4'b0100;
          2'b10:   o_ut_st <= 4'b0010;
          2'b11:   o_ut_st <= 4'b0001;         
       endcase
   end
//根据按钮的列扫描信号和行输入信号判断按钮是否被按下
always@(posedge clk)
   begin
      //如果无按钮按下,定义num=16为无效状态
      if (in_s == 4'b0000)
      begin
         if (tmp == 3)
             begin
                num <= 16;//无按键输入,输出16
                tmp <= 0;
             end
         else
             begin
                num <= num;
                tmp <= tmp + 1'b1;//扫描周期,3个时钟周期
             end
      end
      else
      begin
         tmp <= 0;
         case (dsample)
             //第1列扫描结果
             8'b1000_0001: num <= 0;
             8'b1000_0010: num <= 1;
             8'b1000_0100: num <= 2;
             8'b1000_1000: num <= 3;
             //第2列扫描结果
             8'b0100_0001: num <= 4;
             8'b0100_0010: num <= 5;
             8'b0100_0100: num <= 6;
             8'b0100_1000: num <= 7;
             //第3列扫描结果
             8'b0010_0001: num <= 8;
             8'b0010_0010: num <= 9;
             8'b0010_0100: num <= 10;
             8'b0010_1000: num <= 11;
             //第4列扫描结果
             8'b0001_0001: num <= 12;
             8'b0001_0010: num <= 13;
             8'b0001_0100: num <= 14;
             8'b0001_1000: num <= 15;
         endcase
      end
   end
endmodule   

独立按键消抖程序:
module Btn_without_shake(Clk_50MHz,PB_UP,PB_Out,count_sel);
//定义模块端口信息
input   Clk_50MHz;//模块时钟50MHz
input   PB_UP;//按钮输入
output    PB_Out;//去抖后按钮输出
output    count_sel;//计数器输出
//定义输出信号类型及局部变量
reg    count_high = 0;//按钮输入高电平计数器
reg    count_low = 0;//按钮输入低电平计数器
reg   PB_reg = 0;
reg    count_sel_reg = 0;
//输出赋值
assign   PB_Out = PB_reg;
assign   count_sel = count_sel_reg;
//对输入进行采样,计数
always @(posedge Clk_50MHz)
   if(PB_UP == 1'b0)
      count_low <= count_low + 1'b1;
   else
      count_low <= 20'h0_0000;
always @(posedge Clk_50MHz)
   if(PB_UP == 1'b1)
      count_high <= count_high + 1'b1;
   else
      count_high <= 20'h0_0000;
//防抖输出
always @(posedge Clk_50MHz)
   if(count_high == 20'h7_FFFF)//判断高电平信号是否符合输出条件10ms
      PB_reg <= 1'b1;//如果符合条件,则防抖输出高电平
   else
      if(count_low == 20'h7_FFFF)//判断低电平信号是否符合输出条件10ms
         PB_reg <= 1'b0;//如果符合条件,则防抖输出低电平
      else
         PB_reg <= PB_reg;
//使用去抖输出PB_reg控制count_sel计数
always @(posedge PB_reg)
   count_sel_reg <= count_sel_reg + 1'b1;
endmodule
初学,参考书上的《Verilog HDL程序设计与实践》,准备用状态机做一下矩阵键盘,恩,坛子里也有,不过还是自己尝试一下,坛里老牛很多呀!

mafei881028 发表于 2010-8-7 11:48:13

哈哈哈哈

yuri99q 发表于 2010-8-9 23:11:30

初学的我,只会,用3个D触发器,来完成独立按键防抖~!

ringan865 发表于 2010-8-10 11:22:13

mark,喜欢楼主的编成风格

lyeerr 发表于 2010-12-16 21:21:41

请问楼主,在每个clk到来之时,列扫描信号发生转移,但是与此同时行信号也进行读入时序,会不会出现行信号读入的值是在前一次列信号产生的行信号值,也就是按键对应不上的情况啊

hbchf 发表于 2011-1-7 13:42:23

http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_609637LXJGOJ.JPG
第一的模块仿真时序 (原文件名:44_key.JPG)
本人感觉按下一个键后,该键的同一列都被选中了。
页: [1]
查看完整版本: 4*4矩阵键盘的verilog程序与独立按键的消抖程序,希望做一点点贡献,准备继续深入学习..