- 触摸按键: 电阻式,电容式(主流),红外感应式,表面声波式
- 代码
input: sys_clk, sys_rst_n, key
output: led
FPGA判断上升沿是通过将原信号延迟,再对比获取上升沿
src/touch_led.v
bash
module touch_led(
input sys_clk,
input sys_rst_n,
input touch_key,
output reg led
);
reg touch_key_d0;
reg touch_key_d1;
wire pos_touch_key;
assign pos_touch_key = ~touch_key_d1 & touch_key_d0;//采上升沿
//打两拍,采集上升沿
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n) begin
touch_key_d0 <= 1'd0;
touch_key_d1 <= 1'd0;
end
else begin
touch_key_d0 <= touch_key; //打两拍
touch_key_d1 <= touch_key_d0 ;
end
end
//led信号反转
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
led <= 1'd1;
else if(pos_touch_key)//上升沿
led <= ~led;
else
led <= led;
end
endmodule
3.仿真代码
sim/tb/tb_touch_led.v
bash
`timescale 1ns/1ns
module tb_touch_led();
parameter CLK_PERIOD = 20;//时钟周期
reg sys_clk;//需要被赋值,所以定义为reg类型
reg sys_rst_n;
reg touch_key;
wire led; //不会被赋值,所以定义为wire型。注意:如果是assign连续赋值,则是对wire类型赋值
initial begin
sys_clk <= 1'b0;
sys_rst_n <= 1'b0;
touch_key <= 1'b0;
#200 //延时200ns
sys_rst_n <= 1'b1;
//模拟按键按下/释放
#2000
touch_key <= 1'b1;
#2000
touch_key <= 1'b0;
end
always #(CLK_PERIOD/2) sys_clk = ~sys_clk; //每隔10ns取反一次,时间周期20ns
touch_led u_touch_led(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.touch_key (touch_key),
.led (led))
endmodule