您的位置:技术中心首页 > 硬件语言 >> Verilog HDL >> Verilog的键盘源码keypad—有去抖功能

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

作者:未知   时间:2007-09-29 11:28:50  来自:网上转载  浏览次数:0  文字大小:【】【】【

下面是转的一个源码,俺没有细看,有兴趣的看看,讲讲如何
// 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

责任编辑:5life

更多相关 Verilog 键盘 的文章

Verilog 脉冲发生器程序 [2007-09-29]
Verilog 电梯控制器设计 [2007-09-29]
Verilog学习心得 [2007-09-29]
Verilog交通灯控制器程序 [2007-09-29]
一种基于移位寄存器的CAM的Verilog HDL实现 [2007-09-29]
SPI串行总线接口的Verilog实现 [2007-09-29]
Verilog HDL代码描述对状态机综合的研究 [2007-09-29]
SDRAM控制器软核的Verilog设计 [2007-09-29]
Verilog语言综合问题研究 [2007-09-29]
仿真工作流程(Verilog/Modelsim+Debussy) [2007-05-14]
本文共有0条评论,现在显示最新的5条。

栏目导航

电路基础
硬件语言
逻辑验证
电路综合
后端设计
可测设计
基本逻辑
制造工艺
书籍精选
说文解字
工具学习
数字滤波
趣闻逸事
数字锁相
设计杂项
低耗设计

站点最新

更多相关链接

  Verilog的键盘源码keypa...
  Verilog 脉冲发生器程序
  Verilog 电梯控制器设计
  Verilog学习心得
  Verilog交通灯控制器程序
  一种基于移位寄存器的CA...
  SPI串行总线接口的Veril...
  Verilog HDL代码描述对状...
  SDRAM控制器软核的Veril...
  Verilog语言综合问题研究

栏目最新

更多相关链接

  Verilog的键盘源码keypa...
  Verilog 脉冲发生器程序
  Verilog 电梯控制器设计
  Verilog学习心得
  Verilog交通灯控制器程序
  一种基于移位寄存器的CA...
  SPI串行总线接口的Veril...
  Verilog HDL代码描述对状...
  SDRAM控制器软核的Veril...
  Verilog语言综合问题研究

热点文章

更多相关链接

  中文版Verilog HDL简明教程
  Verilog HDL的基础知识
  Verilog学习笔记(More)
  Verilog 的些许经验
  verilog HDL笔记
  Verilog设计经验点滴
  阻塞式赋值与非阻塞式赋值
  硬件描述语言(HDL)的基础知识...
  SDRAM控制器软核的Verilog设计
  一种基于移位寄存器的CAM的V...