采用的是黑金的板子
1、实验目的
这一次的实验的目的就是使用FPGA上的按键能够控制上面的LED灯的亮灭
2、实验理解
step1 能够检测到按键的变化
step2 将 检测到的按键变化-----能够通过判断到这个按键发生了变化 (消抖的问题) -- 对应到led的灯的亮灭上
3、开始编程啦
//===========================================================================
// Module name: key_test.v
// : ϵĸKEY1~KEY4, ʱ,ӦLEDƷת
//===========================================================================
`timescale 1ns / 1ps
module key_test (
clk, // ʱ: 50Mhz
rst_n, // 븴λ
key_in, // 밴ź(KEY1~KEY4)
led_out // LED,ڿƿĸLED(LED1~LED4)
);
//===========================================================================
// PORT declarations
//===========================================================================
input clk;
input rst_n;
input [3:0] key_in;
output [3:0] led_out;
//Ĵ
reg [19:0] count;
reg [3:0] key_scan; //ɨֵKEY
//===========================================================================
// ֵ20msɨһ,ƵСڰëƵʣ൱˳˸Ƶëźš
//===========================================================================
always @(posedge clk or negedge rst_n) //ʱӵغλ½
begin
if(!rst_n) //λźŵЧ
count <= 20'd0; //0
else
begin
if(count ==20'd999_999) //20msɨһΰ,20ms(50M/50-1=999_999)
begin
count <= 20'b0; //Ƶ20ms
key_scan <= key_in; //ƽ
end
else
count <= count + 20'b1; //1
end
end
//===========================================================================
// źһʱӽ
//===========================================================================
reg [3:0] key_scan_r;
always @(posedge clk)
key_scan_r <= key_scan;
wire [3:0] flag_key = key_scan_r[3:0] & (~key_scan[3:0]); //½ر仯ʱð£Ч
//===========================================================================
// LEDƿ,ʱ,صLEDת
//===========================================================================
reg [3:0] temp_led;
always @ (posedge clk or negedge rst_n) //ʱӵغλ½
begin
if (!rst_n) //λźŵЧ
temp_led <= 4'b1111; //LEDƿźΪ, LEDȫ
else
begin
if ( flag_key[0] ) temp_led[0] <= ~temp_led[0]; //KEY1ֵ仯ʱLED1ת
if ( flag_key[1] ) temp_led[1] <= ~temp_led[1]; //KEY2ֵ仯ʱLED2ת
if ( flag_key[2] ) temp_led[2] <= ~temp_led[2]; //KEY3ֵ仯ʱLED3ת
if ( flag_key[3] ) temp_led[3] <= ~temp_led[3]; //KEY4ֵ仯ʱLED4ת
end
end
assign led_out[0] = temp_led[0];
assign led_out[1] = temp_led[1];
assign led_out[2] = temp_led[2];
assign led_out[3] = temp_led[3];
endmodule
4、最重要的是关于按键的消抖操作的理解
always @(posedge clk or negedge rst_n) //ʱӵغλ½
begin
if(!rst_n) //λźŵЧ
count <= 20'd0; //0
else
begin
if(count ==20'd999_999) //20msɨһΰ,20ms(50M/50-1=999_999)
begin
count <= 20'b0; //Ƶ20ms
key_scan <= key_in; //ƽ
end
else
count <= count + 20'b1; //1
end
end
上面这个模块是对按键进行扫描,扫描的间隔就是20ms(这也就是消抖的关键,进行二次及其二次以上的判断)
always @(posedge clk)
// key_scan_r <= key_scan; //这一句话 是进行将上一个20ms的状态存下来 当下一个20ms 来了时候 就进行比较得到结果
key_scan_r <=4'b1111 ; // 这句话 就是固定值 用于实现只有按下的时候 或者只有放开的时候灯才亮或者灭掉,
//同样 , 在这种情况下, 我们将key_scan的那个 取反的 符号 去掉 就可以了 就可以 实现 只有按下的时候 才灭掉 否则 是只有按下的时候 才亮起来
wire [3:0] flag_key = key_scan_r[3:0] & (~key_scan[3:0]);