【问题标题】:How to detect one button press?如何检测一键按下?
【发布时间】:2016-09-14 12:54:26
【问题描述】:

我有一个在 nexys4 上运行的秒表电路,我可以通过启动、停止和重置按钮来控制它。所以如果我点击开始,计数器开始计数直到停止或重置它。我正在尝试添加一个功能,当我按下另一个按钮时,计数器仅增加 1 位。现在时钟太快了,所以当我按下增量按钮时,它会增加多次,因为它会在每个时钟边缘检测到按钮按下。无论我按住按钮多长时间,我如何让它只按下一个按钮?我需要去抖电路吗?

谢谢

【问题讨论】:

    标签: verilog counter


    【解决方案1】:

    您需要的是一个上升沿检测器和一些去抖动逻辑。 我将从上升沿检测器开始,因为这将解决大部分问题。

    reg [3:0] resync;
    reg       inc_cntr;
    always @ (posedge clk)
    begin 
       resync <= {resync{2:0},inc_btn};  // This will clock in the inc_btn signal and remove metastability.
       inc_cntr <= ~resync[3] & resync[2]; // Only high when the resync[3] was low and resent[2] is high.  
    end
    

    这不能解决的是,如果您的按钮在从上到下转换时弹跳很多。看看这个以了解去抖动。 Switch Debouncing

    在这两个主题之间,您应该能够设计出一个好的按钮过滤器。

    【讨论】:

    • 因此,如果我使用状态机检测按钮按下并将输出状态发送到计数器以告诉它要做什么(向上计数、停止或递增),这会去哪里?我可以把它扔进状态机吗?或者我应该把它作为它自己的模块来做,当按下增量按钮时,将它发送到这个模块(使用去抖动器)并将输出发送到计数器,告诉它加一?这是一个基本框图,它是如何工作的:imgur.com/a/b7iOe(控制器持有状态机)
    • 好吧,除了去抖动器,我已经搞定了! debouncer 是直接在“inc_cntr
    • 我会让你的去抖动器成为一个单独的模块,因为你可能会在你的下一个按钮项目中重用它。我会在同步器之后去抖动。所以预订到 inc_cntr 脉冲会很好。您不希望去抖动器进入元稳定状态,而同步器将防止这种情况发生。
    • 所以目前我在检测到按钮按下的状态机中有同步器。我应该将输出 inc_cntr 发送到去抖动器,然后将去抖动器的输出发送到二进制计数器,对吗?
    • 你的建议我相信会奏效。当你进入这个,你会发现有很多方法可以给猫剥皮,但作为一项规则……首先消除 META 稳定性。对于新手,我会说,永远不要在任何情况下,将非同步信号直接传递到状态机。 [Sync -> debounce -> state-machine] 是一种已知的良好工作模式。请记住,在大多数情况下,去抖动器也是一个状态机……这就是您要先同步的原因。
    猜你喜欢
    • 2022-11-17
    • 1970-01-01
    • 2021-01-27
    • 2013-04-07
    • 2014-07-29
    • 2010-11-09
    • 2010-10-24
    • 1970-01-01
    相关资源
    最近更新 更多