登录 免费注册 首页 | 行业黑名单 | 帮助
维库电子市场网
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | EMC技术 | ARM技术 | EDA技术 | PCB技术 | 嵌入式系统
驱动编程 | 集成电路 | 器件替换 | 模拟技术 | 新手园地 | 单 片 机 | DSP技术 | MCU技术 | IC 设计 | IC 产业 | CAN-bus/DeviceNe

请教各位大师,关于CPLD扫描键盘去抖动的问题

作者:flyzslf 栏目:EDA技术
请教各位大师,关于CPLD扫描键盘去抖动的问题

请教各位大师,小弟才开始学习CPLD,可是写的第一个程序就遇到了一个非常棘手的问题:
      用CPLD扫描按键去抖动的问题,不知道怎么样用CPLD扫描按键。
比如说,在CPLD的一个脚上,接一个按键,我用always @ (posedge key)来读键,可是每按一次,CPLD都会有收到好几次的按键哦,我不知道用什么办法来去抖动哦。请高手指点,如果能帮我用verliog HDL 写一段小程序那就最好了,小弟在此先谢了。

或者发一段示例程序到小弟的邮箱:flyzs@126.com
小弟感激不尽。




2楼: >>参与讨论
dandynee
你用另外一个时钟做触发
注意延时去抖

3楼: >>参与讨论
flyzslf
谢谢!
谢谢!我想请问一下,这样做会不会浪费CPLD的资源,另外就是CPLD怎么延时呀?

4楼: >>参与讨论
luoqiang28
利用时钟的沿触发,可以用多个沿做多次判断
 
5楼: >>参与讨论
dandynee
不想浪费cpld资源对时钟分频
那可以用一个低速时钟,大概k级

6楼: >>参与讨论
flyzslf
什么是最常用的解决方案呢?
谢谢各位大师,给我提供了这么多的解决方案,那么什么办法才是实际中最为常用的解决方案呢?

也就是各位在平常设计中用的是什么办法呢?
请哪们能给小弟一个小小的例程,感激不尽!
我的邮箱是:flyzs@126.com

7楼: >>参与讨论
flyzslf
求教,顶一下
求教,顶一下

8楼: >>参与讨论
flyzslf
谢谢!我再试试,有问题再请教whfseu
谢谢!我再试试,有问题再请教whfseu

9楼: >>参与讨论
flyzslf
whfeu,有一个疑问
whfeu,有一个疑问
好像这个方法和采用一个比较慢的时钟来对键盘采样是一样的哦。

10楼: >>参与讨论
flyzslf
请教最常用的方法是什么?
请教最常用的方法是什么?

11楼: >>参与讨论
cationebox
我也请教
我也请教的
谢谢大家的赐教

12楼: >>参与讨论
xjg1111
可以这么做。


下面是我用来测试的源码,调试过的。用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


13楼: >>参与讨论
xjg1111
简单的解释一下!
本程序做的只是按键单纯挂在IO上,并不是行列扫描的。

其消抖原理:就是采用100hz作为键盘采样的时钟,

作一个8bit的reg,采用移位,当按键有效时,即8bit的reg全部为1时,进行动作。两次连续按键之间的时间间隔可以设定(这个是我根据按键感觉加进去的),

* - 本贴最后修改时间:2005-4-18 8:07:59 修改者:xjg1111

14楼: >>参与讨论
dandynee
.
//  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

            

15楼: >>参与讨论
flyzslf
谢谢各位大哥指点!
谢谢各位大哥指点!
小弟大恩感激不尽。。。。

flyzslf顿首!

参与讨论
昵称:
讨论内容:
 
 
相关帖子
用VHDL语言描述555电路 怎么做啊?
请教cpld中时钟信号来源
ISE5.2安装求助!!急
想用FPGA对图像进行预处理,方案应该如何设计?
我想利用时钟的上升和下降沿干事,是否可以这样判断?
免费注册为维库电子开发网会员,参与电子工程师社区讨论,点此进入


Copyright © 1998-2006 www.dzsc.com 浙ICP证030469号