矩阵键盘

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=8hc0,_1=8hf9,_2=8ha4,_3=8hb0,_4=8h99, _5=8h92,_6=8h82,_7=8hf8,_8=8h80,_9=8h90; /******************************************/ reg[19:0]Count; parameter TIME_10MS=20d499_999; [email protected](posedge CLK or negedge RSTn) if(!RSTn) begin CLK_10MS<=1b0; Count<=20d0; end else if(Count==TIME_10MS) begin CLK_10MS<=~CLK_10MS; Count<=20d0; end else Count<=Count+1b1; /**********************************/ //定时器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<=3d0; ROW<=4b0000; //isCount<=1‘b0; rROW<=4b1111; rCOL<=4b1111; end else case(State) 3d0: begin FLAG<=1b0; ROW<=4b0000; if(COL!=4b1111)//说明有键按下 begin //if(Count==TIME_20MS) //begin FLAG<=1b1;//有键按下 State<=3d1;//检测第一行 ROW<=4b1110; //isCount<=1‘b0; // end // else isCount<=1‘b1; end else State<=3d0; end 3d1: begin if(COL!=4b1111&&ROW==4b1110)//第一行有键按下 begin State<=3d5; //FLAG<=1‘b1; // rCOL<=COL;//锁存键值 // rROW<=ROW; end else begin State<=3d2;//检测第二行 ROW<=4b1101; end end 3d2: begin if(COL!=4b1111&&ROW==4b1101)//第二行有键按下 begin State<=3d5; // FLAG<=1‘b1; //rCOL<=COL; //rROW<=ROW; end else begin State<=3d3; ROW<=4b1011; end end 3d3: begin if(COL!=4b1111&&ROW==4b1011)//第三行有键按下 begin State<=3d5; // FLAG<=1‘b1; //rCOL<=COL; //rROW<=ROW; end else begin State<=3d4; ROW<=4b0111; end end 3d4: begin if(COL!=4b1111&&ROW==4b0111)//第四行有键按下 begin State<=3d5; //FLAG<=1‘b1; //rCOL<=COL; // rROW<=ROW; end else State<=3d0; end 3d5: if(COL!=4b1111) begin rCOL<=COL;//锁存键值 rROW<=ROW; FLAG<=1b1;//有键按下 State<=3d5;//FLAG保持一个时钟/ end else begin State<=3d0; FLAG<=1b0; end default: begin FLAG<=1b0; State<=1b0; 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<=10d0; TEMP<=7d0; // TEMP1<=7‘d0; STATE<=1b0; end else if(TEMP>=7d100)//如果大于等于100清0 TEMP<=7d0; else begin STATE<=FLAG; //把flag的状态赋值给STATE if(!FLAG&&STATE)//有键按下且完成消抖 begin begin //STATE_Value<=1‘b1; case({rCOL,rROW}) 8b11101110:begin Value<=4d0; TEMP<=TEMP+1b0; end 8b11011110:begin Value<=4d1; TEMP<=TEMP+1b1; end 8b10111110:begin Value<=4d2; TEMP<=TEMP+2d2; end 8b01111110:begin Value<=4d3; TEMP<=TEMP+2d3; end 8b11101101:begin Value<=4d4; TEMP<=TEMP+3d4; end 8b11011101:begin Value<=4d5; TEMP<=TEMP+3d5; end 8b10111101:begin Value<=4d6; TEMP<=TEMP+3d6; end 8b01111101:begin Value<=4d7; TEMP<=TEMP+3d7; end 8b11101011:begin Value<=4d8; TEMP<=TEMP+4d8; end 8b11011011:begin Value<=4d9; TEMP<=TEMP+4d9; end 8b10111011:begin Value<=4d10;TEMP<=TEMP+4d10;end 8b01111011:begin Value<=4d11;TEMP<=TEMP+4d11;end 8b11100111:begin Value<=4d12;TEMP<=TEMP+4d12;end 8b11010111:begin Value<=4d13;TEMP<=TEMP+4d13;end 8b10110111:begin Value<=4d14;TEMP<=TEMP+4d14;end 8b01110111:begin Value<=4d15;TEMP<=TEMP+4d15;end default: begin Value<=4d0;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]<=8hff; else case(TEMP%10) 4d0:rSMG1<=_0; 4d1:rSMG1<=_1; 4d2:rSMG1<=_2; 4d3:rSMG1<=_3; 4d4:rSMG1<=_4; 4d5:rSMG1<=_5; 4d6:rSMG1<=_6; 4d7:rSMG1<=_7; 4d8:rSMG1<=_8; 4d9:rSMG1<=_9; default:rSMG1<=_0; endcase reg[7:0] rSMG2; [email protected](posedge CLK or negedge RSTn) if(!RSTn) rSMG2[7:0]<=8hff; else case(TEMP/10) 4d0:rSMG2<=_0; 4d1:rSMG2<=_1; 4d2:rSMG2<=_2; 4d3:rSMG2<=_3; 4d4:rSMG2<=_4; 4d5:rSMG2<=_5; 4d6:rSMG2<=_6; 4d7:rSMG2<=_7; 4d8:rSMG2<=_8; 4d9:rSMG2<=_9; default:rSMG2<=_0; endcase /********************************/ assign LED=Value; assign SMG1=rSMG1; assign SMG2=rSMG2; endmodule

 

以上是关于矩阵键盘的主要内容,如果未能解决你的问题,请参考以下文章

51单片机 4×4键盘矩阵控制条形LED显示+ Proteus仿真

5152单片机使用矩阵键盘

单片机入门-矩阵键盘控制数码管显示

矩阵键盘实验

矩阵键盘 4*4 arduino

疑问----单片机矩阵键盘行列反转扫描法