首页 > 代码库 > 矩阵键盘

矩阵键盘

//功能:按键代表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;always@(posedge CLK or negedge RSTn)if(!RSTn)begin CLK_10MS<=1b0; Count<=20d0;endelse 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;always@(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;/*********************************//*-----检测各行-----*/always@(posedge CLK_10MS or negedge RSTn)if(!RSTn)begin State<=3d0; ROW<=4b0000; //isCount<=1‘b0; rROW<=4b1111; rCOL<=4b1111;endelse 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 endcasereg[7:0] TEMP;//要计算到99//reg[7:0]TEMP1;//储存TEMPreg STATE;//flag的前一状态always@(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 endreg[7:0] rSMG1;always@(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; endcasereg[7:0] rSMG2;always@(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

 

矩阵键盘