主要框图如上所示,上一阶段已经完成了keyscan键盘扫描模块,该模块根据按下的按键输出相应[4:0]key_num,我们需对key_num进行消抖处理。
之前学习过一种消抖方法,在已知按下按键后的稳定状态应为低电平时,在检测到低电平后延时10ms后再检测一下当前状态是否为低电平,是则认为状态稳定按键按下,否则继续检测。由于矩阵键盘情况较为复杂,按下后的状态不是简单的高低电平,可能存在多种状态,所以采用一种新的消抖方法,具体方法如下:
一般按键抖动的过程为10ms,若我们将抖动过程分为10份,即每份为1ms(1khz)。每1ms检测一个数据,判断这个数据是否同上一个检测到的数据相同,是则计数器加1并继续进行后续检测,否则返回原始状态重新开始检测,直至检测到的10个(多几次或者少几次均可,根据具体情况来定)的数据均相同,即判断按键状态稳定,输出真实按键值[4:0]real_num,并输出一个按键是能信号key_en。
主要代码如下:
always @ (posedge clk or negedge rst_n) /**************生成一个1khz的时钟,用于检测key_num***************/
begin
if(!rst_n)
begin
cnt <= 15'd0;
clk_1k <= 0;
end
else
if( cnt >=25000)
begin
cnt <= 0;
clk_1k <= ~clk_1k;
end
else
cnt <= cnt + 1'b1;
end
always @ (posedge clk_1k or negedge rst_n)
begin
if(!rst_n)
begin
state <= 3'd0;
num_temp <= 5'b0_0000;
num_temp1 <= 5'b0_0000;
real_num <= 5'b0_0000;
key_en <= 0;
end
else
begin
case(state)
0: begin
num_temp <= key_num;
state <= 1;
end
1: begin
num_temp <= key_num;
num_temp1 <= num_temp;
state <= 2;
end
2: begin /******************比较检测到的key_num,相同则继续,不同则返回0状态**********************/
if(num_temp1 == num_temp)
begin
num_temp <= key_num;
num_temp1 <= num_temp;
state <= 3;
end
else
state <= 0;
end
3: begin
if(num_temp1 == num_temp)
begin
num_temp <= key_num;
num_temp1 <= num_temp;
state <= 4;
end
else
state <= 0;
end
4: begin
if(num_temp1 == num_temp)
begin
num_temp <= key_num;
num_temp1 <= num_temp;
state <= 5;
end
else
state <= 0;
end
5: begin
if(num_temp1 == num_temp)
begin
num_temp <= key_num;
num_temp1 <= num_temp;
state <= 6;
end
else
state <= 0;
end
6: begin
if(num_temp1 == num_temp)
begin
num_temp <= key_num;
num_temp1 <= num_temp;
state <= 7;
end
else
state <= 0;
end
7: begin
if(num_temp1 == num_temp)
begin
num_temp <= key_num;
num_temp1 <= num_temp;
state <= 8;
end
else
state <= 0;
end
8: begin
if(num_temp1 == num_temp)
begin
num_temp <= key_num;
num_temp1 <= num_temp;
state <= 9;
end
else
state <= 0;
end
9: begin
if(num_temp1 == num_temp)
begin
num_temp <= key_num;
num_temp1 <= num_temp;
state <= 10;
end
else
state <= 0;
end
10: begin
if(num_temp1 == num_temp)
begin
num_temp <= key_num;
num_temp1 <= num_temp;
state <= 11;
end
else
state <= 0;
end
11: begin
if(num_temp1 == num_temp)
begin
num_temp <= key_num;
num_temp1 <= num_temp;
state <= 12;
end
else
state <= 0;
end
12: begin
if(num_temp1 == num_temp)
begin
num_temp <= key_num;
num_temp1 <= num_temp;
state <= 13;
end
else
state <= 0;
end
13: begin
if(num_temp1 == num_temp)
begin
num_temp <= key_num;
num_temp1 <= num_temp;
state <= 14;
end
else
state <= 0;
end
14: begin
if(num_temp1 == num_temp)
begin
num_temp <= key_num;
num_temp1 <= num_temp;
state <= 15;
end
else
state <= 0;
end
15: begin/***********************经过13次比较,每次检测到的状态都一致,说明按键状态稳定*************************/
real_num <= key_num;
state <= 0;
if(key_num[4])
key_en <= 1; /**************按键使能信号,用于判断按键按下************************/
else
key_en <= 0; /**************按键使能信号,用于判断按键抬起或者没有按键按下************************/
end