FPGA-02FPGA按键控制LED灯

按键是常用的一种控制器件。生活中我们可以见到各种形式的按键,由于其结构简单,成本低廉等特点,在家电、数码产品、玩具等方面有广泛的应用。本章我们将介绍如何使用按键控制多个LED的亮灭。

本章包括以下几个部分:

(1)按键简介

按键开关是一种电子开关,属于电子元器件类。我们的开发板上有两种按键开关:第一种是本实验所使用的轻触式按键开关,简称轻触开关。使用时以向开关的操作方向施加压力使内部电路闭合接通,当撤销压力时开关断开,其内部结构是靠金属弹片受力后发生形变来实现通断的;第二种是自锁按键,自锁按键第一次按下后保持接通,即自锁,第二次按下后,开关断开,同时开关按钮弹出来,开发板上的电源键就是这种开关。

(2)实验任务

使用开发板上的四个按键控制四个LED灯,不同按键按下时,四个LED灯显示不同的效果

(3)硬件设计

FPGA-02FPGA按键控制LED灯_第1张图片FPGA-02FPGA按键控制LED灯_第2张图片

按键未按下时,输出为高电平,按下后,输出为低电平。

FPGA-02FPGA按键控制LED灯_第3张图片

          led[3]                output              F9                          LED       

(4)程序设计

最终实现的效果为:无按键按下时,LED灯全灭;按键1按下时,LED灯显示自右向左的流水效果;按键2按下时,LED灯显示自左向右的流水效果;按键3按下时,四个LED灯同时闪烁;按键4按下时,LED灯全亮。

LED在流水效果和闪烁效果在时间间隔均为0.2秒,因此需要在程序中定义一个0.2s的计数器,即每隔0.2s,状态计数器加一。根据当前按键的状态选择不同的显示模式,不同的显示模式下四个led灯的亮灭随状态计数器的值改变,从而呈现出不同的显示效果。

FPGA-02FPGA按键控制LED灯_第4张图片

代码如下:

//===============================================
//按键控制LED灯的状态
//===============================================
module key_led(
	input    sys_clk,
	input    sys_rst_n,
	
	input      [3:0] key,
	output reg [3:0] led
);
reg [23:0] counter;
reg [1:0]  led_control;

//0.2s counter 
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)
		counter <= 24'd0;
	else if(counter < 24'd1000_0000)
		counter <= counter + 1'd1;
	else
		counter <= 24'd0;
end

//led status 
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)
		led_control <= 2'b00;
	else if(counter == 24'd1000_0000)
		led_control <= led_control + 1'b1;
	else
		led_control <= led_control;
end

//key 
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)
		led <= 4'b0000;
	else if(key[0] == 0)//按键1按下时,从右向左的流水灯效果
		case(led_control)
			2'b00  : led <= 4'b1000;
			2'b01  : led <= 4'b0100;
			2'b10  : led <= 4'b0010;
			2'b11  : led <= 4'b0001;
			default: led <= 4'b0000;
		endcase
	else if(key[1] == 0)//按键2按下时,从左向右的流水灯效果
		case(led_control)
			2'b00  : led <= 4'b0001;
			2'b01  : led <= 4'b0010;
			2'b10  : led <= 4'b0100;
			2'b11  : led <= 4'b1000;
			default: led <= 4'b0000;
		endcase
	else if(key[2] == 0)//按键3按下时,LED闪烁
		case(led_control)
			2'b00  : led <= 4'b1111;
			2'b01  : led <= 4'b0000;
			2'b10  : led <= 4'b1111;
			2'b11  : led <= 4'b0000;
			default: led <= 4'b0000;
		endcase
	else if(key[3] == 0)//按键4按下时,LED全亮
		led <= 4'b1111;
	else
		led <= 4'b0000;//无按键按下时,LED熄灭
end
endmodule

代码主要分为三个部分,第12至20行对系统时钟计数,当计数时间达0.2s时,计数器清零,同时使led_control在四个状态(00,01,10,11)内依次变化。第33至65行利用case语句实现对按键状态的检测,当不同的按键按下时,led随着led_control的变化,被赋予不同的值。大家可以发现,本次实验和流水灯实验计数时间都是0.2s,本次实验的计数器最大可以计数9_999_999,而流水灯实验中计数器的值最大可以计数到10_000_000。事实上,这两个实验计数器都是从0开始计数的,本次实验从0计数到9_999_999,需要10_000_000个时钟周期,而系统时钟为20ns,所以计数的时间为0.2s,而流水灯实验从0计数到10_000_000需要10_000_001个时钟周期,因此其计数时间实际上比0.2s要多出20ns。

(5)下载验证

 

你可能感兴趣的:(FPGA)