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 />
|