资讯详情

【按键消抖】基于FPGA的按键消抖模块开发

QUARTUSII8.1

Modelsim6.5d

module tops(             i_clk,    //100M             i_rst,    //系统复位功能,高电平复位,如果不使用这个角,可以直接低电平             i_input1, //按键输入1             i_input2, //按键输入2             o_output1.///脉冲输出1             o_output2,//脉冲输出2             test_cnt1.//测试计数器1             test_cnt2,//测试计数器2             test_enable1.//测试使能信号             test_enable2 //测试使能信号            );             //100M等于10ns,所以1s中就是10_000_000个100M时钟周期 ///模拟时,为方便看到模拟效果,所以将10_000_000改为小值10_000            //parameter NUM = 32'd10000000;  //实际用         parameter NUM = 32'd100;       //仿真用                              input       i_clk;//100M为10ns input       i_rst; input       i_input1; input       i_input2;  output      o_output1; output      o_output2;          output[31:0]test_cnt1;  output[31:0]test_cnt2;  output      test_enable1; output      test_enable2;   reg      o_output1    = 1'b0; reg      o_output2    = 1'b0;   reg      test_enable1 = 1'b0; reg      test_enable2 = 1'b0; reg[31:0]cnt1         = 32'd0; reg[31:0]cnt2         = 32'd0;   reg      flag1        = 1'b1; reg      flag2        = 1'b1;    always @(posedge i_clk or posedge i_rst)//处理主要进程 begin      if(i_rst)//系统复位      begin      test_enable1 <= 1'b0.//定义使能信号      test_enable2 <= 1'b0.//定义使能信号       cnt1         <= 32'd0;        cnt2         <= 32'd0;       flag1        <= 1'b1;        flag2        <= 1'b1;       end else begin           if(i_input1 == 1'b0 & i_input2 == 1'b1 & flag1 == 1'b1)/按键1,不按按键2           begin                //1s保持10分钟内_000_000个时钟周期                                 cnt2 <= 32'd0;                                if(cnt1 < NUM)//不到1s                begin                cnt1 <= cnt1   32'd1;                test_enable1 <= 1'b1.//输出一个脉冲,//按下按钮后,持续1s钟                test_enable2 <= 1'b0;                 flag1        <= 1'b1.//用于屏蔽第二个按钮                  flag2        <= 1'b0.//用于屏蔽第二个按钮                                                end                                if(cnt1 == NUM)//到1s,停止输出                begin                cnt1 <= cnt1;                               test_enable1 <= 1'b0;                test_enable2 <= 1'b0;                  flag1        <= 1'b1;                 flag2        <= 1'b1;                                              end                          end                                     if(i_input1 == 1'b1 & i_input2 == 1'b0 & flag2 == 1'b1)/按键2,不按按键1           begin                //50s保持钟内的能量                cnt1 <= 32'd0;                                if(cnt2 < 50*NUM)//不到50s                begin                cnt2 <= cnt2   32'd1;                test_enable1 <= 1'b0.//输出一个脉冲,//按下按钮后,持续1s钟                test_enable2 <= 1'b1;                 flag1        <= 1'b0.//用于屏蔽第一个按钮                  flag2        <= 1'b1.//用于屏蔽第一个按钮                                                end                                if(cnt2 == 50*NUM)//到1s,停止输出                begin                cnt2 <= cnt2;                               test_enable1 <= 1'b0;                test_enable2 <= 1'b0;                  flag1        <= 1'b1;                 flag2        <= 1'b1;                                              end                         end                                 if(i_input1 == 1'b1 & i_input2 == 1'b1)//没有按键操作           begin           cnt1 <= 32'd0;           cnt2 <= 32'd0;           end                      end         end assign test_cnt1 = cnt1; assign test_cnt2 = cnt2;  以下是能量信号,输出脉冲  //定义两个脉冲计数器 reg[31:0]pcnt1 = 32'd0; reg[31:0]pcnt2 = 32'd0; always @(posedge i_clk or posedge i_rst)//处理主要过程 begin      if(i_rst)//系统复位      begin      pcnt1        <= 32'd0;      pcnt2        <= 32'd0;      o_output1    <= 1'b0;      o_output2    <= 1'b0;       end else begin           if(test_enable1 == 1'b1)//1s内一个100ns的脉冲,即1s内发生一个10M的脉冲信号           begin           pcnt1 <= pcnt1   32'd1;                           if(pcnt1 < 32'd10)                begin                o_output1    <= 1'b1;//产生100ns的信号                end           else begin                o_output1    <= 1'b0;                end           end      else begin           pcnt1        <= 32'd0;           o_output1    <= 1'b0;               end                       if(test_enable2 == 1'b1)//50s内50个100ns的脉冲,即1s内发生一个10M的脉冲信号           begin                           if(pcnt2 == NUM-1)                begin                pcnt2 <= 32'd0;                end           else begin                pcnt2 <= pcnt2   32'd1;                end                                           if(pcnt2 < 32'd10)               begin
               o_output2    <= 1'b1;//产生100ns的信号
               end
          else begin
               o_output2    <= 1'b0;
               end
          end
     else begin
          pcnt2        <= 32'd0;
          o_output2    <= 1'b0;    
          end     

     end        
end
       
endmodule           

QII自带仿真说明:

我们将波形进行局部放大:

第一部分,可以看到input1为高,input2为低,说明2按下了,所以output2产生连续的50个脉冲。

第二部分,input1为低,第一个按键按下了,所以只产生一个高电平信号

第三部分,还是第一个按钮被按下了,所以只产生一个脉冲。

Modelsim仿真说明:

我们将仿真进行局部放大:

按键一按下:

按键二被按下;

还是按键二被按下。

A35-09

标签: ld50s激光传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

 锐单商城 - 一站式电子元器件采购平台  

 深圳锐单电子有限公司