常用Verilog HDL程序

1.按键软件去抖动input[KEY_WIDTH-1:0] key_in; //外部按键输入output[KEY_WIDTH-1:0]key_out; //按键消抖输出reg[KEY_WIDTH-1:0]dout1,dout2,dout3; //寄存器parameter KEY_WIDTH = 8; //参数 assign key_out = (dout1 | dout2 
摘要由CSDN通过智能技术生成

1.按键软件去抖动

input[KEY_WIDTH-1:0] key_in; //外部按键输入

output[KEY_WIDTH-1:0]key_out; //按键消抖输出

reg[KEY_WIDTH-1:0]dout1,dout2,dout3; //寄存器

parameter KEY_WIDTH = 8; //参数

 

assign key_out = (dout1 | dout2 | dout3); //按键消抖输出

 

always @(posedge clk)  //  always @(posedge count[17])  当系统时钟是48MHZ时,count一直计算,计到18位为1时也就满足了按键时钟的要求

begin

dout1 <= key_in;

dout2 <= dout1;

dout3 <= dout2;

end


//下面是利用按键 消抖后的输出  设置一个标志位,将琴键开关转换为乒乓开关   就需要点击2下才可以回复到原来的状态

always @(negedge key_out)
begin
keyen = ~keyen;//将琴键开关转换为乒乓开关
end

或者利用边沿检测的知识

always @(posedge clock)//按键6
begin
if(key_out )//2中的key_out 
keyen = ~keyen;
end

按键消抖关键在于提取稳定的低电平状态,滤除前沿、后沿抖动毛刺。对于一个按键信号,可以用一个脉冲对它进行采样。如果连续三次采样为低电平,可以认为信号已经处于键稳定状态,这时输出一个低电平按键信号。继续采样的过程中如果不能满足连续三次采样为低,则认为键稳定状态结束,这时输出变为高电平。

按键消抖:按键消抖处理一般有硬件和软件两种方法。软件消抖是检测到有触发后,延时一段时间(一般为10ms)后再检测触发状态,如果与之前检测到的状态相同,则认为有按键按下;如果没有。则判断为误触发。硬件就是加去抖动电路,这样可以从根本上解决按键抖动的问题。

消抖电路的采样时钟要实际应用可以灵活改变,因为按键触发的时间一般为几百毫秒,干扰毛刺脉宽一般为几百毫秒到几毫秒,所以采样时钟的周期一般为几毫秒。

这里我们可以选择5ms 即上式的clk的频率为200HZ

2.按键的边沿(下降沿)检测

 

reg [7:0] dout1,dout2,dout3,buff;

always @(posedge clk)

begin

dout1 <= key_in;

dout2 <= dout1;

dout3 <= dout2;

end 

always @(posedge clk)

begin

buff<=dout1|dout2|dout3;

end

assign key_out = ~(dout1 | dout2 | dout3)&buff;//按键的边缘检测  if(key_out[0])..然后就可以用key_out来作为控制信号了


//时钟分频部分     系统时钟 48MHZ
always @(posedge clock)
begin
if (count < 17'd120000)
begin
     count <= count + 1'b1;
     div_clk <= 1'b0;
  end
  else
  begin
     count <= 17'd0;
     div_clk <= 1'b1;
  end
end


//按键消抖部分
always @(posedge clock)
begin
if(div_clk) //分频时钟,用于消抖和扫描
begin
dout1 <= key;
dout2 <= dout1;
dout3 <= dout2;
end
end

//assign key_out = (dout1 | dout2 | dout3); //按键消抖输出


//按键边沿检测部分
always @(posedge clock)
begin
buff <= dout1 | dout2 | dout3;  //buff为按键消抖输出
end


assign key_edge = ~(dout1 | dout2 | dout3) & buff;  //按键消抖输出


always @(posedge clock) //有按键按下
begin
if(key_edge[0])
hex_r[15:12] <= hex_r[15:12] + 1'b1;
end

 

3.程序中用到的小分频程序


always @(posedge clk)

begin

if(dividi_clk)

counter<=26'd0;//使counter为0

else 

counter<=counter+1'b1;

end

assign dividi=(counter>=26'd48000);//26d48000就是分频数(-1)。

 如图是8分频的时序图

reg[16:0]count;//时钟分频计数器    120000分频

always @(posedge clock)
begin
if (count < 17'd120000)
begin
     count <= count + 1'b1;
     div_clk <= 1'b0;
  end
  else
  begin
     count <= 17'd0;
     div_clk <= 1'b1;
  end
end

以上2个程序的div都只是在一个系统时钟内才会出现一个高电平。。这样做有利于使整个的always块的时钟都是系统时钟  像
  
  
  
always @(posedge clock) 都用系统时钟
if(div_clk)



always @(posedge clk)

begin

     if(cnt==设定值) //设定值-起始值=分频数的一半,即计数到分频数的一半时反转输出

begin

             cnt<=起始值;

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值