51单片机矩阵键盘程序示例

合集下载

51键盘矩阵扫描程序

51键盘矩阵扫描程序

51键盘矩阵扫描程序假设按下的是S1键进行如下检测(4*4键盘)先在P3口输出p3 00001111低四位行会有变化cord_h =00001111&00001110 =00001110if !=00001111延时0.1uscord_h=00001110&00001111=00001110if !=00001111P3再输出11111110P3 =00001110|11110000=11111110输出高四位cord_l=P3&0xf0 //此时P3口就是(实际值)输入值01111110 而不是上面的11111110cord_l=01111110&11110000=01110000cord_h+cord_l=00001110+01110000=01111110=0x7e //此编码即为S1的编码#include <reg52.h>//包含头文件#define uchar unsigned char#define uint unsigned intunsigned char consttable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0-Fuchar keyscan(void);void delay(uint i);void main(){uchar key;P2=0x00;//1数码管亮按相应的按键,会显示按键上的字符while(1){key=keyscan();//调用键盘扫描,switch(key){case 0x7e:P0=table[0];break;//0 按下相应的键显示相对应的码值case 0x7d:P0=table[1];break;//1case 0x7b:P0=table[2];break;//2case 0x77:P0=table[3];break;//3case 0xbe:P0=table[4];break;//4case 0xbd:P0=table[5];break;//5case 0xbb:P0=table[6];break;//6case 0xb7:P0=table[7];break;//7case 0xde:P0=table[8];break;//8case 0xdd:P0=table[9];break;//9case 0xdb:P0=table[10];break;//acase 0xd7:P0=table[11];break;//bcase 0xee:P0=table[12];break;//ccase 0xed:P0=table[13];break;//dcase 0xeb:P0=table[14];break;//ecase 0xe7:P0=table[15];break;//f}}}uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法{uchar cord_h,cord_l;//行列值P3=0x0f; //行线输出全为0cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{delay(100); //去抖cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f){P3=cord_h|0xf0; //输出当前列线值cord_l=P3&0xf0; //读入行线值return(cord_h+cord_l);//键盘最后组合码值}}return(0xff); //返回该值}void delay(uint i)//延时函数{while(i--);}。

51单片机矩阵键盘扫描程序

51单片机矩阵键盘扫描程序
void Timer0_isr(void) interrupt 1
{
TH0=(65536-2000)/256;//重新赋值2ms
TL0=(65536-2000)%256;
Display(0,8); //调用数码管扫描
}
/*------------------------------------------------
unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};//显示段码值0~F
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
case 0xd7:return 11;break;//b
case 0xee:return 12;break;//c
case 0xed:return 13;break;//d
case 0xeb:return 14;break;//e
case 0xe7:return 15;break;//f
default:return 0xff;break;
}
}
/*------------------------------------------------
uS延时函数,含有输入参数unsigned char t,无返回值
unsigned char是定义无符号字符变量,其值的范围是
0~255这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下T=tx2+5 uS

基于51单片机的4-4矩阵键盘字符输入

基于51单片机的4-4矩阵键盘字符输入
};
void display(unsigned char num)
{
P0=table[num];
}
void init_led()
{
P0 = 0x00;
}
void main()
{
while(1)
{
P1 = 0xef;
temp = P1;
temp = temp0xf0;
if (temp != 0xf0)
{
temp = P1;
switch(temp)
{
case 0xee:
key=0;
break;
case 0xed:
key=1;
break;
case 0xeb:
key=2;
break;
case 0xe7:
key=3;
break;
default:
break;
}
display(key);
P1=0xfe;
}
P1 = 0xdf;
key=10;
break;
case 0xb7:
key=11;
break;
default:
break;
}
display(key);
}
P1=0x7f;
temp=P1;
temp=temp0x0f;
if(temp!=0x0f)
{
temp=P1;
switch(temp)
{
case 0x7e:
key=12;
break;
temp = P1;
temp = temp0x0f;
if(temp != 0x0f)
{
temp = P1;
switch(temp)

基于51单片机4乘4矩阵键盘的设计

基于51单片机4乘4矩阵键盘的设计
case 0xbd:KEY=6;break;
case 0x7d:KEY=7;break;
case 0xeb:KEY=8;break;
case 0xdb:KEY=9;break;
case 0xbb:KEY=10;break;
case 0x7b:KEY=11;break;
case 0xe7:KEY=12;break;
控制任务:
编程实现4乘4的矩阵键盘控制连接在P0口和P1口上的16个LED,当按下某键并释放后只有对应的LED灯亮,例如按S0后D0亮,按S1后D1亮。
程序及仿真:
#include<reg51.h>
unsigned char code led[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
b=P2;
a=a|b;
switch(a)
{
case 0xee:KEY=0;break;
case 0xde:KEY=1;break;
case 0xbe:KEY=2;break;
case 0x7e:KEY=3;break;
case 0xed:KEY=4;break;
case 0xdd:KEY=5;break;
{
P0=0xff;
P1=led[n-8];
}}
int main(void)
{
whilsplay(KEY);
}
return 0;
}
更多资源,请关注微博“风竹弈星”,私聊。
unsigned char KEY=0xff;
void keyscan(void)
{
unsigned char a,b;
P2=0xf0;//高四位作为输入(高电平),低四位输出低电平

51单片机矩阵键盘程序示例

51单片机矩阵键盘程序示例

;lab5_asm;vol1.0;zqy;2012/2/18;定义初始化LED_CHABIT PSW数码管显示标志位,为1显示十位,为0显示个位;数字0-9ORG 00HJMP STARTORG 000BHJMP INT_T0转到中断服务程序,更改数码管显示ORG 0100HLED_TAB1:DB 0BFH,86H,0DBH,0CFH,0E6H,0EDHDB 0FDH,87H,0FFH,0EFH,0BFHDB 86H,0DBH,0CFH,0E6H,0EDH,0FDHLED_TAB2:DB 0BFH,0BFH,0BFH,0BFH,0BFHDB 0BFH,0BFH,0BFH,0BFH,0BFHDB 86H,86H,86H,86HDB 86H,86H,86HSTART:;工作寄存器和某些数据单元的初始化MOV R0,#0;数码管显示初始化SETB LED_CHAMOVDPTR, #8300H位选地址赋给DPTR高八位P2 口,选中U13锁存器MOVA,#OFEH位选数据,选中个位数码管,置低为选中MOVX@DPTR,脸选数据,对片外I/O 口的外设芯片访问MOVDPTR,#8200H段选地址MOVA,#OBFH段选数据,个位显示0MOVX@DPTR, A;定时器初始化MOV IE,#82H开启定时器T0中断MOV TMOD,#01H设定定时器T0为模式1MOV TH0,#0D8HMOV TL0,#0F0H装入初值,10MS 延时12MHZSETB TRC启动定时器T0KEY:;按键处理LCALL KEY_START用判断有无键按下子程序JZ KEY无键按下,重新扫描LCALL KEY_DELAY键按下,延时去抖LCALL KEY_STARTJZ KEYLCALL KEY_NEXT断哪一个键被按下LCALL DECODED® 译码LCALL KEY_EN判断按键释放LJMP KEYKEY_START:MOV DPTR, #8000H键盘地址MOV A,#0F0HMOVX @DPTR,A亍全部输出0 NOPNOPNOPMOVX A,@DPTR3 描键盘CPL A取正逻辑,1为按下ANL A,#0FHRETKEY_NEXT:MOV R1,# 0扫描行计数器MOV R2,# 0扫描列计数器MOV R3,#0FEH首行扫描字送R3 MOV DPTR, #8000HMOV A,R3MOVX @DPTR,AMOVX A,@DPTRCPL AANL A,#0FHMOV R4,#4S0123: JNZ SKEY不;为全0,有键按下; 全为0,进行下一行扫描INC R1行计数器加1MOV A,R3RL AMOV R3,AMOV DPTR,#8000HMOVX @DPTR,ANOPNOPNOPMOVX A,@DPTRCPL AANL A,#0FHDJNZ R4,S0123LJMP KEYEKEY:RETSKEY 0列号译码JBACC.0,SKEY1JBACC.1,SKEY2JBACC.2,SKEY3JBACC.3,SKEY4SKEY1:M0V A,#00存列号0 MOV R2,AAJMP EKEYSKE Y2:M0V A,#01存列号1 MOV R2,AAJMP EKEYSKEY3:M0V A,#02存列号2 MOV R2,AAJMP EKEYSKEY4: MOV A,#03存列号3 MOV R2,AAJMP EKEYDECODE:;行号在R1列号在R2;键值译码MOV A,R1MOV B,#04HMUL ABADD A,R2INC AMOV R0,ARETKEY_END:MOV DPTR,#8000H键盘地址MOVX A,@DPTR3 描键盘CPL A取正逻辑,1为按下ANL A,#0FHJNZ KEY_ENDLCALL KEY_DELAYJNZ KEY_ENDRETKEY_DELAY:MOV R5,#10HDS1:MOV R6,#0FFHDS2:NOPDJNZ R6,DS2DJNZ R5,DS1RETINT_TO:;中断服务程序,更改数码管显示MOV R7,AJB LED_CHA,DISP检查数码管显示标志位CPL LED_CHAMOVDPTR, #8200H段选地址MOV A,#0MOVX @DPTR,AMOVDPTR,#8300H位选地址赋给DPTR高八位P2 口,选中U13锁存器MOVA, #0FEH位选数据,选中个位数码管,置低为选中MOVX@DPTR, A位选数据,对片外I/O 口的外设芯片访问; 判断需要显示的个位数字MOV A,R0NOPMOV DPTR,#LED_TAB1NOPNOPMOVC A,@A+DPTRMOVDPTR, #82001■段选地址MOVX @DPTR,AJMP INT_EXITDISP_L:CPL LED_CHAMOVDPTR, #8200H段选地址MOV A,#0MOVX @DPTR,AMOVDPTR,#8300H位选地址赋给DPTR高八位P2 口,选中U13锁存器MOVA, #0FDH位选数据,选中十位数码管,置低为选中MOVX@DPTR, A位选数据,对片外I/O 口的外设芯片访问;判断需要显示的十位数字0 或1MOV A,R0NOPMOV DPTR,#LED_TAB2MOVC A,@A+DPTRMOVDPTR, #8200H段选地址MOVX @DPTR,AINT_EXIT:MOV IE,#82HMOV TH0,#0D8HMOV TLO,#OFOH装入初值,10MS延时SETB TR0MOV A,R7MOV DPTR,#8000HRETIEND12MHZ。

矩阵键盘扫描汇编程序

矩阵键盘扫描汇编程序

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教程语句部分,可在首页搜索。

51单片机矩阵键盘程序示例

51单片机矩阵键盘程序示例

;lab5_asm;vol1.0;zqy;2012/2/18;定义初始化LED_CHABIT PSW.5;数码管显示标志位,为1显示十位,为0显示个位;数字0-9ORG 00HJMP STARTORG 000BHJMP INT_T0;转到中断服务程序,更改数码管显示ORG 0100HLED_TAB1:DB 0BFH,86H,0DBH,0CFH,0E6H,0EDHDB 0FDH,87H,0FFH,0EFH,0BFHDB 86H,0DBH,0CFH,0E6H,0EDH,0FDHLED_TAB2:DB 0BFH,0BFH,0BFH,0BFH,0BFHDB 0BFH,0BFH,0BFH,0BFH,0BFHDB 86H,86H,86H,86HDB 86H,86H,86HSTART:;工作寄存器和某些数据单元的初始化MOV R0,#0;数码管显示初始化SETB LED_CHAMOVDPTR, #8300H;位选地址赋给DPTR高八位P2口,选中U13锁存器MOVA,#0FEH;位选数据,选中个位数码管,置低为选中MOVX@DPTR, A;位选数据,对片外I/O口的外设芯片访问MOVDPTR,#8200H;段选地址MOVA,#0BFH;段选数据,个位显示0MOVX@DPTR, A;定时器初始化MOV IE,#82H;开启定时器T0中断MOV TMOD,#01H;设定定时器T0为模式1MOV TH0,#0D8HMOV TL0,#0F0H;装入初值,10MS延时12MHZSETB TR0 ;启动定时器T0KEY:;按键处理LCALL KEY_START;调用判断有无键按下子程序JZ KEY;无键按下,重新扫描LCALL KEY_DELAY;有键按下,延时去抖LCALL KEY_STARTJZ KEYLCALL KEY_NEXT;判断哪一个键被按下LCALL DECODE;键值译码LCALL KEY_END;判断按键释放LJMP KEYKEY_START:MOV DPTR, #8000H;键盘地址MOV A,#0F0HMOVX @DPTR,A;行全部输出0NOPNOPNOPMOVX A,@DPTR;扫描键盘CPL A;取正逻辑,1为按下ANL A,#0FHRETKEY_NEXT:MOV R1,#0;扫描行计数器MOV R2,#0;扫描列计数器MOV R3,#0FEH;首行扫描字送R3 MOV DPTR, #8000HMOV A,R3MOVX @DPTR,AMOVX A,@DPTRCPL AANL A,#0FHMOV R4,#4S0123: JNZ SKEY0;不为全0,有键按下;全为0,进行下一行扫描INC R1;行计数器加1MOV A,R3RL AMOV R3,AMOV DPTR,#8000HMOVX @DPTR,ANOPNOPNOPMOVX A,@DPTRCPL AANL A,#0FHDJNZ R4,S0123LJMP KEYEKEY:RETSKEY0:;列号译码JBACC.0,SKEY1JBACC.1,SKEY2JBACC.2,SKEY3JBACC.3,SKEY4SKEY1:MOV A,#00H;存列号0 MOV R2,AAJMP EKEYSKEY2:MOV A,#01H;存列号1 MOV R2,AAJMP EKEYSKEY3:MOV A,#02H;存列号2MOV R2,AAJMP EKEYSKEY4: MOV A,#03H;存列号3 MOV R2,AAJMP EKEYDECODE:;行号在R1,列号在R2;键值译码MOV A,R1MOV B,#04HMUL ABADD A,R2INC AMOV R0,ARETKEY_END:MOV DPTR,#8000H;键盘地址MOVX A,@DPTR;扫描键盘CPL A;取正逻辑,1为按下ANL A,#0FHJNZ KEY_ENDLCALL KEY_DELAYJNZ KEY_ENDRETKEY_DELAY:MOV R5,#10HDS1:MOV R6,#0FFHDS2:NOPDJNZ R6,DS2DJNZ R5,DS1RETINT_T0:;中断服务程序,更改数码管显示MOV R7,AJB LED_CHA,DISP_L;检查数码管显示标志位CPL LED_CHAMOVDPTR, #8200H;段选地址MOV A,#0MOVX @DPTR,AMOVDPTR,#8300H;位选地址赋给DPTR高八位P2口,选中U13锁存器MOVA, #0FEH;位选数据,选中个位数码管,置低为选中MOVX@DPTR, A;位选数据,对片外I/O口的外设芯片访问;判断需要显示的个位数字MOV A,R0NOPMOV DPTR,#LED_TAB1NOPNOPMOVC A,@A+DPTRMOVDPTR, #8200H;段选地址MOVX @DPTR,AJMP INT_EXITDISP_L:CPL LED_CHAMOVDPTR, #8200H;段选地址MOV A,#0MOVX @DPTR,AMOVDPTR,#8300H;位选地址赋给DPTR高八位P2口,选中U13锁存器MOVA, #0FDH;位选数据,选中十位数码管,置低为选中MOVX@DPTR, A;位选数据,对片外I/O口的外设芯片访问;判断需要显示的十位数字0或1MOV A,R0NOPMOV DPTR,#LED_TAB2MOVC A,@A+DPTRMOVDPTR, #8200H;段选地址MOVX @DPTR,AINT_EXIT:MOV IE,#82HMOV TH0,#0D8HMOV TL0,#0F0H;装入初值,10MS延时SETB TR0MOV A,R7MOV DPTR,#8000HRETIEND12MHZ。

51单片机矩阵键盘PROTEUS仿真演示

51单片机矩阵键盘PROTEUS仿真演示

51单片机矩阵键盘PROTEUS仿真演示51单片机矩阵键盘PROTEUS仿真演示(图、程序)作者:给力哈哈程序如下:#include#define uchar unsigned char;uchar key_val=0; //定义键值,初始默认为0uchar code TAB[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xC6,0xa1,0x86,0x8e}; //0~F共阳数码管显示段码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 = row*4 +col; // 获取键值,识别按键return; // 退出循环}tmp2*=2; // tmp2左移一位}}}}void main(){P2=0xFF; //位码,这里全部置高,点亮8位数码管while(1){Check_Key();P0=TAB[key_val]; //显示}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

;lab5_asm
;vol
1.0
;zqy
;2012/2/18
;定义初始化
LED_CHABIT PSW数码管显示标志位,为1显示十位,为0显示个位;数字0-9
ORG 00H
JMP START
ORG 000BH
JMP INT_T0转到中断服务程序,更改数码管显示
ORG 0100H
LED_TAB1:DB 0BFH,86H,0DBH,0CFH,0E6H,0EDH
DB 0FDH,87H,0FFH,0EFH,0BFH
DB 86H,0DBH,0CFH,0E6H,0EDH,0FDH
LED_TAB2:
DB 0BFH,0BFH,0BFH,0BFH,0BFH
DB 0BFH,0BFH,0BFH,0BFH,0BFH
DB 86H,86H,86H,86H
DB 86H,86H,86H
START:
;工作寄存器和某些数据单元的初始化
MOV R0,#0
;数码管显示初始化
SETB LED_CHA
MOVDPTR, #8300H位选地址赋给DPTR高八位P2 口,选中U13锁存器
MOVA,#OFEH位选数据,选中个位数码管,置低为选中
MOVX@DPTR,脸选数据,对片外I/O 口的外设芯片访问
MOVDPTR,#8200H段选地址
MOVA,#OBFH段选数据,个位显示0
MOVX@DPTR, A
;定时器初始化
MOV IE,#82H开启定时器T0中断
MOV TMOD,#01H设定定时器T0为模式1
MOV TH0,#0D8H
MOV TL0,#0F0H装入初值,10MS 延时12MHZ
SETB TRC启动定时器T0
KEY:
;按键处理
LCALL KEY_START用判断有无键按下子程序
JZ KEY无键按下,重新扫描
LCALL KEY_DELAY键按下,延时去抖
LCALL KEY_START
JZ KEY
LCALL KEY_NEXT断哪一个键被按下LCALL DECODED® 译码
LCALL KEY_EN判断按键释放LJMP KEY
KEY_START:
MOV DPTR, #8000H键盘地址
MOV A,#0F0H
MOVX @DPTR,A亍全部输出0 NOP
NOP
NOP
MOVX A,@DPTR3 描键盘
CPL A取正逻辑,1为按下
ANL A,#0FH
RET
KEY_NEXT:
MOV R1,# 0扫描行计数器
MOV R2,# 0扫描列计数器
MOV R3,#0FEH首行扫描字送R3 MOV DPTR, #8000H
MOV A,R3
MOVX @DPTR,A
MOVX A,@DPTR
CPL A
ANL A,#0FH
MOV R4,#4
S0123: JNZ SKEY不;为全0,有键按下; 全为0,进行下一行扫描
INC R1行计数器加1
MOV A,R3
RL A
MOV R3,A
MOV DPTR,#8000H
MOVX @DPTR,A
NOP
NOP
NOP
MOVX A,@DPTR
CPL A
ANL A,#0FH
DJNZ R4,S0123
LJMP KEY
EKEY:
RET
SKEY 0列号译码
JB
ACC.0,SKEY1
JB
ACC.1,SKEY2
JB
ACC.2,SKEY3
JB
ACC.3,SKEY4
SKEY1:M0V A,#00存列号0 MOV R2,A
AJMP EKEY
SKE Y2:M0V A,#01存列号1 MOV R2,A
AJMP EKEY
SKEY3:M0V A,#02存列号2 MOV R2,A
AJMP EKEY
SKEY4: MOV A,#03存列号3 MOV R2,A
AJMP EKEY
DECODE:
;行号在R1列号在R2
;键值译码
MOV A,R1
MOV B,#04H
MUL AB
ADD A,R2
INC A
MOV R0,A
RET
KEY_END:
MOV DPTR,#8000H键盘地址MOVX A,@DPTR3 描键盘CPL A取正逻辑,1为按下ANL A,#0FH
JNZ KEY_END
LCALL KEY_DELAY
JNZ KEY_END
RET
KEY_DELAY:
MOV R5,#10H
DS1:MOV R6,#0FFH
DS2:NOP
DJNZ R6,DS2
DJNZ R5,DS1
RET
INT_TO:;中断服务程序,更改数码管显示
MOV R7,A
JB LED_CHA,DISP检查数码管显示标志位
CPL LED_CHA
MOVDPTR, #8200H段选地址
MOV A,#0
MOVX @DPTR,A
MOVDPTR,#8300H位选地址赋给DPTR高八位P2 口,选中U13锁存器MOVA, #0FEH位选数据,选中个位数码管,置低为选中
MOVX@DPTR, A位选数据,对片外I/O 口的外设芯片访问
; 判断需要显示的个位数字
MOV A,R0
NOP
MOV DPTR,#LED_TAB1
NOP
NOP
MOVC A,@A+DPTR
MOVDPTR, #82001■段选地址
MOVX @DPTR,A
JMP INT_EXIT
DISP_L:
CPL LED_CHA
MOVDPTR, #8200H段选地址
MOV A,#0
MOVX @DPTR,A
MOVDPTR,#8300H位选地址赋给DPTR高八位P2 口,选中U13锁存器MOVA, #0FDH位选数据,选中十位数码管,置低为选中
MOVX@DPTR, A位选数据,对片外I/O 口的外设芯片访问
;判断需要显示的十位数字0 或1
MOV A,R0
NOP
MOV DPTR,#LED_TAB2
MOVC A,@A+DPTR
MOVDPTR, #8200H段选地址
MOVX @DPTR,A
INT_EXIT:
MOV IE,#82H
MOV TH0,#0D8H
MOV TLO,#OFOH装入初值,10MS延时
SETB TR0
MOV A,R7
MOV DPTR,#8000H
RETI
END12MHZ。

相关文档
最新文档