给大家分享一些简单的代码。
很多FPGA初学者,不会做按键消抖,可能他们会写出这样的代码
always(*)
if(!key)
begin
//该按键的功能
end
意思是把按键当时钟来用,这样即没有消抖,也没有做同步。
我目前用的这个是计数消抖,设置一个计数器来消抖(消抖时间可任意设定),同时,产生一个跟时钟同步的单脉冲。
用计数器消抖很好理解,但是为什么要产生一个跟时钟同步的单脉冲呢?
这就是FPGA设计原则里面的同步原则,意思是每个模块都用同一个时钟(很多时候这个时钟是由PLL产生的),
这样的话,在按键消抖后面紧跟的模块就可以这样来处理这个单脉冲。
always(posedge clk)//clk是全局时钟,这个时钟跟消抖模块的时钟是相同的。
if(key) //key是消抖后,出来的单脉冲,高电平有效。
begin
//该按键的功能。
end
这个方法同样适合于单片机的按键消抖。
比如用C51写这样的代码:
if(!key)
{
delayms(10);
if(!key)
{ //该按键的功能
}
}
很多教材都写这样的例子出来,但是它会出现一个问题,就是如果你一直按住这个按键,MCU就会不断地进入这个函数,就是说代码的容错性不好。
uchar key_time=0; //“键龄”,这是全局变量。
void key_scan(void)
{
if(!key)
{
if(key_time<8) //这个8是消抖时间,虽然自己设定
key_time++; //捕捉“键龄”
if(key_time==1)
{
if(!key)
{
//该按键的功能
}
}
}
else
key_time=0;
}
具体的理论可以参考,周航慈的单片机教材。
这样的话,单片机和FPGA就可以触类旁通了。如有问题可以加Q:331922164
PS:附上了参考文献、VHDL和verilog两种代码,使用这些代码之前,要先搞清楚按键按下是高电平还是低电平,出来的单脉冲是高电平还是低电平。
因为quartus9.0不支持中文,所以我写的代码全部都用英文注解。
[
本帖最后由 k331922164 于 2013-11-27 10:27 编辑 ]