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