繁体中文
设为首页
加入收藏

推荐文章

更多

07-14·[可控硅] 可控硅及其整流
07-14·[可控硅] 集成化六脉冲触发组件KCZ6电原理图
07-27·[单片机技术] PIC单片机16F84的内部硬件资源

 

最新文章

更多

· 基于FPGA的雷达脉冲压缩...
· 智能延迟触发产生器的设计
· 基于FPGA的机载合成孔径...
· 一种用CPLD实现视频信号...
· 实现PCB高效自动布线的设...
· 电子产品设计阶段的成本控制
· 线路板电镀槽的尺寸核算方法
· 基于FPGA的TCP粘合设计与...
· 基于CPLD的位同步时钟提...
· 基于MATLAB7.0软件的实...
当前位置:技术文章首页 >> 可编程逻辑 >> verilog的键盘源码keypad—有去抖功能

verilog的键盘源码keypad—有去抖功能

2008-03-30 16:50:31  作者:不详  来源:互联网  浏览次数:482  文字大小:【】【】【
verilog的键盘源码keypad—有去抖功能
  • 字体大小: 作者:     来源:     日期:2007-01-31     点击:644

下面是转的一个源码,俺没有细看,有兴趣的看看,讲讲如何
// author: Dandy Nee
// mail:   dandynee@yeah.net
// module: HW KeyScan Module
// version:0.1
// **************************
// all functions are provided as if okay
// run at your own risk
// **************************
//
// problem:   there is one keyvalue valid
//         indicator signal needed
//
//------------------------------------------------
//
//       ^ ^ ^ ^ Pull Up
//       | | | |
// x0 >--|--|--|--|-
// x1 >--|--|--|--|-
// x2 >--|--|--|--|-
// x3 >--|--|--|--|-
// y0 <--+ | | |
// y1 <-----+ | |
// y2 <--------+ |
// y3 <-----------+
//
module m_keyscan(
        clk,     //system clk
        rstb,     //system a-rst, low active
        //
        clkdiv,   //clock divide coef
        //
        keyvalue,   //returned key
        //
        x,       //x-row scan out
        y       //y-col scan in
        );

input     clk, rstb;
input   [19:0] clkdiv;
output [15:0] keyvalue;
output [3:0]   x;
input   [3:0]   y;

reg [19:0] cnt;
always @(posedge clk or negedge rstb)
if(~rstb)
  cnt<=0;
else
  cnt <= cnt==clkdiv ? 0 : cnt+1;

reg clken;
always @(posedge clk or negedge rstb)
if(~rstb)
  clken <= 0;
else
  clken <= cnt==clkdiv;

reg [2:0]   fsm;
always @(posedge clk or negedge rstb)
if(~rstb)
  fsm <= 0;
else if(clken)
  fsm <= fsm+1;   //8 states

reg [15:0] keyvalue;
reg [3:0]   x;
always @(posedge clk or negedge rstb)
if(~rstb)
  keyvalue <= 0;
else if(clken)
  case(fsm)
  0: begin
    x <= 4'b1110;
    end
  1: begin
    keyvalue[3:0] <= ~y;
    end
  2: begin
    x <= 4'b1101;
    end
  3: begin
    keyvalue[7:4] <= ~y;
    end
  4: begin
    x <= 4'b1011;
    end
  5: begin
    keyvalue[11:8] <= ~y;
    end
  6: begin
    x <= 4'b0111;
    end
  7: begin
    keyvalue[15:12] <= ~y;
    end
  endcase

endmodule


本程序做的只是按键单纯挂在IO上,并不是行列扫描的。

其消抖原理:就是采用100hz作为键盘采样的时钟,作一个8bit的reg,采用移位,当按键有效时,即8bit的reg全部为1时,进行动作。两次连续按键之间的时间间隔可以设定(这个是我根据按键感觉加进去的), 下面是我用来测试的源码,调试过的。用FPGA做的。

module key_delay
(
  // {{ALTERA_ARGS_BEGIN}} DO NOT REMOVE THIS LINE!
  clk, key_in, rst, led
  // {{ALTERA_ARGS_END}} DO NOT REMOVE THIS LINE!
);
// Port Declaration

  // {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE!
  input clk;
  input [1:0] key_in;
  input rst;
  output [3:0] led;
  // {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE!
reg [17:0] counter ;
reg [3:0] led ;
reg key_clk ;
always @(negedge rst or posedge clk)
if(!rst)
begin
  counter <= 0 ;
  key_clk <= 0 ;
end
else begin
  if(counter >= 250000) //分出用于键盘的时钟为100hz , 需要时钟速度较高时采用流水线
  begin
    counter <= 0;
    key_clk <= ~key_clk ;
  end
  else counter <= counter + 1 ;
end

reg [1:0] key_reg ; //提取分频后的键盘的时钟上升沿
always @(negedge rst or posedge clk)
if(!rst)
key_reg <= 0 ;
else key_reg <= {key_reg[0] ,key_clk } ;

wire key_all = &key_in ;
reg [7:0] shift_reg ;
reg [3:0] key_interval ;
always @(negedge rst or posedge clk)
if(!rst)
begin
  shift_reg <= 0 ;
  key_interval <='b_1111 ;
end
else begin
  if(key_reg == 2'b01)
  begin
    if(shift_reg == 8'b1111_1111) //一次有效的按键
    begin
        shift_reg <= 0 ;
        key_interval <= 0;
    end
    else
    begin
        if(key_interval =='b_1111 ) //连续按键的时间间隔(可根据需要修改)
        shift_reg <= {shift_reg[6:0] , (~key_all)} ;
        else key_interval <= key_interval + 1 ; //每次有效的按键后都要用计数器,计数等待。
    end
  end
end

always @(negedge rst or posedge clk) //用于测试按键的程序 ,通过LED移位来显示
if(!rst)
led <= 2'b01;
else
begin
  if(key_reg == 2'b01)
    begin
    if(shift_reg == 8'b1111_1111)
        begin
          case(key_in)
          2'b01: led <= {led[2:0] ,led[3]};
          2'b10: led <= {led[0] ,led[3:1]} ;
          default : led <= 4'bxxxx;
          endcase
        end
    end
end

endmodule

责任编辑:

启蒙电子http://www.51c51.net 启蒙电子网http://www.atc51.com 启蒙电子论坛
相关文章