|
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | EMC技术 | ARM技术 | EDA技术 | PCB技术 | 嵌入式系统 驱动编程 | 集成电路 | 器件替换 | 模拟技术 | 新手园地 | 单 片 机 | DSP技术 | MCU技术 | IC 设计 | IC 产业 | CAN-bus/DeviceNe |
请教各位大师,关于CPLD扫描键盘去抖动的问题 |
作者:flyzslf 栏目:EDA技术 |
请教各位大师,小弟才开始学习CPLD,可是写的第一个程序就遇到了一个非常棘手的问题: 用CPLD扫描按键去抖动的问题,不知道怎么样用CPLD扫描按键。 比如说,在CPLD的一个脚上,接一个按键,我用always @ (posedge key)来读键,可是每按一次,CPLD都会有收到好几次的按键哦,我不知道用什么办法来去抖动哦。请高手指点,如果能帮我用verliog HDL 写一段小程序那就最好了,小弟在此先谢了。 或者发一段示例程序到小弟的邮箱:flyzs@126.com 小弟感激不尽。 |
2楼: | >>参与讨论 |
作者: dandynee 于 2005/4/13 13:07:00 发布:
你用另外一个时钟做触发 注意延时去抖 |
3楼: | >>参与讨论 |
作者: flyzslf 于 2005/4/13 17:01:00 发布:
谢谢! 谢谢!我想请问一下,这样做会不会浪费CPLD的资源,另外就是CPLD怎么延时呀? |
4楼: | >>参与讨论 |
作者: luoqiang28 于 2005/4/14 11:26:00 发布:
利用时钟的沿触发,可以用多个沿做多次判断 |
5楼: | >>参与讨论 |
作者: dandynee 于 2005/4/14 11:43:00 发布:
不想浪费cpld资源对时钟分频 那可以用一个低速时钟,大概k级 |
6楼: | >>参与讨论 |
作者: flyzslf 于 2005/4/14 17:48:00 发布:
什么是最常用的解决方案呢? 谢谢各位大师,给我提供了这么多的解决方案,那么什么办法才是实际中最为常用的解决方案呢? 也就是各位在平常设计中用的是什么办法呢? 请哪们能给小弟一个小小的例程,感激不尽! 我的邮箱是:flyzs@126.com |
7楼: | >>参与讨论 |
作者: flyzslf 于 2005/4/15 9:36:00 发布:
求教,顶一下 求教,顶一下 |
8楼: | >>参与讨论 |
作者: flyzslf 于 2005/4/15 18:32:00 发布:
谢谢!我再试试,有问题再请教whfseu 谢谢!我再试试,有问题再请教whfseu |
9楼: | >>参与讨论 |
作者: flyzslf 于 2005/4/15 18:35:00 发布:
whfeu,有一个疑问 whfeu,有一个疑问 好像这个方法和采用一个比较慢的时钟来对键盘采样是一样的哦。 |
10楼: | >>参与讨论 |
作者: flyzslf 于 2005/4/16 10:20:00 发布:
请教最常用的方法是什么? 请教最常用的方法是什么? |
11楼: | >>参与讨论 |
作者: cationebox 于 2005/4/16 15:51:00 发布:
我也请教 我也请教的 谢谢大家的赐教 |
12楼: | >>参与讨论 |
作者: xjg1111 于 2005/4/16 18:39:00 发布:
可以这么做。 下面是我用来测试的源码,调试过的。用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 于 2005/4/17 18:19:00 发布:
简单的解释一下! 本程序做的只是按键单纯挂在IO上,并不是行列扫描的。 其消抖原理:就是采用100hz作为键盘采样的时钟, 作一个8bit的reg,采用移位,当按键有效时,即8bit的reg全部为1时,进行动作。两次连续按键之间的时间间隔可以设定(这个是我根据按键感觉加进去的), * - 本贴最后修改时间:2005-4-18 8:07:59 修改者:xjg1111 |
14楼: | >>参与讨论 |
作者: dandynee 于 2005/4/17 21:35:00 发布:
. // 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 于 2005/4/18 15:50:00 发布:
谢谢各位大哥指点! 谢谢各位大哥指点! 小弟大恩感激不尽。。。。 flyzslf顿首! |
|
|
免费注册为维库电子开发网会员,参与电子工程师社区讨论,点此进入 |
Copyright © 1998-2006 www.dzsc.com 浙ICP证030469号 |