当前位置:   article > 正文

【FPGA学习笔记02】按键控制LED灯_fpga的按键开关是什么

fpga的按键开关是什么

具体见正点原子《达芬奇Pro之FPGA开发指南v2.1》

1.硬件介绍:按键

按键开关是一种电子开关,属于电子元器件类。
这里主要用轻触式按键开关。该开关只有在被施加压力时内部电路才会闭合导通,也就是说,只有按住按键时才有动作响应,松开没有。
(1)原理图
在这里插入图片描述
①电阻:限流,防止按键按下时电源直接接地造成电路短路。
②按下按键后输出高电平。
在这里插入图片描述
结合原理图可知,KEY0对应T4,KEY1对应T3,KEY2对应R6,KEY3对应T6。
管脚约束代码如下:

#------------------LED-----------------------------
set_property -dict {PACKAGE_PIN V9 IOSTANDARD LVCMOS15} [get_ports {led[0]}]
set_property -dict {PACKAGE_PIN Y8 IOSTANDARD LVCMOS15} [get_ports {led[1]}]
set_property -dict {PACKAGE_PIN Y7 IOSTANDARD LVCMOS15} [get_ports {led[2]}]
set_property -dict {PACKAGE_PIN W7 IOSTANDARD LVCMOS15} [get_ports {led[3]}]
#------------------按键----------------------------
set_property -dict {PACKAGE_PIN T4 IOSTANDARD LVCMOS15} [get_ports {key[0]}]
set_property -dict {PACKAGE_PIN T3 IOSTANDARD LVCMOS15} [get_ports {key[1]}]
set_property -dict {PACKAGE_PIN R6 IOSTANDARD LVCMOS15} [get_ports {key[2]}]
set_property -dict {PACKAGE_PIN T6 IOSTANDARD LVCMOS15} [get_ports {key[3]}]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这里采用了整合的写法,用-dict实现,分开写举例如下:

set_property PACKAGE_PIN V9 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS15 [get_ports {led[0]}]
  • 1
  • 2

和整合写法相比,分开写要写的代码量较大,且重复了一些语句。

2.软件部分:主要代码

主要功能为:
按下KEY0 - LED从低到高流水
按下KEY1 - LED从高到低流水
按下KEY2 - LED间隔0.5s亮灭交替
按下KEY3 - LED常亮

module key_led(
   //input
   input			sys_clk,
   input			sys_rst_n,
   input	[3:0]	key,
   
   //output
   output reg[3:0]  led
);

//parameter
parameter CNT_MAX = 25'd2500_0000;
//parameter CNT_MAX = 25'd25;

//reg define
reg [24:0] cnt;
reg [1:0]  led_flag;

//***********************************
//**	main code
//***********************************

//计数器计时0.5s
always @(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n)
		cnt <= 25'd0;
	else if(cnt < (CNT_MAX - 25'd1))
		cnt <= cnt + 25'd1;
	else
		cnt <= 25'd0;
end

//LED状态切换标志位
// 0   1   2   3
// 00 01  10  11
always @(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n)
		led_flag <= 2'd0;
	else if(cnt == (CNT_MAX - 25'd1)) 
		led_flag <= led_flag + 2'd1;
	else
		led_flag <= led_flag;
end

//LED控制
always @(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n)
		led <= 4'b0000; //LED初始化全灭
	else begin
		case(key)
			4'b1111: led <= 4'b0000; //未按下:LED常灭
			4'b1110: begin //按下key0,从低到高流水灯
				if(led_flag == 2'd0)
					led <= 4'b0001;
				else if(led_flag == 2'd1)
					led <= 4'b0010;
				else if(led_flag == 2'd2)
					led <= 4'b0100;
				else
					led <= 4'b1000;
			end
			4'b1101: begin //按下key1,从高到低流水灯
				if(led_flag == 2'd0)
					led <= 4'b1000;
				else if(led_flag == 2'd1)
					led <= 4'b0100;
				else if(led_flag == 2'd2)
					led <= 4'b0010;
				else
					led <= 4'b0001;
			
			end
			4'b1011: begin //按下key2,4个LED一起交替闪烁
				if(led_flag[0] == 1'b0) 
					led <= 4'b1111;
				else
					led <= 4'b0000;
			end
			4'b0111: begin //按下key3,4个LED一起亮
				led <= 4'b1111;
			end
			default: ; 
		endcase
	end
end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86

①设置了变量led_flag用来表示四个灯。
②用case判断是哪个按键按下。
③设置了常量CNT_MAX便于修改定时器定时时间。

3. 检测部分:仿真

仿真代码:

`timescale 1ns/1ns

module tb_key_led();

//parameter define
parameter CLK_PERIOD = 20;  //20ns
parameter CNT_MAX = 25'd25; //仅用于仿真,500ns(20*25 = 500)

//reg define
reg				sys_clk;
reg				sys_rst_n;
reg [3:0]		key;

//wire define
wire [3:0]		led;

//产生时钟
always #(CLK_PERIOD/2) sys_clk = ~sys_clk;

//信号初始化
initial begin
	sys_clk <= 1'b0;
	sys_rst_n <= 1'b0;
	key <= 4'b1111;
	
	#200
	sys_rst_n <= 1'b1;
	
	#2000
	key <= 4'b1110; //按下key0
	
	#2000
	key <= 4'b1101; //按下key1
	
	#2000
	key <= 4'b1011; //按下key2
	
	#2000
	key <= 4'b0111; //按下key3
	
	#2000
	key <= 4'b1111; //松开
end

//例化待测设计
key_led #(
	.CNT_MAX	(CNT_MAX)
)u_key_led(
	.sys_clk	(sys_clk),
	.sys_rst_n	(sys_rst_n),
	.key		(key),
	.led		(led)
);
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

仿真结果:
在这里插入图片描述①设置数字格式可以右击变量,选择Radix,在列表里选择想要的数字格式即可(包括十六进制、十进制等)。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/726137
推荐阅读
相关标签
  

闽ICP备14008679号