ORG 0100H START: MOV TMOD,#20H ;定时器T1为方式2 MOV TH1,#0F3H MOV TL1,#0F3H ;12m,波特率为2400 MOV PCON,#00H ;置SMOD=1 SETB TR1 ;启动T1计数开始 MOV SCON,#50H ;串口方式1 CLR RI ;清接收标志 CLR TI ;清发送标志
KSCAN: LCALL KEYS1 ;调用判键闭合子程序 JNZ KEY1;(A)<>0有键闭合则转至去抖动 AJMP RETURN;无键闭合则返回 KEY1: ACALL D10MS ;调用10ms延时程序 ACALL KEYS1;再次调用判键闭合子程序 JNZ KEY2;确认有键闭合,开始扫描 LJMP RETURN;无键闭合则返回 KEY2: MOV R2,#0FEH ;送首列扫描字 MOV R4,#00H ;送首列号 KEY0: MOV A,R2 MOV P1,A MOV P0,#0FFH MOV A,P0;扫描字从P1口送出 JB ACC.0,LINE1 ;第1行无键闭合,转第2行 MOV A,#00H;第1行首键号送A AJMP KPV ;转键值计算程序 LINE1: JB ACC.1,LINE2 ;第2行无键闭合,转第3行 MOV A,#04H;第2行首键号送A AJMP KPV;转键值计算程序 LINE2: JB ACC.2,LINE3;第3行无键闭合,转第4行 MOV A,#08H;第3行首键号送A AJMP KPV ;转键值计算程序 LINE3: JB ACC.3,LINE4 ;第4行无键闭合,转下1列 MOV A,#0CH;第4行首键号送A AJMP KPV LINE4: JB ACC.4,NEXT MOV A,#10H KPV: ADD A,R4;计算键值 MOV 50H,A ;键值存放在40H单元 ACALL SEDATA PUSH ACC KEY3: ACALL KEYS1;等待键释放 JNZ KEYS1 POP ACC SETB FLAG;置有键按下标志 SJMP KEY4 RETURN:CLR FLAG;清有键按下标志 KEY4: RET NEXT: INC R4;列号加1 MOV A,R2 CJNE A,#0F7H,RETURN;判断4行是否都已扫描完,;完则返回 RL A ;为扫描下1行做准备 MOV R2,A AJMP KEY0;开始扫描下1列
KEYS1: MOV P1,#0F0H;判键闭合子程序 MOV P0,#0FFH MOV A,P0 CPL A ANL A,#0E0H RET
D10MS:MOV R7,#14H;10ms延时子程序 DLY: MOV R6,#0F8H DLY1: DJNZ R6,DLY1 DJNZ R7,DLY RET
SEDATA:MOV R0,#50H WAIT: JNB TI,$ ;等待发送完一个字符 MOVX A,@R0;取一个字符 MOV SBUF,A;送串口 CLR TI RET END |