微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 有关特权同学verilog 按键消抖从按下到弹上的问题

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

时间:10-02 整理:3721RD 点击:
特权同学的键盘消抖是利用按键在从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

加個ms的延遲

这个语句led_ctrl= low_sw_r[2:0] &(~low_sw[2:0])只检测从高电平到低电平的变化,所以当按键弹起的时候,led_ctrl不会变化保持低电平,led的亮灭也就不会在这时候反转了。



   具体点,可以吗,谢谢了



   具体点,可以吗,谢谢了



   具体点,可以吗,谢谢了



   那么,当按键先按下时,led_ctrl为1,然后再让按键弹起,照你的理解应该是led_ctrl保持不变,应该是保持在1而不是0啊,这样的话就算弹起灯不是依旧亮着的吗?ps:我主要是这个不理解,再解释下好吗,谢了


led_ctrl 在按下时是电平由低变高只保持了一个clk时钟周期(你的代码注释里写了的),20ns之后就是低电平了。你可以写个tb,用modelsim看下。



   好的,谢了哈

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


   


当按键弹上时,led_ctrl依旧一直保持低电平,if(led_ctr1[0])d1<=~d1;是无法执行的啊,那么他是如何实现按键弹上时灯灭的啊?仿真图如上



   我理解了,谢谢了

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top