关于按键消抖的理解:【基于特权FPGA教程第9讲】
先列几个关键的点,理解了这几个点,其余都好理解。
①key_rst和key_rst_r的关系如下:
如果看了这张图还不理解的话,那就在传输线上标上一些符号就会明白了。
当时钟信号的上升沿到来时,sw[3:1]的信号被key_rst[2:0]触发器接收,同时key_rst上的信号被key_rst_r触发器接收。这样的话,就能够得到sw[2:0]的两个状态。
②该程序的思路:
当按键被按下时,会导致key_an不等于0,进而cnt=0;
那么在cnt=20’hfffff时,low_sw会感受到sw的变化,不如变为”110”
而low_sw_r依旧为”111”,会导致led_ctrl=1,进而可以判断是哪一个键被按下。
③对于我之前一直怀疑的并行问题,不如如果两个always同时执行的话会同时对cnt进行赋值,会不会出现随机的现象。答案是不会,因为所谓的并行特性是指每时每刻各个语句都在被执行(相关器件在工作),但这只是从时间上说。如果从空间上进行理解(参考RTL图),我们会发现各个器件在空间上的连接是有一定次序的。举例如下:
源程序:
reg[19:0] cnt;//counter
always @ (posedge clk or negedge rst_n)
if(!rst_n) cnt <= 20'd0;
else if(key_an) cnt <= 20'd0;
else cnt <= cnt + 1'b1;
reg[2:0] low_sw;
always @ (posedge clk or negedge rst_n)
if(!rst_n) low_sw <= 3'b111;
else if(cnt == 20'hfffff)//20ms
low_sw <= {sw3_n,sw2_n,sw1_n};
该段程序的功能:如果key_an不等于0,cnt=0;如果cnt=20’hfffff就更新low_sw。
我一开始想了这么一个问题,如果同时出现key_an!=0和cnt=20’hfffff那么这段程序是有毛刺的。我想了很长的时间,发现从程序的角度越想越感觉每段程序好像都有问题。但长期的经验告诉我,如果你刚开始学习一门新的技术,在知识结构没有完善之前,你那些所谓的思考都是没有任何益处的。最好的方法是先对相关的知识进行学习,比如看有关的书、视频。
所以我打断了自己的思考,开始看RTL电路,我发现上述程序的RTL电路是这样的:
【不过当触发器cnt[19:0]输出恰好为20’hfffff时会读到按键后的值,便立即认为键盘被按下,不过这样的概率为1/1000000】
这段程序增加了我对并行的理解。时间上同时运行,但空间上有先后顺序。
本文及其他我写的文章,皆是鄙人学习总结笔记。文中内容我会尽最大的努力保证正确,如你发现bug,请一定要通知我,我会按您的指导进行Debug。
我相信交流是提高技术最好的方法。
用户1631420 2011-6-13 12:39