FPGA触摸按键控制LED——边沿检测——同步时钟的意识

边沿检测

想要实现按一次LED翻转状态,而不是按下亮,打开灭,就需要检测边沿。
在这里插入图片描述
我们对同一信号打一拍后在①位置处就可以检测到上升沿,使之拉高一个时钟的脉冲;在②位置处可以检测到下降沿,使之拉高一个时钟的脉冲。

上升沿检测核心代码:

在①处检测到 data 为高电平且 data_reg 为低电平时,表示有上升沿产生。

方法一:与逻辑实现
 always@(posedge sys_clk or negedge sys_rst_n)
 if(sys_rst_n == 1'b0)
 podge <= 1'b0;
 else if((data) && (~data_reg)) //核心逻辑
 podge <= 1'b1;
 else 
 podge <= 1'b0;
方法二:或逻辑实现
 always@(posedge sys_clk or negedge sys_rst_n)
 if(sys_rst_n == 1'b0)
 podge <= 1'b0;
 else if((~data) || (data_reg)) //核心逻辑
 podge <= 1'b0;
 else 
 podge <= 1'b1;

下降沿检测核心代码:

在②处检测到 data 为低电平且 data_reg 为高电平时,表示有下降沿产生,和上升沿的情况刚好相反。

方法一:与逻辑实现
 always@(posedge sys_clk or negedge sys_rst_n)
 if(sys_rst_n == 1'b0)
 nedge <= 1'b0;
 else if((~data) && (data_reg)) //核心逻辑
 nedge <= 1'b1;
 else 
 nedge <= 1'b0;
方法二:或逻辑实现
 always@(posedge sys_clk or negedge sys_rst_n)
 if(sys_rst_n == 1'b0)
 nedge <= 1'b0;
 else if((data) || (~data_reg)) //核心逻辑
 nedge <= 1'b0;
 else 
 nedge <= 1'b1;

只需要注重核心逻辑那句,同样可以使用assign语句用组合逻辑的方法实现,这样检测出的边沿信号就不会延时一个时钟周期。

代码编写——时钟同步的思想

在这里插入图片描述
那么这里,为什么要设置touch_key_dly1/2 而不用touch_key呢,因为我们按下按键的时候touch_key不一定与时钟同步,所以使用时序逻辑的一次赋值touch_key_dly1 <= touch_key ;将touch_key信号与时钟同步,再用touch_key_dly2对touch_key_dly1进行延一拍的操作,之后就可以进行判断边沿了。


//下降沿检测
module touch_ctrl_led
(
	input   wire    sys_clk     ,  
	input   wire    sys_rst_n   ,  
	input   wire    touch_key	,  
	
	output  reg     led_out	
);

reg 	touch_key_dly1	;//将touch_key同步到时钟下
reg 	touch_key_dly2	;//对touch_key_dly1进行打一拍的操作

/*
设置touch_key_dly1/2 不能用touch_key原因:
touch_key和系统时钟不关联,会影响整体稳定性,
而通过时序逻辑的一次赋值touch_key_dly1 <= touch_key	;
就可以将touch_key同步到时钟下
*/

wire 	touch_en		;

assign	touch_en = (~touch_key_dly1) & touch_key_dly2;

//对 touch_key 信号延迟两个时钟周期用来产生触摸按键信号
always@(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n)
		begin
			touch_key_dly1 <= 1'b0;
			touch_key_dly2 <= 1'b0;
		end
	else
		begin
			touch_key_dly1 <= touch_key		;
			touch_key_dly2 <= touch_key_dly1;
		end
end

always@(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n)
		led_out <= 1'b1		;
	else if(touch_en)
		led_out <= ~led_out	;
	else
		led_out <= ~led_out	;
end

endmodule

疑问

其实有个疑问,为什么不能touch_key_dly1 <= touch_key,然后negedge touch_key_dly1 呢

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值