赞
踩
具体见正点原子《达芬奇Pro之FPGA开发指南v2.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]}]
这里采用了整合的写法,用-dict
实现,分开写举例如下:
set_property PACKAGE_PIN V9 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS15 [get_ports {led[0]}]
和整合写法相比,分开写要写的代码量较大,且重复了一些语句。
主要功能为:
按下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
①设置了变量led_flag
用来表示四个灯。
②用case
判断是哪个按键按下。
③设置了常量CNT_MAX
便于修改定时器定时时间。
仿真代码:
`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
仿真结果:
①设置数字格式可以右击变量,选择
Radix
,在列表里选择想要的数字格式即可(包括十六进制、十进制等)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。