矩阵键盘
Posted 晓鹏的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了矩阵键盘相关的知识,希望对你有一定的参考价值。
//功能:按键代表0~9 10个数字,按下按键led显示按下数字的二进制码,同时数码管加上该数字
/*****************************************************************************/ /*--思路:让行分别为0111 1011 1101 1110 然后检测列的状态 如果列的状态为0111 1011 1101 1110 通过矩阵按键 来让led显示二进数字*/ //错误1 行输入不稳定 错的话经常显示第一行的数据,但是第一行数据稳定 解决:消抖 //错误2:按键按下的是上一个状态 解决:松手检测 //错误三:延时20ms计算错误 //通过20ms检测一次电平的方法消抖效果更好 //当第一个按键按下的时候 temp没有加数字 但是value已经发生变换了 数码管比按键落后一个状态 // if(FLAG&&!STATE)//有键按下且完成消抖原来是这个鬼,如果是按键检测的话rcol,rROW的值还没有刷新 //错误四:第三四行,刷新数据满不如12行稳定 可能是时间比较长 将20ms消抖改成10ms消抖 module juzhenbutton ( CLK,RSTn,ROW,COL,LED,SMG1,SMG2 ); input CLK; input RSTn; input [3:0]COL; output[3:0]ROW; output [9:0]LED; output[6:0]SMG1; output[6:0]SMG2; /*************************/ reg[2:0]State;//多个状态 reg[3:0]ROW;//寄存器放行 四个寄存器 reg[9:0]Value;//储存按键码 reg FLAG;//如果FLAG为1的话表示按键按下 reg [3:0]rCOL;//储存列 reg [3:0]rROW;//储存行键值 reg CLK_10MS; parameter _0=8‘hc0,_1=8‘hf9,_2=8‘ha4,_3=8‘hb0,_4=8‘h99, _5=8‘h92,_6=8‘h82,_7=8‘hf8,_8=8‘h80,_9=8‘h90; /******************************************/ reg[19:0]Count; parameter TIME_10MS=20‘d499_999; [email protected](posedge CLK or negedge RSTn) if(!RSTn) begin CLK_10MS<=1‘b0; Count<=20‘d0; end else if(Count==TIME_10MS) begin CLK_10MS<=~CLK_10MS; Count<=20‘d0; end else Count<=Count+1‘b1; /**********************************/ //定时器20ms /* reg[19:0]Count1; reg isCount;//是否开始计数 //parameter TIME_20MS=20‘d999_999; [email protected](posedge CLK or negedge RSTn) if(!RSTn) Count1<=20‘d0; else if(Count1==TIME_20MS) Count1<=20‘d0; else if(isCount) Count1<=Count1+1‘b1; else if(!isCount) Count1<=20‘b0; /*********************************/ /*-----检测各行-----*/ [email protected](posedge CLK_10MS or negedge RSTn) if(!RSTn) begin State<=3‘d0; ROW<=4‘b0000; //isCount<=1‘b0; rROW<=4‘b1111; rCOL<=4‘b1111; end else case(State) 3‘d0: begin FLAG<=1‘b0; ROW<=4‘b0000; if(COL!=4‘b1111)//说明有键按下 begin //if(Count==TIME_20MS) //begin FLAG<=1‘b1;//有键按下 State<=3‘d1;//检测第一行 ROW<=4‘b1110; //isCount<=1‘b0; // end // else isCount<=1‘b1; end else State<=3‘d0; end 3‘d1: begin if(COL!=4‘b1111&&ROW==4‘b1110)//第一行有键按下 begin State<=3‘d5; //FLAG<=1‘b1; // rCOL<=COL;//锁存键值 // rROW<=ROW; end else begin State<=3‘d2;//检测第二行 ROW<=4‘b1101; end end 3‘d2: begin if(COL!=4‘b1111&&ROW==4‘b1101)//第二行有键按下 begin State<=3‘d5; // FLAG<=1‘b1; //rCOL<=COL; //rROW<=ROW; end else begin State<=3‘d3; ROW<=4‘b1011; end end 3‘d3: begin if(COL!=4‘b1111&&ROW==4‘b1011)//第三行有键按下 begin State<=3‘d5; // FLAG<=1‘b1; //rCOL<=COL; //rROW<=ROW; end else begin State<=3‘d4; ROW<=4‘b0111; end end 3‘d4: begin if(COL!=4‘b1111&&ROW==4‘b0111)//第四行有键按下 begin State<=3‘d5; //FLAG<=1‘b1; //rCOL<=COL; // rROW<=ROW; end else State<=3‘d0; end 3‘d5: if(COL!=4‘b1111) begin rCOL<=COL;//锁存键值 rROW<=ROW; FLAG<=1‘b1;//有键按下 State<=3‘d5;//FLAG保持一个时钟/ end else begin State<=3‘d0; FLAG<=1‘b0; end default: begin FLAG<=1‘b0; State<=1‘b0; end endcase reg[7:0] TEMP;//要计算到99 //reg[7:0]TEMP1;//储存TEMP reg STATE;//flag的前一状态 [email protected](posedge CLK or negedge RSTn) if(!RSTn) begin Value<=10‘d0; TEMP<=7‘d0; // TEMP1<=7‘d0; STATE<=1‘b0; end else if(TEMP>=7‘d100)//如果大于等于100清0 TEMP<=7‘d0; else begin STATE<=FLAG; //把flag的状态赋值给STATE if(!FLAG&&STATE)//有键按下且完成消抖 begin begin //STATE_Value<=1‘b1; case({rCOL,rROW}) 8‘b11101110:begin Value<=4‘d0; TEMP<=TEMP+1‘b0; end 8‘b11011110:begin Value<=4‘d1; TEMP<=TEMP+1‘b1; end 8‘b10111110:begin Value<=4‘d2; TEMP<=TEMP+2‘d2; end 8‘b01111110:begin Value<=4‘d3; TEMP<=TEMP+2‘d3; end 8‘b11101101:begin Value<=4‘d4; TEMP<=TEMP+3‘d4; end 8‘b11011101:begin Value<=4‘d5; TEMP<=TEMP+3‘d5; end 8‘b10111101:begin Value<=4‘d6; TEMP<=TEMP+3‘d6; end 8‘b01111101:begin Value<=4‘d7; TEMP<=TEMP+3‘d7; end 8‘b11101011:begin Value<=4‘d8; TEMP<=TEMP+4‘d8; end 8‘b11011011:begin Value<=4‘d9; TEMP<=TEMP+4‘d9; end 8‘b10111011:begin Value<=4‘d10;TEMP<=TEMP+4‘d10;end 8‘b01111011:begin Value<=4‘d11;TEMP<=TEMP+4‘d11;end 8‘b11100111:begin Value<=4‘d12;TEMP<=TEMP+4‘d12;end 8‘b11010111:begin Value<=4‘d13;TEMP<=TEMP+4‘d13;end 8‘b10110111:begin Value<=4‘d14;TEMP<=TEMP+4‘d14;end 8‘b01110111:begin Value<=4‘d15;TEMP<=TEMP+4‘d15;end default: begin Value<=4‘d0;TEMP<=TEMP ; end endcase //TEMP1<=TEMP; end //else isCount<=1‘b1;//开始计数 end end reg[7:0] rSMG1; [email protected](posedge CLK or negedge RSTn) if(!RSTn) rSMG1[7:0]<=8‘hff; else case(TEMP%10) 4‘d0:rSMG1<=_0; 4‘d1:rSMG1<=_1; 4‘d2:rSMG1<=_2; 4‘d3:rSMG1<=_3; 4‘d4:rSMG1<=_4; 4‘d5:rSMG1<=_5; 4‘d6:rSMG1<=_6; 4‘d7:rSMG1<=_7; 4‘d8:rSMG1<=_8; 4‘d9:rSMG1<=_9; default:rSMG1<=_0; endcase reg[7:0] rSMG2; [email protected](posedge CLK or negedge RSTn) if(!RSTn) rSMG2[7:0]<=8‘hff; else case(TEMP/10) 4‘d0:rSMG2<=_0; 4‘d1:rSMG2<=_1; 4‘d2:rSMG2<=_2; 4‘d3:rSMG2<=_3; 4‘d4:rSMG2<=_4; 4‘d5:rSMG2<=_5; 4‘d6:rSMG2<=_6; 4‘d7:rSMG2<=_7; 4‘d8:rSMG2<=_8; 4‘d9:rSMG2<=_9; default:rSMG2<=_0; endcase /********************************/ assign LED=Value; assign SMG1=rSMG1; assign SMG2=rSMG2; endmodule
以上是关于矩阵键盘的主要内容,如果未能解决你的问题,请参考以下文章