在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 5960|回复: 12

[求助] 有关特权同学verilog 按键消抖从按下到弹上的问题

[复制链接]
发表于 2013-7-12 18:05:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
特权同学的键盘消抖是利用按键在从1-0变化时产生的一个周期的高脉冲实现的,但是当按键从按下到弹上时,按键是从0-1变化,那么也就是说按键弹上,LED的信号不会发生反转,即灯不会变灭,但是实际情况是会变灭的,这个是如何实现的,求指导,谢谢。代码如下:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date:    17:10:39 07/11/2013
// Design Name:
// Module Name:    KEY_PAN
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//说明:当三个独立按键的某一个被按下后,相应的LED灯被点亮,
//再次按下后,LED灯熄灭
//////////////////////////////////////////////////////////////////////////////////
module KEY_PAN(

clk,

rst_n,

sw1_n,sw2_n,sw3_n,

led_d1,led_d2,led_d3
    );


input clk;      
   
//时钟信号
input rst_n;     
   //复位信号,低有效
input sw1_n,sw2_n,sw3_n;   
//三个独立按键,低表示按下
output led_d1,led_d2,led_d3;  //发光二极管,分别由按键控制
////---------------------------------------------------------

reg[2:0] key_rst;



always @(posedge clk or negedge rst_n)


if(!rst_n) key_rst <= 3'b111;

else

begin

key_rst <= {sw1_n,sw2_n,sw3_n};

//
key_rst_r <= key_rst;

end
reg[2:0] key_rst_r;
//每个时钟周期上升沿将key_rst锁存至key_rst_r

always @(posedge clk or negedge rst_n)

if(!rst_n)key_rst_r<=3'b111;

else key_rst_r <= key_rst;


wire[2:0] key_an=key_rst_r &(~key_rst);//当寄存器key_rst由1变0时,key_an为1

////--------------------------------------------------

reg[19:0] cnt;
//计数寄存器


always @(posedge clk or negedge rst_n)


if(!rst_n)cnt<=20'd0;

else if(key_an)cnt<=20'd0;

else cnt <= cnt+1'b1;


reg[2:0] low_sw;

always @(posedge clk or negedge rst_n)


if(!rst_n)low_sw<=3'b111;

else if(cnt == 20'hfffff)//满20ms,将键值锁存到寄存器low_sw

begin

low_sw <={sw3_n,sw2_n,sw1_n};

end
//---------------------------------------------------------

reg [2:0] low_sw_r;//每个时钟周期的上升沿将low_sw信号锁存至low_sw_r

always @(posedge clk or negedge rst_n)


if(!rst_n)low_sw_r<=3'b111;

else

low_sw_r <=low_sw;


wire[2:0] led_ctr1= low_sw_r[2:0] &(~low_sw[2:0]);
//当寄存器low_sw由1变为0时,led_ctr1的值变为高,维持一个周期

reg d1;
reg d2;
reg d3;

always @(posedge clk or negedge rst_n)


if(!rst_n)begin

d1<=1'b0;

d2<=1'b0;

d3<=1'b0;end

else begin

if(led_ctr1[0])d1<=~d1;

if(led_ctr1[1])d2<=~d2;

if(led_ctr1[2])d3<=~d3;

end


assign led_d1=d1 ? 1'b1:1'b0;
assign led_d2=d2 ? 1'b1:1'b0;
assign led_d3=d3 ? 1'b1:1'b0;



endmodule
发表于 2013-7-12 21:56:54 | 显示全部楼层
加個ms的延遲
发表于 2013-7-12 23:04:26 | 显示全部楼层
这个语句led_ctrl= low_sw_r[2:0] &(~low_sw[2:0])只检测从高电平到低电平的变化,所以当按键弹起的时候,led_ctrl不会变化保持低电平,led的亮灭也就不会在这时候反转了。
 楼主| 发表于 2013-7-12 23:40:52 | 显示全部楼层
回复 2# shiyinjita


   具体点,可以吗,谢谢了
 楼主| 发表于 2013-7-12 23:40:57 | 显示全部楼层
回复 2# shiyinjita


   具体点,可以吗,谢谢了
 楼主| 发表于 2013-7-12 23:41:01 | 显示全部楼层
回复 2# shiyinjita


   具体点,可以吗,谢谢了
 楼主| 发表于 2013-7-12 23:46:56 | 显示全部楼层
回复 3# vvb6


   那么,当按键先按下时,led_ctrl为1,然后再让按键弹起,照你的理解应该是led_ctrl保持不变,应该是保持在1而不是0啊,这样的话就算弹起灯不是依旧亮着的吗?ps:我主要是这个不理解,再解释下好吗,谢了
发表于 2013-7-13 12:22:02 | 显示全部楼层
回复 7# xujiong1992

led_ctrl 在按下时是电平由低变高只保持了一个clk时钟周期(你的代码注释里写了的),20ns之后就是低电平了。你可以写个tb,用modelsim看下。
 楼主| 发表于 2013-7-13 12:46:09 | 显示全部楼层
回复 8# vvb6


   好的,谢了哈
 楼主| 发表于 2013-7-13 13:05:03 | 显示全部楼层

RE: 有关特权同学verilog 按键消抖从按下到弹上的问题

回复 8# vvb6


   
无标题.png 当按键弹上时,led_ctrl依旧一直保持低电平,if(led_ctr1[0])d1<=~d1;是无法执行的啊,那么他是如何实现按键弹上时灯灭的啊?仿真图如上
无标题.png
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-25 13:11 , Processed in 0.027974 second(s), 10 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表