FPGA模块——按键消抖+松手检测

FPGA模块——按键消抖+松手检测

代码

作为按键模块,加入了松手检测,通过判断按键的值来检测是否松手
使用模块需要输入key 和输出led

module key_led(
    //input
    input               sys_clk,
    input               sys_rst_n,
    input              [3:0]  key,
    //output        
    output     reg       [3:0]  led 
    );
//参数
//parameter CNT_MAX = 25'd5000000;    
parameter CNT_MAX = 25'd2000;    
//reg define
reg  [24:0]  cnt0;
reg  [24:0]  cnt1;
reg  [24:0]  cnt2;
reg  [24:0]  cnt3;
reg  [3:0]   key_reg ;
reg  [3:0]    flag_time;
reg          flag0;
reg          flag1;
reg          flag2;
reg          flag3;




initial led <= 4'b0000 ;
//*****************************************************
//**                    main code
//*****************************************************
   
//按键持续0.1s
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)begin
        cnt0 <= 25'b0;
        cnt1 <= 25'b0;
        cnt2 <= 25'b0;
        cnt3 <= 25'b0;
        led <= 4'b0000 ;
    end
    else begin
        key_reg<= key ;
        if(key_reg[0]==0)begin
             
                cnt0 <= cnt0 + 25'b1 ;
                if(cnt0 > (CNT_MAX-25'b1))begin
                       cnt0 <=  25'b0 ;                  
                       flag0 <= 1'b1 ; 
                      // led[1]<=~led[1] ;                 
                end       
        end 
        else  begin
                if(flag0==1'b1)begin
                   led[0]<=~led[0] ; 
                   flag0 <= 1'b0 ;
                end
               
                else
                  cnt0 <=   25'b0 ;
         end 
        
        if(key_reg[1]==0)begin            
                cnt1 <= cnt1 + 25'b1 ;
                if(cnt1 > (CNT_MAX-25'b1))begin
                       cnt1 <=  25'b0 ;                  
                       flag1 <= 1'b1 ;                                   
                end       
        end 
        else  begin
                if(flag1==1'b1)begin
                   led[1]<=~led[1] ; 
                   flag1 <= 1'b0 ;
                end
               
                else
                  cnt1 <=   25'b0 ;
         end 
         
         if(key_reg[2]==0)begin
             
                cnt2 <= cnt2 + 25'b1 ;
                if(cnt2 > (CNT_MAX-25'b1))begin
                       cnt2 <=  25'b0 ;                  
                       flag2 <= 1'b1 ;                                   
                end       
        end 
        else  begin
                if(flag2==1'b1)begin
                   led[2]<=~led[2] ; 
                   flag2 <= 1'b0 ;
                end
               
                else
                  cnt2 <=   25'b0 ;
         end 
         
         
         if(key_reg[3]==0)begin           
                cnt3 <= cnt3 + 25'b1 ;
                if(cnt3 > (CNT_MAX-25'b1))begin
                       cnt3 <=  25'b0 ;                  
                       flag3 <= 1'b1 ;                                   
                end       
        end 
        else  begin
                if(flag3==1'b1)begin
                   led[3]<=~led[3] ; 
                   flag3 <= 1'b0 ;
                end            
                else
                  cnt3 <=   25'b0 ;
         end 
            
            
    end
end
      
endmodule   


管脚约束

#时序约束
create_clock -period 20.000 -name sys_clk [get_ports sys_clk]

#IO管脚约束
set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN U2 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]
set_property -dict {PACKAGE_PIN T1 IOSTANDARD LVCMOS33} [get_ports {key[0]}]
set_property -dict {PACKAGE_PIN U1 IOSTANDARD LVCMOS33} [get_ports {key[1]}]
set_property -dict {PACKAGE_PIN R2 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
set_property -dict {PACKAGE_PIN R3 IOSTANDARD LVCMOS33} [get_ports {led[1]}]



set_property PACKAGE_PIN W2 [get_ports {key[2]}]
set_property PACKAGE_PIN T3 [get_ports {key[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {key[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {key[3]}]

set_property PACKAGE_PIN V2 [get_ports {led[2]}]
set_property PACKAGE_PIN Y2 [get_ports {led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]

固化文件

# 固化文件原语
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS true [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE Yes [current_design]

问题

如果按照两个always语句来写,会出现问题。
以下代码仿真没问题,实际上上板操作,灯不会亮。

module key_led(  
    //input  
    input               sys_clk,  
    input               sys_rst_n,  
    input              [3:0]  key,  
    //output          
    output reg          [3:0]  led   
);  
//参数  
parameter CNT_MAX = 25'd2000;      
reg [24:0] cnt;  
reg [3:0] key_reg;  
reg [3:0] flag_time;  
reg flag0;  
  
initial led <= 4'b1001;  
//按键持续0.1s  
always @(posedge sys_clk or negedge sys_rst_n) begin  
    if(!sys_rst_n) begin  
        cnt <= 25'b0;  
        flag0 <= 1'b0;  
    end 
    else begin  
        key_reg <= key;  
        if(key_reg[1] == 0) begin  
            cnt <= cnt + 25'b1;  
            if(cnt > (CNT_MAX-25'b1)) begin  
                cnt <= 25'b0;                    
                flag0 <= 1'b1;                                 
            end  
        end else begin  
            cnt <= 25'b0;                     
        end  
    end  
end  
//在flag0为1时改变led的值,同时将flag0重置为0  
always @(posedge sys_clk or negedge sys_rst_n) begin  
    if(!sys_rst_n) begin  
        flag0 <= 1'b0;
        led  <=4'b0000;
    end 
    else if(flag0 == 1'b1) begin  
        led <= 4'b1111;  
          
    end  
end 
 
endmodule
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云影点灯大师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值