(原创)矩阵键盘扫描程序详解

合集下载

矩阵键盘扫描

矩阵键盘扫描

矩阵键盘扫描1.实验目的与效果:4¡4矩阵键盘在众多场合有举足轻重的地位,所以有必要学好矩阵键盘扫描的编程。

实验板上的矩阵键盘是接单片机P2口的,以P2.4-P2.7作输出线,P2.0-P2.3作输入线;每按一个键会在数码管上显示相关的信息。

键盘上可以这样来定义,这只是个例子,用户在运用矩阵键盘键值是可以重新定义之。

2.原理图:矩阵键盘连接图3.实验板上操作:1)矩阵键盘在实验板上已经固定连接P2口了。

2)将HEX文件烧到单片机上。

3)将数码管的位选拨码开关拨到ON上。

4.实物连接图:拨码开关全部拨到ON5. C语言程序://MCU:AT89S51//晶振:12M#include"AT89X51.H"unsigned char code numcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0X88,0X83,0XC6,0XA1,0X86,0X8E,0XFF};//数字0~9及ABCDEF共阳数码管代码unsigned char code charcode[]={0xc0,0xc7,0xc7,0x86,0x89};// HELLO 字样共阳数码管代码unsigned char code bitcode[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //数码管位选代码unsigned char dispbuf[8]={16,16,16,0,1,2,3,4};unsigned char disp_bit_count;unsigned char disp_count;unsigned char temp;unsigned char key;unsigned char i,j;/********1ms延时子程序***********/delay_nms(unsigned int n){unsigned int i;unsigned char j;for(i=0;i<n;i++)for(j=0;j<120;j++); //空操作}unsigned char keyscan(void){P2=0xff;P2_4=0;temp=P2;temp=temp&0x0f;if (temp!=0x0f){delay_nms(10);temp=P2;temp=temp&0x0f;if (temp!=0x0f){temp=P2;temp=temp&0x0f;switch(temp){case 0x0e:key=7;break;case 0x0d:key=8;break;case 0x0b:key=9;break;case 0x07:key=10;break;}temp=P2;temp=temp & 0x0f;while(temp!=0x0f){temp=P2;temp=temp&0x0f;}}}P2=0xff;P2_5=0;temp=P2;temp=temp&0x0f;if (temp!=0x0f){delay_nms(10);temp=P2;temp=temp&0x0f;if (temp!=0x0f){temp=P2;temp=temp&0x0f;switch(temp){case 0x0e:key=4;break;case 0x0d:key=5;break;case 0x0b:key=6;break;case 0x07:key=11;break;}temp=P2;temp=temp & 0x0f;while(temp!=0x0f){temp=P2;temp=temp&0x0f;}}}P2=0xff;P2_6=0;temp=P2;temp=temp&0x0f;if (temp!=0x0f){delay_nms(10);temp=P2;temp=temp&0x0f;if(temp!=0x0f){temp=P2;temp=temp&0x0f;switch(temp){case 0x0e:key=1;case 0x0d:key=2;break;case 0x0b:key=3;break;case 0x07:key=12;break;}temp=P2;temp=temp&0x0f;while(temp!=0x0f){temp=P2;temp=temp&0x0f;}}}P2=0xff;P2_7=0;temp=P2;temp=temp & 0x0f;if (temp!=0x0f){delay_nms(10);temp=P2;temp=temp&0x0f;if (temp!=0x0f){temp=P2;temp=temp & 0x0f;switch(temp){case 0x0e:key=0;break;case 0x0d:key=13;break;case 0x0b:key=14;case 0x07:key=15;break;}temp=P2;temp=temp & 0x0f;while(temp!=0x0f){temp=P2;temp=temp & 0x0f;}}}return (key);}void main(void){TMOD=0x02; //使用定时器0,选择方式2(常数自动重装的8位定时器)TH0=0x06; //保存数值,用于自动重装TL0=0x06; //定时250uS初值TR0=1; //开定时器0ET0=1; //开定时器0溢出中断EA=1; //开总中断while(1){dispbuf[0]=keyscan();}}/**********T0250uS中断服务程序***************/void t0(void) interrupt 1 using 0{disp_count++;if(disp_count==8){disp_count=0;if(disp_bit_count>=3)P0=charcode[dispbuf[disp_bit_count]];elseP0=numcode[dispbuf[disp_bit_count]];P1=bitcode[disp_bit_count];disp_count=0;disp_bit_count++;if(disp_bit_count==8){disp_bit_count=0;}}}。

矩阵键盘扫描汇编程序

矩阵键盘扫描汇编程序

4*4矩阵键盘扫描汇编程序(基于51单片机)// 程序名称:4-4keyscan.asm;// 程序用途:4*4矩阵键盘扫描检测;// 功能描述:扫描键盘,确定按键值。

程序不支持双键同时按下,;// 如果发生双键同时按下时,程序将只识别其中先扫描的按键;// 程序入口:void;// 程序出口:KEYNAME,包含按键信息、按键有效信息、当前按键状态;//================================================================== ====PROC KEYCHKKEYNAME DATA 40H ;按键名称存储单元;(b7-b5纪录按键状态,b4位为有效位,;b3-b0纪录按键)KEYRTIME DATA 43H ;重复按键时间间隔SIGNAL DATA 50H ;提示信号时间存储单元KEY EQU P3 ;键盘接口(必须完整I/O口) KEYPL EQU P0.6 ;指示灯接口RTIME EQU 30 ;重复按键输入等待时间KEYCHK:;//=============按键检测程序========================================= ====MOV KEY,#0FH ;送扫描信号MOV A,KEY ;读按键状态CJNE A,#0FH,NEXT1 ;ACC<=0FH; CLR C ;Acc等于0FH,则CY为0,无须置0NEXT1:; SETB C ;Acc不等于0FH,则ACC必小于0 FH,;CY为1,无须置1MOV A,KEYNAMEANL KEYNAME,#1FH ;按键名称屏蔽高三位RRC A ;ACC带CY右移一位,纪录当前按键状态ANL A,#0E0H ;屏蔽低五位ORL KEYNAME,A ;保留按键状态;//=============判别按键状态,决定是否执行按键扫描=================== =====CJNE A,#0C0H,NEXT2 ;110按键稳定闭合,调用按键检测子程序SJMP KEYSCANNEXT2:CJNE A,#0E0H,NEXT3 ;111按键长闭合,重复输入允许判断SJMP WAITNEXT3:CJNE A,#0A0H,EXIT ;101干扰,当111长闭合处理ORL KEYNAME,#0E0HWAIT:MOV A,KEYRTIMEJNZ EXIT ;时间没到,退出;//=============键盘扫描程序========================================= =====KEYSCAN:MOV R1,#0 ;初始化列地址MOV R3,#11110111B ;初始化扫描码LOOP:MOV A,R3RL AMOV R3,A ;保留扫描码MOV KEY,A ;送扫描码MOV A,KEY ;读键盘ORL A,#0F0H ;屏蔽高四位CJNE A,#0FFH,NEXT31 ;A不等于FFH,说明该列有按键动作INC R1 ;列地址加1,准备扫描下一列CJNE R1,#4,LOOP ;列地址不等于4,扫描下一列SJMP EXIT ;没有按键,退出;//=============按键判断对应位等于零,说明该行有按键按下============= =====NEXT31:JB ACC.0,NEXT32MOV R2,#0 ;第0行有按键SJMP NEXT5NEXT32:JB ACC.1,NEXT33MOV R2,#1 ;第1行有按键SJMP NEXT5NEXT33:JB ACC.2,NEXT34MOV R2,#2 ;第2行有按键SJMP NEXT5NEXT34:MOV R2,#3 ;第3行有按键NEXT5: ;计算按键地址MOV A,R1RL ARL A ;列地址乘4(每列对应4行)ADD A,R2 ;加行地址MOV DPTR,#KEYTABMOVC A,@A+DPTRANL KEYNAME,#0E0HORL KEYNAME,A ;送按键(送值的时候已经置按键有效)MOV KEYRTIME,#RTIME ;送重复按键等待时间CLR KEYPL ;打开指示灯MOV SIGNAL,#10 ;送信号提示时间(每次按键闪10 0ms)EXIT:MOV KEY,#0FFH ;置键盘接口高电平RET ;退出;//=============按键名称表=========================================== =====KEYTAB:DB 1AH ;扫描码0,对应A ************************************ ******DB 1BH ;扫描码1,对应B ** **DB 1CH ;扫描码2,对应C ** I/O口 PX.4 PX.5 PX.6 PX.7 **DB 1DH ;扫描码3,对应D ** **DB 11H ;扫描码4,对应1 ** PX.0 A(0) 1(4) 2(8) 3 (C) **DB 14H ;扫描码5,对应4 ** **DB 17H ;扫描码6,对应7 ** PX.1 B(1) 4(5) 5(9) 6 (D) **DB 1EH ;扫描码7,对应E ** **DB 12H ;扫描码8,对应2 ** PX.2 C(2) 7(6) 8(A) 9 (E) **DB 15H ;扫描码9,对应5 ** **DB 18H ;扫描码A,对应8 ** PX.3 D(3) E(7) 0(B) F(F) **DB 10H ;扫描码B,对应0 ** **DB 13H ;扫描码C,对应3 ************************************ ******DB 16H ;扫描码D,对应6DB 19H ;扫描码E,对应9DB 1FH ;扫描码F,对应FEND第二种解法ORG 0000HSTART: MOV R0,#00H ;初始化程序,开始的延时是为了使硬件能够准备好DJNZ R0,$LOOP: MOV SP,#60HCALL KEYDISPLAY:MOV A,R4MOV DPTR,#TABLE ;定义字形表的起始地址MOVC A,@A+DPTR ;TABLE为表的起始地址MOV P2,ASJMP LOOP;子程序内容,P1口的低四位为行线,高四位为列线KEY: PUSH PSWPUSH ACCMOV P1,#0F0H ;令所有的行为低电平,全扫描字-P1.0-P1.3,列为输入方式;这一段只是验证有键按下,并不能判断是哪一行MOV R7,#0FFH ;设置计数常数,作为延时KEY1: DJNZ R7, KEY1MOV A,P1 ;读取P1口的列值ANL A,#0F0H ;判别有键值按下吗(当有键按下时,P1口的高四位就不全为1了,底四位还是都为0的);这个地方进行相或的原因,是因为要把底四位的0000变成1111,以便下一步进行求反ORL A,#0FH //这个地方原版上没有,这是又加了,如果不加的的话,是不对的********CPL A ;求反后,有高电平就有键按下JZ EKEY;累加器为0则转移(意为求反后本来全为0的,如果有键按下时,求反后高四位就有1了),退出LCALL DEL20ms ;有键按下,进行处理;下面进行行行扫描,1行1行扫SKEY: MOV A,#00HMOV R0,A ;R0作为行计数器,开始初值为0MOV R1,A ;R1作为列计数器,开始初值为0MOV R2,#0FEH ;R2作为扫描暂存字,开始初值为1111 1110,(第四位作为行扫描字)SKEY2: MOV A,R2MOV P1,A ;输出行扫描字,1111 1110NOPNOPNOP ;3个NOP操作使P1口输出稳定MOV A,P1 ;读列值(和开始一样)MOV R1,A ;暂存列值(第一次为**** 1110,既高四位有一位"可能"会为0)ANL A,#0F0H ;取高四位,ORL A,#0FH ;使第四位全部置1CPL ABIAOZHI:JNZ SKEY3 ;累加器为非0则转移指令(意思是判断到按键在这一行),转去处理INC R0 ;如果按键没在这一行,行计数器加1SETB C ;进位标志位加1,为了在左移的时候开始的低位0不在出现在低(循环一圈后)MOV A,R2RLC A ;带进位左移1位(形成下一行扫描字,再次扫描)MOV R2,AMOV A,R0;把加1后的行计数器R0和总共扫描次数(4次比较)CJNE A,#04H,SKEY2 ;(扫描完了么)书本上这个地方也有错误,书本上写的是:SKEY1AJMP EKEY ;如果没有的话,退出;有键按下后行扫描过后,此为确列行SKEY3: MOV A,R1 ;JNB ACC.4,SKEY5 ;直接寻址位为0咋转移指令JNB ACC.5,SKEY6JNB ACC.6,SKEY7JNB ACC.7,SKEY8AJMP EKEY //我自己感觉到这命令没有用处SKEY5: MOV A,#00H ;存0列号MOV R3,AAJMP DKEYSKEY6: MOV A,#01H ;存1列号MOV R3,AAJMP DKEYSKEY7: MOV A,#02H ;存2列号MOV R3,AAJMP DKEYSKEY8: MOV A,#03H ;存3列号MOV R3,AAJMP DKEY;取出具体的行号,再加上列号,最终确认按键的号码DKEY: //MOV R4,#00HMOV A,R0MOV B,#04HMUL AB ;让行号*4,第四位放在A中(总共就4行,相乘后一定<16,也就是只有第四位有值)ADD A,R3 ;让行号和列号相加,最终确认任按键的具体号MOV R4,AEKEY: POP ACCPOP PSWRET ;按键扫描处理函数DEL20ms:MOV R7,#2DL2: MOV R6,#18DL1: MOV R5,#255DJNZ R5,$DJNZ R6,DL1DJNZ R7,DL2RET;此为共阴极数码管的数字表TABLE: DB 3FH ;0DB 06H ;1DB 5BH ;2DB 4FH ;3DB 66H ;4DB 6DH ;5DB 7DH ;6DB 27H ;7DB 7FH ;8DB 6FH ;9DB 77HDB 7CHDB 39HDB 5EHDB 79HDB 71HEND第三种PIC单片机键盘扫描汇编程序;本程序用于PIC外接键盘的识别,通过汇编程序,使按下K1键时第一个数码管显示1,按下K2键时第一;个数码管上显示2,按下K3键时第一个数码管上显示3,按下K4键时第一个数码管上显示4,;汇编程序对键盘的扫描采用查询方式LIST P=18F458INCLUDE "P18F458.INC";所用的寄存器JIANR EQU 0X20FLAG EQU JIANR+1 ;标志寄存器DEYH EQU JIANR+2DEYL EQU JIANR+3F0 EQU 0 ;FLAG的第0位定义为F0ORG 0X00GOTO MAINORG 0X30;*************以下为键盘码值转换表****************** CONVERT ADDWF PCL,1RETLW 0XC0 ;0,显示段码与具体的硬件连接有关RETLW 0XF9 ;1RETLW 0XA4 ;2RETLW 0XB0 ;3RETLW 0X99 ;4RETLW 0X92 ;5RETLW 0X82 ;6RETLW 0XD8 ;7RETLW 0X80 ;8RETLW 0X90 ;9RETLW 0X88 ;ARETLW 0X83 ;BRETLW 0XC6 ;CRETLW 0XA1 ;DRETLW 0X86 ;ERETLW 0X8E ;FRETLW 0X7F ;"."RETLW 0XBF ;"-"RETLW 0X89 ;HRETLW 0XFF ;DARKRETURN;***************PIC键盘扫描汇编程序初始化子程序***************** INITIALBCF TRISA,5 ;置RA5为输出方式,以输出锁存信号BCF TRISB,1BCF TRISA,3BCF TRISE,0BCF TRISE,1BSF TRISB,4 ;设置与键盘有关的各口的输入输出方式BCF TRISC,5BCF TRISC,3 ;设置SCK与SDO为输出方式BCF INTCON,GIE ;关闭所有中断LW 0XC0WF SSPSTAT ;设置SSPSTAT寄存器LW 0X30WF SSPCON1 ;设置SPI的控制方式,允许SSP方式,并且时钟下降;沿发送数据,与"74HC595当其SCLK从低到高电平;跳变时,串行输入数据(DI)移入寄存器"的特点相对应LW 0X01WF JIANR ;显示值寄存器(复用为键值寄存器)赋初值CLRF FLAG ;清除标志寄存器RETURN ;返回;**************显示子程序*****************DISPLAYCLRF PORTAWF SSPBUFAGAINBTFSS PIR1,SSPIFGOTO AGAINNOPBCF PIR1,SSPIFBSF PORTA,5 ;详细的程序语句请参考 pic教程语句部分,可在首页搜索。

单片机矩阵键盘扫描的两种方式

单片机矩阵键盘扫描的两种方式

单片机矩阵键盘扫描的两种方式单片机矩阵键盘扫描的两种方式矩阵键盘扫描方式:第一种:逐行扫描法,就是一行一行的扫描。

实现代码如下(键盘连接P2口):#define NO_KEY 0XFF#define KEY_LO() P2 &= 0XF0#define KEY_HI() P2 |= 0X0F#define KEY_L(i) P2 &= ~(1<<i)#define KEY_RD() ((P2>>4) & 0x0f)UINT8 OnceKey(void){UINT8 line = 0;UINT8 key = NO_KEY;//key valueKEY_LO();if (KEY_RD() == 0X0F){KEY_HI();return NO_KEY;}for (line=0; line<4; line ++){KEY_HI();KEY_L(line);key = KEY_RD();switch (key){case ROW_FIRST:key = 4*line + 0;break;case ROW_SECOND:key = 4*line + 1;break;case ROW_THIRD:key = 4*line + 2;break;case ROW_FOURTH:key = 4*line +3;break;default :key = 0x0f;break;}if (key < 0x10){return key;}}return NO_KEY;}第二种,线性反转法。

就是行和列分别读出。

实现代码如下:#define CVT(i) ((i)==(~1)&0x0f)? 0: ((i)==(~2)&0x0f)? 1: ((i)==(~4)&0x0f)? 2: ((i)==(~8)&0x0f)? 3: 4;#define KEY0_3HI() P2 |= 0X0F#define KEY0_3LO() P2 &= 0XF0#define KEY4_7HI() P2 |= 0XF0#define KEY4_7LO() P2 &= 0X0F#define KEY0_3RD() (P2 & 0X0F)#define KEY4_7RF() ((P2>>4) & 0X0F)UINT8 OnceKey(void){UINT8 line = NO_KEY;UINT8 row = NO_KEY;UINT8 key;KEY0_3HI();KEY4_7LO();line = KEY0_3RD();//读入行的值if (0x0f == line){key = NO_KEY;}else{KEY0_3LO();KEY4_7HI();row = KEY4_7RD();//读入列的值if (0x0f == row){key = NO_KEY;}else{key = CVT(line)*4 + CVT(row);}}KEY0_3HI();KEY4_7HI();return key; }。

键盘扫描

键盘扫描
case 0xf7: managekey3();break;
case 0xef: managekey4();break;
case 0xdf: managekey5();break;
case 0xbf: managekey6();break;
* P1.0-P1.3为列线,P1.4-P1.7为行线 *
* 喇叭接P3.7口 矩阵键盘P1口, 数码管数据P0口,数码管控制P2口 *
* *
}
//--------------------------------------------------
main()
{
P0=0xFF; //置P0口
P2=0xFF; //置P2口
dis_buf=0xBF;
while(1)
temp=temp&0x0F;
temp=~(temp|0xF0);
if(temp==1)
key=0;
else if(temp==2)
key=1;
else if(temp==4)
key=2;
else if(temp==8)
else
{ for(a=0;a<4;a++)
P1=0xF0;
if(P1!=0xF0)
{
keyscan();
beep();
// while(P1!=0xF0); //等待键释放
}
}
//--------------------------------------------------
void beep()
}
//--------------------------------------------------

51单片机数码管显示及矩阵键盘扫描程序

51单片机数码管显示及矩阵键盘扫描程序

51单片机数码管显示及矩阵键盘扫描程序硬件实验十一八段数码管实验一、实验任务1、在静态数码管上轮流显示数字0-9。

2、在两个4位数码管上动态显示数字0-9二、流程图及程序静态显示:流程图:程序代码:#include#define uchar unsigned chucharcodevalue[10]={0xC0,0xF9,0xA4,0xB0,0X99,0x92,0x82,0xF8,0 x80,0x90};//0 -9数码管显示段码void delay(char x) //延时子程序{uchar i;for(i=0;i<200;i++);}main() //主函数{int i;while(1){for(i=0;i<10;i++) //显示0-9{P0=codevalue[i];delay(500); //延时1秒}}}动态显示:#include#includetab1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7D,0x07,0x7f,0x6f}; //数码管显示数字字段unsigned char tab2[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//片选字段unsigned char i,k,j,x;void delay(x); //声明延时子函数void main() //主函数{while(1){for(i=0;i<8;i++) //显示0-7{ P1=tab1[i];P0=tab2[i];delay(5); //延时}P1=tab1[8]; P0=tab2[0]; delay(5); //显示8-9P1=tab1[9]; P0=tab2[1]; delay(5);}}void delay(x) //延时函数定义{do{for(j=0;j<250;j++)for(k=0;k<250;k++);}}硬件实验十二矩阵键盘扫描显示一、实验任务1、把矩阵键盘上的按键输入的键码在静态数码管上显示出来。

矩阵键盘过程及扫描程序

矩阵键盘过程及扫描程序

键盘是单片机常用输入设备,在按键数量较多时,为了节省I/O口等单片机资源,一般采取扫描的方式来识别到底是哪一个键被按下。

即通过确定被按下的键处在哪一行哪一列来确定该键的位置,获取键值以启动相应的功能程序。

矩阵键盘的四列依次接到单片机的P1.0~P1.3,四行依次接到单片机的P1.4~P1.7;同时,将列线上拉,通过10K电阻接电源。

查找哪个按键被按下的方法为:一个一个地查找。

先第一行输出0,检查列线是否非全高;否则第二行输出0,检查列线是否非全高;否则第三行输出0,检查列线是否非全高;如果某行输出0时,查到列线非全高,则该行有按键按下;根据第几行线输出0与第几列线读入为0,即可判断在具体什么位置的按键按下。

下面是具体程序:void Check_Key(void){unsigned char row,col,tmp1,tmp2;tmp1 = 0x10;//tmp1用来设置P1口的输出,取反后使P1.4~P1.7中有一个为0for(row=0;row<4;row++) // 行检测{P1 = 0x0f; // 先将p1.4~P1.7置高P1 =~tmp1; // 使P1.4~p1.7中有一个为0tmp1*=2; // tmp1左移一位if ((P1 & 0x0f) < 0x0f)// 检测P1.0~P1.3中是否有一位为0,只要有,则说明此行有键按下,进入列检测{tmp2 = 0x01; // tmp2用于检测出哪一列为0for(col =0;col<4;col++) // 列检测{if((P1 & tmp2)==0x00)// 该列如果为低电平则可以判定为该列{key_val =key_Map[ row*4 +col ];// 获取键值,识别按键;key_Map为按键的定义表return; // 退出循环}tmp2*=2; // tmp2左移一位}}}} //结束。

3x4矩阵键盘的扫描程序

3x4矩阵键盘的扫描程序

3x4矩阵键盘的扫描程序(C语言)#includeunsigned char code table[]={0xC0,0xF9,0xA4,0xB0,0x99, //0~4 0x92,0x82,0xF8,0x80,0x90, //5~90x88,0x83,0xA7,0xA1,0x86,0x8E}; //A~Fvoid KeyScan();void delay10ms(unsigned char time);void Dispaly(unsigned char k);unsigned char key,temp;void main() //主程序{while(1){KeyScan();}}void KeyScan() //按键扫描子程序{P1=0xFF;P1_3=0;temp=P1;temp&=0xF0;if(temp !=0xF0){delay10ms(1);temp=P1;temp&=0xF0;if(temp !=0xF0){temp=P1;temp&=0xF0;switch(temp){case 0x70:key=1;break;case 0xB0:key=2;break;case 0xD0:key=3;break;}}}P1=0xFF;P1_2=0;temp=P1;temp&=0xF0;if(temp !=0xF0) {delay10ms(1); temp=P1; temp&=0xF0; if(temp !=0xF0) {temp=P1; temp&=0xF0;switch(temp) {case 0x70:key=4;break; case 0xB0:key=5;break; case 0xD0:key=6;break; }Dispaly(key); }}P1=0xFF;P1_1=0;temp=P1;temp&=0xF0;if(temp !=0xF0) {delay10ms(1); temp=P1; temp&=0xF0; if(temp !=0xF0) {temp=P1; temp&=0xF0;switch(temp) {case 0x70:case 0xB0:key=8;break;case 0xD0:key=9;break;}Dispaly(key);}}P1=0xFF;P1_0=0;temp=P1;temp&=0xF0;if(temp !=0xF0){delay10ms(1);temp=P1;temp&=0xF0;if(temp !=0xF0){temp=P1;temp&=0xF0;switch(temp){case 0x70:key=14;break;case 0xB0:key=0;break;case 0xD0:key=15;break;}Dispaly(key);}}}//延时程序void delay10ms(unsigned char time) {unsigned char a,b,c;for(a=0;a for(b=0;b<10;b++)for(c=0;c<120;c++);}void Dispaly(unsigned char k) //显示程序{P0=table[k];P2_1=0;}流水广告灯设计程序利用取表的方法,使端口P1做单一灯的变化:左移2次,右移2次,闪烁2次(延时的时间0.2秒)。

矩阵键盘扫描程序

矩阵键盘扫描程序
int lie; //define 列
int keyscan();
void delay(int x);
void main()
{
int key;
while(1) //scan the keybord in loop
{
P1=0xf0; //P1 must have a initial value
key=00; //reset the key signal
delay(1000);
P2=0xff; //put out the LED
delay(1000);
}
}
void delay(int x) //the delay subprogram
case 2:
return k42;
break;
case 3:
return k43;
break;
case 4:
return k44;
break;
default:
break;
}
}
while( (P1&0x0f) !=0x0f);
return hang*10+lie; /*用int作为键盘返回值得好处,有一个干净的算式直接得到结果,
不像下面被屏蔽掉的那部分一样冗余。*/
/* switch (hang) //同时取出行列信号,确定哪个按键被按下,并把他作为返回值
break;
default:
break;
}
break;
case 4: //行4
switch (lie)
{
case 1:
return k41;

矩阵式键盘的按键识别方法

矩阵式键盘的按键识别方法

矩阵式键盘的按键识别方法矩阵式键盘是一种常见的电子输入设备,它由多个按键组成,这些按键以矩阵的形式排列在键盘上。

在使用矩阵式键盘时,我们需要将按下的按键与相应的键值进行关联,以实现按键的识别。

下面将介绍几种常见的矩阵式键盘按键识别方法。

1.矩阵扫描法矩阵扫描法是最常见的一种按键识别方法。

在矩阵式键盘上,按键被组织成不同的行和列。

通过扫描每一行和每一列,我们可以确定按下的按键。

具体操作步骤如下:-所有行设置为输出,所有列设置为输入。

-循环扫描每一行,将当前行设置为高电平,然后读取所有列的状态。

-如果其中一列的状态为低电平,说明当前位置的按键被按下。

-记录下按下按键的位置(行和列),以及对应的键值。

2.矩阵编码法矩阵编码法是一种较为高级的按键识别方法,它通过给每个按键分配一个唯一的编码,以实现按键的识别。

具体操作步骤如下:-所有行和列都需要连接到对应的编码器上。

-当按键被按下时,编码器会生成一个唯一的编码,表示按下的按键。

-通过读取编码器的输出,我们可以确定按下的按键以及对应的键值。

3.容量触摸法除了物理按键,一些矩阵式键盘还具有触摸功能。

这种键盘使用触摸传感器来检测手指触摸的位置,以实现按键的识别。

具体操作步骤如下:-键盘上的每个按键都带有一个触摸传感器。

-当手指触摸一些按键时,触摸传感器会检测到电容的变化。

-根据电容的变化,我们可以确定手指触摸的位置,从而确定按下的按键以及对应的键值。

总结起来,矩阵式键盘的按键识别方法可以通过矩阵扫描法、矩阵编码法和容量触摸法来实现。

无论采用哪种方法,都需要通过适当的硬件和软件设计来实现按键的检测和识别。

这些方法的选择通常取决于键盘的设计要求和成本限制。

矩阵键盘的三种扫描方法

矩阵键盘的三种扫描方法

矩阵键盘的三种扫描方法矩阵键盘是一种常见的输入设备,它由多个按键组成,并通过矩阵扫描的方式来检测用户的按键输入。

矩阵键盘的扫描方法可以分为三种:行扫描、列扫描和交错扫描。

下面将详细介绍这三种扫描方法。

1.行扫描行扫描是最简单的一种扫描方法。

它的原理是将矩阵键盘的每一行连接到一个IO口,通过轮询检测每一行的电平变化来获取用户的按键输入。

行扫描的工作流程如下:1)将矩阵键盘的每一行连接到一个IO口,并设置为输入模式。

2)逐个地将每一行的IO口设置为高电平,并检测列的电平状态。

3)如果其中一列的电平为低电平,说明该列有按键按下。

此时,记录下这个按键的位置(行号和列号)以及按键的值(键码或字符),然后将这个按键的位置和值传递给上层应用或处理器。

4)将当前行的IO口设置为低电平,然后继续下一行的检测,重复2)~3)步骤,直到所有行都被检测完毕。

行扫描的优点是实现简单,只需要一个IO口来检测按键的状态。

但是它的缺点是扫描速度较慢,因为需要逐个地检测每一行。

2.列扫描列扫描是一种比较常用的扫描方法。

它的原理是将矩阵键盘的每一列连接到一个IO口,通过轮询检测每一列的电平变化来获取用户的按键输入。

列扫描的工作流程如下:1)将矩阵键盘的每一列连接到一个IO口,并设置为输入模式。

2)逐个地将每一列的IO口设置为高电平,并检测行的电平状态。

3)如果其中一行的电平为低电平,说明该行有按键按下。

此时,记录下这个按键的位置(行号和列号)以及按键的值(键码或字符),然后将这个按键的位置和值传递给上层应用或处理器。

4)将当前列的IO口设置为低电平,然后继续下一列的检测,重复2)~3)步骤,直到所有列都被检测完毕。

列扫描的优点是速度较快,因为只需要逐个地检测每一列。

但是它的缺点是需要多个IO口来检测按键的状态。

3.交错扫描交错扫描是一种综合了行扫描和列扫描的扫描方法,它可以有效地减少扫描的时间。

交错扫描的原理是将矩阵键盘的行和列交错地连接到多个IO口,通过并行检测行和列的电平变化来获取用户的按键输入。

经典的矩阵键盘扫描程序

经典的矩阵键盘扫描程序

经典的矩阵键盘扫描程序矩阵键盘是一种常见的输入设备,广泛应用于电子产品中。

为了实现对矩阵键盘的扫描和输入响应,需要编写一个矩阵键盘扫描程序。

本文将详细介绍如何编写一个经典的矩阵键盘扫描程序。

1. 程序功能描述矩阵键盘扫描程序的主要功能是实现对矩阵键盘的扫描,并根据按键的状态进行相应的处理。

程序需要实现以下功能:- 扫描矩阵键盘的按键状态;- 根据按键状态进行相应的处理;- 输出按键的值或执行相应的操作。

2. 程序设计思路矩阵键盘通常由多行多列的按键组成,每个按键都有一个唯一的行列地址。

程序的设计思路如下:- 初始化矩阵键盘的引脚和状态变量;- 循环扫描矩阵键盘的按键状态;- 检测按键状态变化,并根据变化进行相应的处理;- 输出按键的值或执行相应的操作。

3. 程序代码示例下面是一个简单的矩阵键盘扫描程序的代码示例:```#include <stdio.h>#include <stdbool.h>// 定义矩阵键盘的行列数#define ROWS 4#define COLS 4// 定义矩阵键盘的引脚int rowPins[ROWS] = {2, 3, 4, 5}; int colPins[COLS] = {6, 7, 8, 9}; // 定义矩阵键盘的按键值char keys[ROWS][COLS] = {{'1', '2', '3', 'A'},{'4', '5', '6', 'B'},{'7', '8', '9', 'C'},{'*', '0', '#', 'D'}};// 初始化矩阵键盘void setup() {// 设置引脚模式为输入for (int i = 0; i < ROWS; i++) { pinMode(rowPins[i], INPUT); }// 设置引脚模式为输出for (int i = 0; i < COLS; i++) {pinMode(colPins[i], OUTPUT);}}// 扫描矩阵键盘void scanKeypad() {for (int i = 0; i < COLS; i++) {// 将当前列引脚设置为高电平digitalWrite(colPins[i], HIGH);for (int j = 0; j < ROWS; j++) {// 检测当前行引脚的状态bool state = digitalRead(rowPins[j]); // 如果按键状态发生变化if (state != lastState[i][j]) {// 更新按键状态lastState[i][j] = state;// 如果按键被按下if (state == LOW) {// 输出按键的值Serial.println(keys[j][i]);// 执行相应的操作switch (keys[j][i]) {case '1':// 执行操作1break;case '2':// 执行操作2break;// 其他按键的操作}}}}// 将当前列引脚设置为低电平 digitalWrite(colPins[i], LOW); }}void loop() {// 扫描矩阵键盘scanKeypad();// 延时一段时间,避免频繁扫描delay(10);}```4. 程序运行结果编写完成矩阵键盘扫描程序后,可以将程序上传到相应的开发板或单片机上进行测试。

51单片机的矩阵按键扫描的设计C语言程序

51单片机的矩阵按键扫描的设计C语言程序

51单片机的矩阵按键扫描的设计C语言程序以下为一个基于51单片机的矩阵按键扫描的设计C语言程序:```c#include <reg51.h>//定义端口连接到矩阵键盘sbit col1 = P2^0;sbit col2 = P2^1;sbit col3 = P2^2;sbit row1 = P2^3;sbit row2 = P2^4;sbit row3 = P2^5;sbit row4 = P2^6;//声明按键函数char read_keypad(;void maiwhile (1)char key = read_keypad(; // 读取按键值//根据按键值进行相应操作switch(key)case '1'://第一行第一列按键逻辑//在此处添加相应的代码break;case '2'://第一行第二列按键逻辑//在此处添加相应的代码break;//继续处理其他按键//...default://未识别到按键break;}}//按键扫描函数char read_keypacol1 = 0; col2 = 1; col3 = 1; // 激活第一列if (row1 == 0) { // 第一行第一列按键被按下while (row1 == 0); //等待按键释放return '1'; // 返回按键值}if (row2 == 0) { // 第二行第一列按键被按下while (row2 == 0); //等待按键释放return '4'; // 返回按键值}if (row3 == 0) { // 第三行第一列按键被按下while (row3 == 0); //等待按键释放return '7'; // 返回按键值}if (row4 == 0) { // 第四行第一列按键被按下while (row4 == 0); //等待按键释放return '*'; // 返回按键值}col1 = 1; col2 = 0; col3 = 1; // 激活第二列//处理第二列的按键逻辑//...col1 = 1; col2 = 1; col3 = 0; // 激活第三列//处理第三列的按键逻辑//...return '\0'; // 返回空字符表示未检测到按键```以上代码中,我们使用51单片机的P2端口连接到矩阵键盘的列和行,通过扫描不同的列和检测行的状态来判断按键是否被按下。

矩阵键盘扫描程序

矩阵键盘扫描程序
while((P2&0x0f)!=0x0f);
}
P2=0xef; //扫描第四行
temp=P2&0x0f;
if(temp!=0x0f)
{
demp=P2&0x0f;
if(temp!=0x0f)
case(0x0e):
key=15;
break;
}
}
while((P2&0x0f)!=0x0f);
}
return(key);
}
//===============================================================
key=3;
break;
}
}
while((P2&0x0f)!=0x0f); //等待按键抬起
}
P2=0xbf; //扫描第二行
temp=P2&0x0f;
if(temp!=0x0f)
{
delay(1000);
//硬件连接:4*4键盘的8个引脚接51的P2口
#include<reg51.h>
//***********************以下为函数声明部分*****************
void delay(unsigned int us);
unsigned char keyscan(void);
//入口参数:无
//出口参数:无
//===============================================================
int main(void)

概述矩阵式按键行列扫描过程

概述矩阵式按键行列扫描过程

1111
矩阵式按键行列扫描的过程是这样的:
1. 把属于列的IO口设置为输入状态,由于上拉电阻的作用,当按键没有动作时,程序就会读到高电平。

2. 开始按行进行扫描,先把行1的IO设置为输出状态,然后设置输出为低电平,接着依次读取列IO口的状态。

3. 如果有按键被按下,那么列IO口的读入电平就变成低电平,这时就可以根据行和列判断出动作按键的位置。

4. 行1的扫描完成后,把行1的IO置高,然后按照上面步骤依次进行行2和行3的扫描,确认有动作按键的位置即可。

在实际应用中,为避免按键抖动影响,需要在程序中加入去抖动处理。

矩阵按键扫描广泛应用于各种设备的按键输入控制中,如电子琴、钢琴、智能家居等。

4x4矩阵键盘扫描例程

4x4矩阵键盘扫描例程

//4x4矩阵键盘扫描例程(C51)//使用P0口上的LED灯显示键盘扫描得到的键值//===============#include<reg51.h> //51系列单片机头文件#define uchar unsigned char#define uint unsigned int#define key_4x4_port P3 //定义4x4键盘使用的单片机端口uchar key; //存放扫描得到的键值void delayms(uint xms); //声明延时子程序void key_4x4_scan(); //声明4x4键盘扫描子程序,得到的键值送全局变量key //=====================void main(){P0=0xff; //P0开机初始化Key=0xff; //键盘值开机初始化为ff(检测到的键值应为0-15)while(1){key_4x4_scan(); //不停调用键盘扫描子程序P0=key; //用P0来显示键值}}//========================void delayms(uint xms) //延时子程序{ uint i, j;for (i=xms; i>0; i--)for (j-110; j>0; j--);}//======================void key_4x4_scan() //4x4键盘扫描子程序,得到的键值送全局变量key{ uchar temp;key_4x4_port=0xfe; //送出P3.0位0电平去扫描temp= key_4x4_port; //读出整个口得到的值temp=temp&0xf0; //屏蔽低4位if (temp!=0xf0) //假如高4位不全是1{ delayms(10); // 延时消抖再读temp=key_4x4_port;temp=temp&0xf0;if (temp!=0xf0) //消抖后如果再次高4位确定不是全1{ temp=key_4x4_port; //读出此次按键的值switch(temp){ case 0xee;key=0; break;case 0xde;key=1; break;case 0xbe;key=2; break;case 0x7e;key=3; break;}while(temp!=0xf0) //等待按键放开{ temp=key_4x4_port;temp=temp&0xf0;}}}//====次高位送0==========key_4x4_port=0xfd; //送出P3.1位0电平去扫描temp= key_4x4_port; //读出整个口得到的值temp=temp&0xf0; //屏蔽低4位if (temp!=0xf0) //假如高4位不全是1{ delayms(10); // 延时消抖再读temp=key_4x4_port;temp=temp&0xf0;if (temp!=0xf0) //消抖后如果再次高4位确定不是全1{ temp=key_4x4_port; //读出此次按键的值switch(temp){ case 0xed;key=4; break;case 0xdd;key=5; break;case 0xbd;key=6; break;case 0x7d;key=7; break;}while(temp!=0xf0) //等待按键放开{ temp=key_4x4_port;temp=temp&0xf0;}}}//====第3高位送0==========key_4x4_port=0xfb; //送出P3.2位0电平去扫描temp= key_4x4_port; //读出整个口得到的值temp=temp&0xf0; //屏蔽低4位if (temp!=0xf0) //假如高4位不全是1{ delayms(10); // 延时消抖再读temp=key_4x4_port;temp=temp&0xf0;if (temp!=0xf0) //消抖后如果再次高4位确定不是全1{ temp=key_4x4_port; //读出此次按键的值switch(temp){ case 0xeb;key=8; break;case 0xdb;key=9; break;case 0xbb;key=10; break;case 0x7b;key=11; break;}while(temp!=0xf0) //等待按键放开{ temp=key_4x4_port;temp=temp&0xf0;}}}//====第4高位送0==========key_4x4_port=0xf7; //送出P3.3位0电平去扫描temp= key_4x4_port; //读出整个口得到的值temp=temp&0xf0; //屏蔽低4位if (temp!=0xf0) //假如高4位不全是1{ delayms(10); // 延时消抖再读temp=key_4x4_port;temp=temp&0xf0;if (temp!=0xf0) //消抖后如果再次高4位确定不是全1{ temp=key_4x4_port; //读出此次按键的值switch(temp){ case 0xe7;key=12; break;case 0xd7;key=13; break;case 0xb7;key=14; break;case 0x77;key=15; break;}while(temp!=0xf0) //等待按键放开{ temp=key_4x4_port;temp=temp&0xf0;}}}}//==========End。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{
delay(5); //延时5毫秒
temp=P3; //此时P3=0XFE; 将0XFE反带回来赋给temp;则说明之前 temp的值并不是OXFE;而是0XFO;
temp=temp&0xf0;
while(temp!=0xf0) //重复上边的工作,在延时之后再次看是否真正的改变
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}
P3=0xfb; //检测第三行, 1111,1011
}
}
P3=0xf7; //检测第四行, 1111,0111
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
break;
case 0xdd:num=6; //1101,1101
break;
case 0xbd:num=7; //1011,1101
break;
case 0x7d:num=8; //0111,1101
}
uchar keyscan() //0Xfe 就是 1111,0000
{
P3=0xfe; //检测第一行, 1111,1110
temp=P3;
temp=temp&0xf0; // temp=0xfe&0xf0;
while(temp!=0xf0) //当temp不等于OXFO时,则有temp=OXF0,就是按下了。执行下面的语句 //总结,按下后temp改变就是按下了。不变就是不按下
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:num=5; //1110,1101
break;
case 0x7b:num=12; //0111,1011
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
break;
case 0xb7:num=15; //1011,0111
break;
case 0x77:num=16; //0111,0111
break;
}
while(temp!=0xf0)
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:num=9; //1110,1011
break;
case 0xdb:num=10; //1101,1011
break;
case 0xbb:num=11; //1011,1011
case 0xbe:num=3; //1011,1110
break;
case 0x7e:num=4; //0111,1110
break;
}
while(temp!=0xf0) //撤销按键之后再延时,看是否真正的改变
{
temp=P3;
temp=temp&0xf0;
}
}
}
P3=0xfd; //检测第二行 ,1111,1101
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch0,1110
break;
case 0xde:num=2; //1101,1110
break;
{
temp=P3;
temp=temp&0xf0;
}
}
}
return num;
}
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:num=13; //1110,0111
break;
case 0xd7:num=14; //1101,0111
// 矩阵键盘(具体说明,理解版)
// P3口接矩阵键盘
#define uchar unsigned char
uchar temp;
void delay(uchar x)
{
uchar y,z;
for(y=x;y>0;y--)
for(z=125;z>0;z--)
;
相关文档
最新文档