L4: RLC A ;将按键左移一位 JNC KEYIN ;判断C=0?有键按下则C=0,跳至KEYIN INC R1 ;C=1,则无键按下,将取码指针值加1 DJNZ R5, L4 ;4列扫描完毕了吗? MOV A, R3 ;扫描值载入 SETB C ;C=1 RRC A ;扫描下一行(P1.3~P1.0) MOV R3, A ;存回扫描寄存器 JC L3 ;C=1?是则P1.0尚未扫描到 SJMP KEYSCAN ;C=0,则四行已扫描完毕 KEYIN: MOV R7, #60 ;延时消除抖动 D2: MOV R6, #248 ; DJNZ R6, $ ; DJNZ R7, D2 ; D3: MOV A, P1 ;延时后再读入P1值 XRL A, R4 ;与上次读入值作比较 JZ D3 ;A=0,表示按键未放,等待按键释放 MOV A, R1 ;按键已放开,取码指针载入累加器 MOV DPTR,#TABLE ;键盘码表首地址送DPTR MOVC A, @A+DPTR ;查键码 RET ;返回
TABLE: DB 00H,01H,02H,03H ;键码安排表与键盘相同 DB 04H,05H,06H,07H DB 08H,09H,0AH,0BH DB 0CH,0DH,0EH,0FH ORG 0200H
DISPLAY:MOV R0, #DBUF ;串口静态显示子程序 MOV R2,#3 ;显示3位数码 MOV DPTR,#SEGTAB; DISP: MOV A,@R0 ; MOVC A,@A+DPTR ;取字段码 MOV SCON,#0 ;置串口工作方式0 MOV SBUF,A ;开始发送 JNB TI,$ ;等待发送完毕 CLR TI ;发送完毕,标志位清零 INC R0 ;缓冲单元地址增1 DJNZ R2,DISP ;三位数码发送完否? RET ;发送完毕,则返回 SEGTAB: DB 0FCH,60H,0DAH,0F2H ;0,1,2,3(共阳极字段码表) DB 66H,0B6H, 0BEH,0E0H ;4,5,6,7 DB 0FEH,0F6H,0EEH,3EH ;8,9,A,B DB 9CH,7AH,9EH,8EH ;C,D,+,- END DBUF
EQU
30H
;三位显示缓冲区首址
- 23 -
ORG AJMP
0000H MAIN
ORG 0030H
MAIN: MOV SP,#60H
NEXT1: NEXT2:
KEYSZ:
L1:
L2:
KEYSCAN: ACALL KEYSCAN ;调用键盘扫描子程序判断是加分或减分
CJNE
A,#0EH,NEXT2
;不是加分键,则转移判断是减分键?
ACALL KEYSZ
;是加分键,调用键盘设置子程序 ACALL DISPLAY ;调用串口静态显示子程序
SJMP
MAIN
CJNE A,#0FH,MAIN ;都不是,则转MAIN AJMP
NEXT1
;是减分键,调用键盘设置子程序
ORG 0100H
PUSH PSW
;键盘设置子程序
PUSH ACC SETB RS1 MOV R0,#DBUF ;R0指向显示缓冲区首地址 MOV R7,#3 ;设置键盘输入位数 CLR
RS1
ACALL KEYSCAN ;调用键盘扫描子程序取按下键的键号 SETB RS1
CJNE A,#0AH,L2 ;键入数合法性检测(是否大于9) JNC L1 ;大于9,重新键入 MOV R0,A
;键号送显示缓冲区
INC R0 DJNZ R7,L1 ;3位数值输入完否?未完继续,否则返回 POP ACC POP PSW CLR RS1
RET
MOV R3, #0F7H ;扫描初值(P0.3=0)
- 24 -
MOV MOV MOV MOV MOV SETB MOV RLC JNC INC DJNZ MOV SETB RRC MOV JC SJMP
R1, #00H A, R3 P0, A A, P0 R4, A C
;取码指针 ;开始扫描
;将扫描值输出至P1
;读入P1值,判断是否有键按下 ;存入R4,以判断按键是否放开 ;C=1
;扫描P1.4~P1.7 ;将按键左移一位
;判断C=0?有键按下则C=0,跳至KEYIN ;C=1,则无键按下,将取码指针值加1 ;4列扫描完毕了吗? ;扫描值载入 ;C=1
;扫描下一行(P1.3~P1.0) ;存回扫描寄存器
;C=1?是则P1.0尚未扫描到 ;C=0,则四行已扫描完毕 ;延时消除抖动 ; ; ;
;延时后再读入P1值 ;与上次读入值作比较
;A=0,表示按键未放,等待按键释放 ;按键已放开,取码指针载入累加器
L3:
R5, #04H A
L4:
KEYIN R1
R5, L4 A, R3 C A
R3, A L3
KEYSCAN R7, #60 R6, #248 R6, $ R7, D2 A, P0 A, R4 D3
KEYIN: MOV D2: MOV
DJNZ DJNZ
D3: MOV
XRL JZ MOV MOV MOVC RET
A, R1
DPTR,#TABLE ;键盘码表首地址送DPTR A, @A+DPTR ;查键码
;返回
TABLE: DB 00H,01H,02H,03H ;键码安排表与键盘相同
DB 04H,05H,06H,07H
- 25 -
DB 08H,09H,0AH,0BH DB 0CH,0DH,0EH,0FH ORG 0200H
;串口静态显示子程序 ;显示3位数码
DISPLAY:MOV R0, #DBUF
MOV MOV
R2,#3
DPTR,#SEGTAB; DISP:
SEGTAB: DB DB DB
A,@R0
;
A,@A+DPTR ;取字段码 SCON,#0 ;置串口工作方式0 SBUF,A ;开始发送 TI,$ ;等待发送完毕 TI ;发送完毕,标志位清零 R0
;缓冲单元地址增1 R2,DISP ;三位数码发送完否?
;发送完毕,则返回
0FCH,60H,0DAH,0F2H ;0,1,2,3(共阳极字段码表) 66H,0B6H, 0BEH,0E0H ;4,5,6,7 0FEH,0F6H,0EEH,3EH ;8,9,A,B DB
9CH,7AH,9EH,8EH
;C,D,+,-
- 26 -
MOV MOVC MOV MOV JNB CLR INC
DJNZ RET
END
抢答器软件程序(附2)
#include
//uchar code table[]={0x00,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe }; /*代码存储区(64KB)*/
//共阳码
uchar code table[]={0x03,0x9f,0x25,0x0d,0x99,0xc2,0x41,0x1f,0x01,0xff }; void delay (void) { /* delay 函数*/ uchar i,j; /*这个函数执行时间的延迟 */
for (i=0;i<20;i++)
for(j=0;j<250;j++) ;
}
void main (void) {
uchar temp,key,j,time; /* 声明变量temp */ while (1) { /* 无穷循环 */ */
delay(); temp=P0;
temp=P0;
/* 将P2输入的数据直接放入变量temp当中
switch(temp) {
case 0xfe: key = 1;break; case 0xfd: key = 2;break; case 0xfb: key = 3;break; case 0xf7: key = 4;break; case 0xef: key = 5;break; case 0xdf: key = 6;break; case 0xbf: key = 7;break; case 0x7f: key = 8;break;
- 27 -
default : break; }
if(temp==0xff) { for(time=1;time>0;time--) /*无键按下,则关显示*/
{ j=table[0];
SCON=0x00;
}
/*取键值并显示*/ SBUF=j; while(TI!=1); TI=0; }
else { j=table[key]; SCON=0x00;
SBUF=j; while(TI!=1); }
delay(); } } TI=0; for(;;)
/*指示显示,并实现锁键功能*/
{ P1=temp;
}
- 28 -