FPGA-02FPGA按键控制LED灯
按键是常用的一种控制器件。生活中我们可以见到各种形式的按键,由于其结构简单,成本低廉等特点,在家电、数码产品、玩具等方面有广泛的应用。本章我们将介绍如何使用按键控制多个LED的亮灭。
本章包括以下几个部分:
(1)按键简介
按键开关是一种电子开关,属于电子元器件类。我们的开发板上有两种按键开关:第一种是本实验所使用的轻触式按键开关,简称轻触开关。使用时以向开关的操作方向施加压力使内部电路闭合接通,当撤销压力时开关断开,其内部结构是靠金属弹片受力后发生形变来实现通断的;第二种是自锁按键,自锁按键第一次按下后保持接通,即自锁,第二次按下后,开关断开,同时开关按钮弹出来,开发板上的电源键就是这种开关。
(2)实验任务
使用开发板上的四个按键控制四个LED灯,不同按键按下时,四个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灯的亮灭随状态计数器的值改变,从而呈现出不同的显示效果。
代码如下:
//=============================================== //按键控制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 <= 24d0; else if(counter < 24d1000_0000) counter <= counter + 1d1; else counter <= 24d0; end //led status always @(posedge sys_clk or negedge sys_rst_n)begin if(!sys_rst_n) led_control <= 2b00; else if(counter == 24d1000_0000) led_control <= led_control + 1b1; else led_control <= led_control; end //key always @(posedge sys_clk or negedge sys_rst_n)begin if(!sys_rst_n) led <= 4b0000; else if(key[0] == 0)//按键1按下时,从右向左的流水灯效果 case(led_control) 2b00 : led <= 4b1000; 2b01 : led <= 4b0100; 2b10 : led <= 4b0010; 2b11 : led <= 4b0001; default: led <= 4b0000; endcase else if(key[1] == 0)//按键2按下时,从左向右的流水灯效果 case(led_control) 2b00 : led <= 4b0001; 2b01 : led <= 4b0010; 2b10 : led <= 4b0100; 2b11 : led <= 4b1000; default: led <= 4b0000; endcase else if(key[2] == 0)//按键3按下时,LED闪烁 case(led_control) 2b00 : led <= 4b1111; 2b01 : led <= 4b0000; 2b10 : led <= 4b1111; 2b11 : led <= 4b0000; default: led <= 4b0000; endcase else if(key[3] == 0)//按键4按下时,LED全亮 led <= 4b1111; else led <= 4b0000;//无按键按下时,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)下载验证