|
最簡(jiǎn)單矩陣鍵盤(pán)掃描程序 key:mov p0,#00001111b;上四位和下四位分別為行和列,所以送出高 低電壓檢查有沒(méi)有按鍵按下 jmp k10;跳到K10處開(kāi)始掃描,這里可以改成其它條件轉(zhuǎn)移指令來(lái)決 定本次掃描是否要繼續(xù),例如減1為0轉(zhuǎn)移或者位為1或0才轉(zhuǎn)移,這主 要用來(lái)增加功能,確認(rèn)上一按鍵功能是否完成?是否相當(dāng)于經(jīng)過(guò)了延 時(shí)?是否要封鎖鍵盤(pán)? goend:jmp kend;如果上面判斷本次不執(zhí)行鍵盤(pán)掃描程序,則立即轉(zhuǎn) 到程序尾部,不要浪費(fèi)CPU的時(shí)間 k10:jb p0.0,k20;掃描正式開(kāi)始,先檢查列1四個(gè)鍵是否有鍵按下, 如果沒(méi)有,則跳到K20檢查列2 k11:mov p0,#11101111b;列1有鍵按下時(shí),P0.0變低,到底是那一個(gè)鍵 按下?現(xiàn)在分別輸出各行低電平 jb p0.0,k12;該行的鍵不按下時(shí),p0.0為高電平,跳到到K12,檢查其 它的行 mov r1,#1;如果正好是這行的鍵按下,將寄存器R0寫(xiě)下1,表示1號(hào)鍵 按下了 k12:mov p0,#11011111b jb p0.0,k13 mov r1,#2;如果正好是這行的鍵按下,將寄存器R0寫(xiě)下2,表示2號(hào)鍵 按下了 k13:mov p0,#10111111b jb p0.0,k14 mov r1,#3;如果正好是這行的鍵按下,將寄存器R0寫(xiě)下3,表示3號(hào)鍵 按下了 k14:mov p0,#01111111b jb p0.0,kend;如果現(xiàn)在四個(gè)鍵都沒(méi)有按下,可能按鍵松開(kāi)或干擾, 退出掃描(以后相同) mov r1,#4如果正好是這行的鍵按下,將寄存器R0寫(xiě)下4,表示4號(hào)鍵 按下了 jmp kend;已經(jīng)找到按下的鍵,跳到結(jié)尾吧 k20:jb p0.1,k30;列2檢查為高電平再檢查列3、4 k21:mov p0,#11101111b;列2有健按下時(shí),P0.0會(huì)變低,到底是那一 行的鍵按下呢?分別輸出行的低電平 jb p0.1,k22;該行的鍵不按下時(shí)p0.0為高電平,跳到到K22,檢查另 外三行 mov r1,#5;如果正好是這行的鍵按下,將寄存器R0寫(xiě)下5,表示5號(hào)鍵 按下了(以后相同,不再重復(fù)了) k22:mov p0,#11011111b jb p0.1,k23 mov r1,#6 k23:mov p0,#10111111b jb p0.1,k24 mov r1,#7 k24:mov p0,#01111111b jb p0.1,kend mov r1,#8 jmp kend;已經(jīng)找到按下的鍵,跳到結(jié)尾吧(以后相同,不要重復(fù)了 ) k30:jb p0.2,k40 k31:mov p0,#11101111b jb p0.2,k32 mov r1,#9 k32:mov p0,#11011111b jb p0.2,k33 mov r1,#10 k33:mov p0,#10111111b jb p0.2,k34 mov r1,#11 k34:mov p0,#01111111b jb p0.2,kend mov r1,#12 jmp kend k40:jb p0.3,kend k41:mov p0,#11101111b jb p0.3,k42 mov r1,#13 k42:mov p0,#11011111b jb p0.3,k43 mov r1,#14 k43:mov p0,#10111111b jb p0.3,k44 mov r1,#15 k44:mov p0,#01111111b jb p0.3,kend mov r1,#16 kend: ret /*-------------------------------------------------------*/行列掃描鍵盤(pán)可檢測(cè)出雙鍵按下 #i nclude <reg52.h> #define ulong unsigned long #define uint unsigned int #define uchar unsigned char extern void delay(unsigned int x); unsigned char Tab_key[]= //行列式鍵盤(pán)映射 {0x00, //無(wú)鍵按下 '7','8','9','/', '4','5','6','*', '1','2','3','-', 'C','0','=','+', //下面為按'C'同時(shí)再按的鍵: '7','8','9','/', '4','5','6','*', '1','2','3','-', '0','=','+',}; // P1口行列式鍵盤(pán) // #define KEYPIN_L P1 // 定義鍵掃描列端口為 P1 低四位輸入 // #define KEYPIN_H P1 // 定義鍵掃描行端口為 P1高 四位掃描輸出 // // P1口行列式鍵盤(pán) // //公用函數(shù) unsigned char KeysCAN(void); // 鍵掃描函數(shù) // //內(nèi)部私有函數(shù) unsigned char fnKeycode(unsigned char key); // 根據(jù)鍵盤(pán) 映射表輸出順序鍵值 // /* // P1口行列式鍵盤(pán) // extern unsigned char KeysCAN(void); // 鍵掃描函數(shù) // */ // P1口行列式鍵盤(pán) // //--------------------------------------------------------- ------------------// unsigned char KeysCAN(void) // 鍵掃描 函數(shù) // { unsigned char sccode,recode,keytemp = 0; KEYPIN_L = KEYPIN_L|0x0f; // P1低四 位為列線輸入 // KEYPIN_H = KEYPIN_H&0x0f; // P1高四 位為行線發(fā)全零掃描碼 // if ((KEYPIN_L&0x0f) != 0x0f) { delay(10); // 延時(shí) 10 MS 消抖 // if ((KEYPIN_L&0x0f) != 0x0f) { sccode = 0xef; // 逐行掃 描碼初值(1110 1111) // while(sccode != 0xff) //將掃描4次 ,keytemp為每次鍵值相 或的值 // { KEYPIN_H = sccode; // 輸出 行掃描碼 // if ((KEYPIN_L&0x0f) != 0x0f) // 本行有 鍵按下 // { recode = (KEYPIN_L&0x0f)|0xf0; // 只 要低位,高位置1 // keytemp |= (~sccode)+(~recode); //特 征碼(高位為列P3,低位為行KEYPIN_H) // } sccode = (sccode << 1)|0x01; // 掃描碼0 向高位移動(dòng) // } } } KEYPIN_H = KEYPIN_H|0xf0; return(fnKeycode(keytemp)); } //--------------------------------------------------------- ------------------// unsigned char fnKeycode(unsigned char key) // 根據(jù)鍵盤(pán) 映射表輸出順序鍵值 // { switch(key) { case 0x11: // 1 鍵 // key = 0x01; break; case 0x21: // 2 鍵 // key = 0x02; break; case 0x41: // 3 鍵 // key = 0x03; break; case 0x81: // 4 鍵 // key = 0x04; break; case 0x12: // 5 鍵 // key = 0x05; break; case 0x22: // 6 鍵 // key = 0x06; break; case 0x42: // 7 鍵 // key = 0x07; break; case 0x82: // 8 鍵 // key = 0x08; break; case 0x14: // 9 鍵 // key = 0x09; break; case 0x24: // 10 鍵 // key = 0x0A; break; case 0x44: // 11 鍵 // key = 0x0B; break; case 0x84: // 12 鍵 // key = 0x0C; break; case 0x18: // 13 鍵 // key = 0x0D; break; case 0x28: // 14 鍵 // key = 0x0E; break; case 0x48: // 15 鍵 // key = 0x0F; break; case 0x88: // 16 鍵 // key = 0x10; break; //以下為功能鍵// case 0x19: // 'C' +1 鍵 // key = 0x11; break; case 0x29: // 'C' +2 鍵 // key = 0x12; break; case 0x49: // 'C' +3 鍵 // key = 0x13; break; case 0x89: // 'C' +4 鍵 // key = 0x14; break; case 0x1A: // 'C' +5 鍵 // key = 0x15; break; case 0x2A: // 'C' +6 鍵 // key = 0x16; break; case 0x4A: // 'C' +7 鍵 // key = 0x17; break; case 0x8A: // 'C' +8 鍵 // key = 0x18; break; case 0x1C: // 'C' +9 鍵 // key = 0x19; break; case 0x2C: // 'C' +10 鍵 // key = 0x1A; break; case 0x4C: // 'C' +11 鍵 // key = 0x1B; break; case 0x8C: // 'C' +12 鍵 // key = 0x1C; break; // case 0x18: // 'C' +13 鍵 // // key = 0x1D; // break; case 0x38: // 'C' +14 鍵 // key = 0x1D; break; case 0x58: // 'C' +15 鍵 // key = 0x1E; break; case 0x98: // 'C' +16 鍵 // key = 0x1F; break; default : // 無(wú)鍵 // key = 0x00; break; } return(Tab_key[key]); } /*---------------------------------------------------------*/矩鍵查尋鍵值44程序與顯示 #i nclude <reg52.h> //#i nclude <math.h> #i nclude <intrins.h> #define uchar unsigned char #define TURE 1 #define FALSE 0 int key; int del; void Tkey(void); void led(void); /************主 程序*************/ void main(void) { void tkey(void); void led(void); void delay(int);
SCON=0x00; TI=0; while(TURE) { Tkey(); led(); delay(2000); }
}
/********矩鍵查尋鍵值4*4程序******/按鍵為P1.0---P1.7 void Tkey(void) { uchar readkey;//rereadkey; uchar x_temp,y_temp;
P1=0x0f; x_temp=P1&0x0f; if(x_temp==0x0f) goto keyout; P1=0xf0; y_temp=P1&0xf0; readkey=x_temp|y_temp; readkey=~readkey; switch(readkey) { case 0x11:key=0; break; case 0x21:key=1; break; case 0x41:key=2; break; case 0x81:key=3; break; case 0x12:key=4; break; case 0x22:key=5; break; case 0x42:key=6; break; case 0x82:key=7; break; case 0x14:key=8; break; case 0x24:key=9; break; case 0x44:key=10;break; case 0x84:key=11;break; case 0x18:key=12;break; case 0x28:key=13;break; case 0x48:key=14;break; case 0x88:key=15;break; default: key=16;break; }
keyout:_nop_(); } /************顯示程序*************/ void led(void) {uchar code LEDValue[]=
{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //0-9 uchar data num[6]; uchar k; num[0]=0; num[1]=0; num[2]=0; num[3]=0; num[4]=key/10; num[5]=key-(key/10)*10; for(k=0;k<=5;k++) { SBUF=LEDValue[num[5-k]]; while(TI==0); TI=0; } } /************延時(shí)程序*************/ void delay(del) { for(del;del>0;del--); } /*--------------------------------------------*/;偽定義 KEYBUF EQU 30H ;鍵值暫存單元,查表時(shí)用 ;************************************* ;* * ;* 主程序和中斷程序入口 * ;* * ;************************************* ORG 0000H ;程序執(zhí)行開(kāi)始地址 AJMP MAIN ;跳至MAIN執(zhí)行 ;************************************* ;* * ;* 主 程 序 * ;* * ;************************************* ORG 0040H MAIN: MOV P1,#0FFH MOV P3,#0FFH LCALL KEYSCAN ;主體程序。調(diào)用查鍵子程序 LJMP MAIN ;轉(zhuǎn)MAIN循環(huán) NOP ;軟件陷阱 NOP NOP LJMP MAIN ;************************************* ;* * ;* 鍵盤(pán)工作子程序(4 * 5 陣列) * ;* 接口為2051的P3和P1口 * ;************************************* KEYSCAN:MOV P3,#0FFH ;清P3口,初始化鍵低電平有效 CLR P3.2 ;清P3.2口 MOV A,P1 ;讀P1口狀態(tài) ANL A,#0FH ;清高4位,保留低四位低電平有效 XRL A,#0FH ;異或相同則為0不同結(jié)果為1,為0則表;示無(wú)鍵被按下(這一行) JZ NOKEY1 ;為0則轉(zhuǎn)下一行鍵值處理 LCALL DL10MS ;有鍵按下則延時(shí)10ms再測(cè)一次抗干擾 MOV A,P1 ANL A,#0FH XRL A,#0FH JZ NOKEY1 ;是干擾則轉(zhuǎn)下一行鍵值處理程序 MOV A,P1 ANL A,#0FH ;保留低四? KB1: CJNE A,#0EH,KB2 ;如果值為#0E則為P1.4與P1.0組合的鍵 MOV KEYBUF,#0 ;賦鍵值 LJMP KEYWORK ;轉(zhuǎn)鍵處理 KB2: CJNE A,#0DH,KB3 ;如果值為#0D則為P1.4與P1.1組合的鍵 MOV KEYBUF,#1 LJMP KEYWORK KB3: CJNE A,#0BH,KB4 ;如果值為#0B則為P1.4與P1.2組合的 MOV KEYBUF,#2 LJMP KEYWORK KB4: CJNE A,#07H,KB5 ;如果值為#07則為P1.4與P1.3組合的 MOV KEYBUF,#3 LJMP KEYWORK KB5: NOP ; NOKEY1: MOV P3,#0FFH CLR P3.3 MOV A,P1 ANL A,#0FH XRL A,#0FH JZ NOKEY2 LCALL DL10MS MOV A,P1 ANL A,#0FH XRL A,#0FH JZ NOKEY2 MOV A,P1 ANL A,#0FH CJNE A,#0EH,KB6 MOV KEYBUF,#4 LJMP KEYWORK KB6: CJNE A,#0DH,KB7 MOV KEYBUF,#5 LJMP KEYWORK KB7: CJNE A,#0BH,KB8 MOV KEYBUF,#6 LJMP KEYWORK KB8: CJNE A,#07H,KB9 MOV KEYBUF,#7 LJMP KEYWORK KB9: NOP ; NOKEY2: MOV P3,#0FFH CLR P3.4 MOV A,P1 ANL A,#0FH XRL A,#0FH JZ NOKEY3 LCALL DL10MS MOV A,P1 ANL A,#0FH XRL A,#0FH JZ NOKEY3 MOV A,P1 ANL A,#0FH CJNE A,#0EH,KB10 MOV KEYBUF,#8 LJMP KEYWORK KB10: CJNE A,#0DH,KB11 MOV KEYBUF,#9 LJMP KEYWORK KB11: CJNE A,#0BH,KB12 MOV KEYBUF,#10 LJMP KEYWORK KB12: CJNE A,#07H,KB13 MOV KEYBUF,#11 LJMP KEYWORK KB13: NOP ; NOKEY3: MOV P3,#0FFH CLR P3.5 MOV A,P1 ANL A,#0FH XRL A,#0FH JZ NOKEY4 LCALL DL10MS MOV A,P1 ANL A,#0FH XRL A,#0FH JZ NOKEY4 MOV A,P1 ANL A,#0FH CJNE A,#0EH,KB14 MOV KEYBUF,#12 LJMP KEYWORK KB14: CJNE A,#0DH,KB15 MOV KEYBUF,#13 LJMP KEYWORK KB15: CJNE A,#0BH,KB16 MOV KEYBUF,#14 LJMP KEYWORK KB16: CJNE A,#07H,KB17 MOV KEYBUF,#15 LJMP KEYWORK KB17: NOP ; NOKEY4: MOV P3,#0FFH CLR P3.7 MOV A,P1 ANL A,#0FH XRL A,#0FH JZ NOKEY5 LCALL DL10MS MOV A,P1 ANL A,#0FH XRL A,#0FH JZ NOKEY5 MOV A,P1 ANL A,#0FH CJNE A,#0EH,KB18 MOV KEYBUF,#16 LJMP KEYWORK KB18: CJNE A,#0DH,KB19 MOV KEYBUF,#17 LJMP KEYWORK KB19: CJNE A,#0BH,KB20 MOV KEYBUF,#18 LJMP KEYWORK KB20: CJNE A,#07H,KB21 MOV KEYBUF,#19 LJMP KEYWORK KB21: NOP ; NOKEY5: LJMP MAIN ; KEYWORK:MOV A,KEYBUF ;得到鍵值 MOV DPTR,#TABLE MOVC A,@A+DPTR ;查行鍵值送ACC MOV P0,A ; WAITFREE: MOV A,P1 ;以下程序等待鍵釋放 MOV KEYBUF,#00H ANL A,#0FH XRL A,#0FH JNZ WAITFREE RET ; ;************************************* ;* * ;* 延時(shí)513 us * ;* * ;************************************* ; ;513微秒延時(shí)程序 DELAY: MOV R2,#0FEH DELAY1: DJNZ R2,DELAY1 RET ; ;************************************* ;* * ;* 延時(shí)10ms * ;* * ;************************************* ; ;10毫秒延時(shí)程序 DL10MS: MOV R3,#14H DL10MS1:LCALL DELAY DJNZ R3,DL10MS1 RET ; TABLE: ;七段顯示器數(shù)據(jù)定義 DB 0C0H, 0F9H, 0A4H, 0B0H, 99H ; 01234 DB 92H, 82H, 0F8H, 80H, 90H ; 56789 DB 88H, 83H, 0C6H, 0A1H, 86H; ABCDE DB 8EH ; F ; END ;程序結(jié)束 /*--------------------------------------------------------------*/ KEYBUF EQU 30H ORG 00H START: MOV KEYBUF,#2 WAIT: MOV P3,#0FFH CLR P3.4 MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY1 LCALL DELY10MS MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY1 MOV A,P3 ANL A,#0FH CJNE A,#0EH,NK1 MOV KEYBUF,#0 LJMP DK1 NK1: CJNE A,#0DH,NK2 MOV KEYBUF,#1 LJMP DK1 NK2: CJNE A,#0BH,NK3 MOV KEYBUF,#2 LJMP DK1 NK3: CJNE A,#07H,NK4 MOV KEYBUF,#3 LJMP DK1 NK4: NOP DK1: MOV A,KEYBUF MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A
DK1A: MOV A,P3 ANL A,#0FH XRL A,#0FH JNZ DK1A NOKEY1: MOV P3,#0FFH CLR P3.5 MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY2 LCALL DELY10MS MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY2 MOV A,P3 ANL A,#0FH CJNE A,#0EH,NK5 MOV KEYBUF,#4 LJMP DK2 NK5: CJNE A,#0DH,NK6 MOV KEYBUF,#5 LJMP DK2 NK6: CJNE A,#0BH,NK7 MOV KEYBUF,#6 LJMP DK2 NK7: CJNE A,#07H,NK8 MOV KEYBUF,#7 LJMP DK2 NK8: NOP DK2: MOV A,KEYBUF MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A DK2A: MOV A,P3 ANL A,#0FH XRL A,#0FH JNZ DK2A NOKEY2: MOV P3,#0FFH CLR P3.6 MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY3 LCALL DELY10MS MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY3 MOV A,P3 ANL A,#0FH CJNE A,#0EH,NK9 MOV KEYBUF,#8 LJMP DK3 NK9: CJNE A,#0DH,NK10 MOV KEYBUF,#9 LJMP DK3 NK10: CJNE A,#0BH,NK11 MOV KEYBUF,#10 LJMP DK3 NK11: CJNE A,#07H,NK12 MOV KEYBUF,#11 LJMP DK3 NK12: NOP DK3: MOV A,KEYBUF MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A DK3A: MOV A,P3 ANL A,#0FH XRL A,#0FH JNZ DK3A NOKEY3: MOV P3,#0FFH CLR P3.7 MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY4 LCALL DELY10MS MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY4 MOV A,P3 ANL A,#0FH CJNE A,#0EH,NK13 MOV KEYBUF,#12 LJMP DK4 NK13: CJNE A,#0DH,NK14 MOV KEYBUF,#13 LJMP DK4 NK14: CJNE A,#0BH,NK15 MOV KEYBUF,#14 LJMP DK4 NK15: CJNE A,#07H,NK16 MOV KEYBUF,#15 LJMP DK4 NK16: NOP DK4: MOV A,KEYBUF MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A DK4A: MOV A,P3 ANL A,#0FH XRL A,#0FH JNZ DK4A NOKEY4: LJMP WAIT DELY10MS: MOV R6,#10 D1: MOV R7,#248 DJNZ R7,$ DJNZ R6,D1 RET TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H END |