赞
踩
由于前面已经分享过了,这里直接说思路,贴代码。原理等等其他的翻前面的博文。(代码经过验证,可以在板机上使用)
四个独立按键分别对应四个led灯,按键控制led的反转。
这里的思路其实很简单,基于按键的抖动最长为20ms,所以每20ms取一次按键状态,前后两次进行下降沿检测就行。(有没有很简单,还有一个更简单的!!!后面代码中分享)贴张图
- module key_filter(clk,rst_n,key_in,led
- );
- input clk;
- input rst_n;
- input [3:0] key_in;
-
- output [3:0] led;
- //这两段代码前面分别进行计数和在计数满产生一个高脉冲信号cnt_full
- //20ms计数器
- reg cnt_full;
- reg [19:0] cnt;
- always@(posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- cnt <= 20'd0;
- else if(cnt == 20'd999_999)
- cnt <= 20'd0;
- else
- cnt <= cnt + 1'b1;
- end
- //计数满信号
- always@(posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- cnt_full <= 1'b0;
- else if(cnt == 20'd999_999)
- cnt_full <= 1'b1;
- else
- cnt_full <= 1'b0;
- end
-
- //这两段代码就是来用实现取前后按键信号的
- reg [3:0] key_in_r;
- reg [3:0] key_in_r_next;
- always@(posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- key_in_r_next <= 4'b1111;
- else if(cnt_full)
- key_in_r_next <= key_in;
- else
- key_in_r_next <= key_in_r_next;
- end
- always@(posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- key_in_r <= 4'b1111;
- else
- key_in_r <= key_in_r_next;
- end
- wire [3:0] key_out;
- assign key_out = key_in_r & (~key_in_r_next);
-
- //后面两个单元很简单,控制led翻转
- reg [3:0] led_r;
- //led翻转
- always@(posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- led_r <= 4'b0000;
- else
- begin
- if(key_out == 4'b0001) led_r[0] <= ~led[0];
- if(key_out == 4'b0010) led_r[1] <= ~led[1];
- if(key_out == 4'b0100) led_r[2] <= ~led[2];
- if(key_out == 4'b1000) led_r[3] <= ~led[3];
- end
- end
- assign led[0] = led_r[0];
- assign led[1] = led_r[1];
- assign led[2] = led_r[2];
- assign led[3] = led_r[3];
- endmodule
本来不想贴,但是它太漂亮了,,所以分享下,一起感受它的美!!
小惊喜!!!!上边核心代码是不是有点不太好理解??这里有一个新思路,直接计数40ms!!取值两次进行对比即可(两次取值分别在中间和结束,看看和上边图是不是一个意思??)!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。