一、描述
涉及到按键的应用时,常见操作是提取变化边沿,但按键输入信号这样的异步信号有一定的几率不满足寄存器的建立保持时间,就会出现亚稳态现象。在同步低速域信号到高速域时,常见的就是两级寄存器寄存,以达到尽可能消除亚稳态的作用。之前的笔记中关于按键检测操作如下图,明显地,直接将按键的物理输入key_in赋值给key_reg0,这样key_reg0发生振荡或者稳定在0、1都是有可能的,后面直接用key_reg0用于边沿判断明显是不安全的。
![](https://i-blog.csdnimg.cn/blog_migrate/d576bd69fb432b481998518f4f4f89a5.png)
解决思路是:在对边沿进行判断时,先用两级寄存器对key_in信号进行同步消除亚稳态。再用两级寄存器对优化后的信号进行寄存判断。检测下降沿模型如下:
![](https://i-blog.csdnimg.cn/blog_migrate/521935b29ecd74044923463cc12a980a.png)
代码操作:就是四个寄存器组成的移位寄存器。
![](https://i-blog.csdnimg.cn/blog_migrate/2970b3d478a4538248fea391919b74e6.png)
疑惑:刚接触这个概念的时候,有一点疑惑。在按键下降沿没来的时候四个寄存器的都是1,一旦某个瞬间在时钟沿检测到按键的下降沿上,经过稳定后,key_in_r[0]的信号可能不能反映真是的按键意图0,而是可能稳定在0或1,四个寄存器有两种状态,0111或1111,当为0111时,这种情况有种歪打正着的感觉,传递到后两级寄存器后是可以正常检测出下降沿的,但1111这样的情况就检测不到了,这样后续的检测不是失去了可靠性了吗?
在后来,仔细画图理解每个细节之后,发现如果是0111这种情况那是最好,如果是1111的话也是可以的,在紧跟其后的一个时钟采集下,会检测到按键下降沿之后的常态0,这样一级级传递下去也是可行的,只不过检测到下降沿会比正常情况要延迟一个时钟周期。细节看下图:
![](https://i-blog.csdnimg.cn/blog_migrate/6278b619b3bff9787de4a7bebd80c836.png)
结果是显然的!
二、总结
理解了可能由于按键输入引起的亚稳态问题。
掌握了处理这种类型亚稳态的基本方法。
还有一些其他情况引起的亚稳态的解决方案涉及到FIFO、异步复位同步释放的内容,会在之后的笔记中记录。