level 1
4.4 主要程序分析主程序:
OK EQU 20H ;抢答开始标志位
RING EQU 22H ;响铃标志位
DATA0 EQU 36H ;抢答按键口数据存放地址
ORG 0000H
AJMP MAIN
ORG 0003H
AJMP INTT0
ORG 000BH
AJMP T0INT
ORG 001BH
AJMP T1INT
ORG 0040H
MAIN: MOV R1, #20 ;初设抢答时间为20s
MOV R2, #30 ;初设答题时间为30s
MOV 38h, #60 ;启用锦囊时间从60s倒计时
MOV TMOD, #11H ;设置未定时器/模式1
MOV TH0, #0F0H
MOV TL0, #0FFH ;越高发声频率越高,越尖
MOV TH1, #3CH
MOV TL1, #0B0H ;50ms为一次溢出中断
SETB EA
SETB ET0
SETB ET1 ;允许二个中断,T0/T1
CLR OK
CLR RING
SETB TR1
SETB TR0 ;一开始就运行定时器,以开始显示FFF.如果想重新计数,重置TH1/TL1就可以了
查询程序: START:
MOV DATA0,#0FFH ;初始化
MOV R5,#0BH
MOV R4,#0BH
MOV R3,#0BH
ACALL DISPLAY ;未开始抢答时候显示FFF JNB P3.3,SELSUB0 JNB P3.4,TZ3 ;倒计时调整 JB P3.0,NEXT ACALL DELAY JB P3.0,NEXT ;去抖动,如果“开始键”按下就向下执行,否者跳到非法抢答查询 SETB EX0 ;开放INT0 ACALL BARK ;按键发声 MOV A,R1 MOV R6,A ;送R1到R6,因为R1中保存了抢答时间 SETB OK ;抢答标志位,在使用锦囊时用作判断是抢答倒计时还是回答倒计时 MOV R3,#0AH ;抢答只显示计时,灭号数 AJMP COUNT ;进入倒计时程序,“查询有效抢答的程序”在COUNT里面NEXT: JNB P1.0,FALSE1 JNB P1.1,FALSE2 JNB P1.2,FALSE3 JNB P1.3,FALSE4 JNB P1.4,FALSE5 JNB P1.5,FALSE6 JNB P1.6,TZ1 JNB P1.7,TZ2 AJMP START TZ1: AJMP FALSE7TZ2: AJMP FALSE8TZ3: AJMP SELSUB1非法抢答处理程序:FALSE1: MOV R3,#01H AJMP ERRORFALSE2: MOV R3,#02H AJMP ERRORFALSE3: MOV R3,#03H AJMP ERRORFALSE4: MOV R3,#04H AJMP ERRORFALSE5: MOV R3,#05H AJMP ERRORFALSE6: MOV R3,#06H AJMP ERRORFALSE7: MOV R3,#07H AJMP ERRORFALSE8: MOV R3,#08H AJMP ERRORSELSUB0(抢答时间R1调整程序):SELSUB0: MOV A,R1 MOV B,#0AH DIV AB MOV R5,A MOV R4,B MOV R3,#0AH ACALL DISPLAY ;先在两个时间LED上显示R1 JNB P3.5,INC0 ;P3.5为+1s键,如按下跳到INCO JNB P3.6,DEC0 ;P3.6为-1s键,如按下跳到DECO JNB P3.1,BACK0 ;P3.1为确定键,如按下跳到BACKO AJMP SELSUB0INC0: MOV A,R1 CJNE A,#63H,ADD0 ;如果不是99,R2加1,如果加到99,R1就置0,重新加起。 MOV R1,#00H ACALL DELAY1 AJMP SELSUB0ADD0: INC R1 ACALL DELAY1 AJMP SELSUB0DEC0: MOV A,R1 JZ SETR1 ;如果R1为0, R1就置99, DEC R1 ACALL DELAY1 AJMP SELSUB0SETR1: MOV R1,#63H ACALL DELAY1 AJMP SELSUB0BACK0: AJMP STARTSELSUB1(回答时间R2调整程序):SELSUB1: MOV A,R2 MOV B,#0AH DIV AB MOV R5,A MOV R4,B MOV R3,#0AH ACALL DISPLAY JNB P3.5,INC1 JNB P3.6,DEC1 JNB P3.1,BACK1 AJMP SELSUB1INC1: MOV A,R2 CJNE A,
#63H,ADD1 MOV R2,#
00H ACALL DELAY1AJMP SELSUB1ADD1: INC R2 ACALL DELAY1 AJMP SELSUB1DEC1: MOV A,R2 JZ SETR2 DEC R2 ACALL DELAY1 AJMP SELSUB1SETR2: MOV R2,#63H ACALL DELAY1 AJMP SELSUB1BACK1: AJMP START启用锦囊程序:REPEAT:MOV A,38h ;使用锦囊时重新计时 MOV R6,A CLR RING ;当倒计时进入最后5秒的时候,启用锦囊能消除蜂鸣倒计时程序(抢答倒计时和回答倒计时都跳到改程序):COUNT: MOV R0,#00H ;重置定时器中断次数 MOV TH1,
#3CH MOV TL1,#
0B0H ;重置定时器RECOUNT:MOV A,R6 ;R6保存了倒计时的时间,之前先将抢答时间或回答时间给R6 MOV B,#0AH DIV AB ;除十分出个位/十位 MOV 30H,A ;十位存于(30H) MOV 31H,B ;个位存于(31H) MOV R5,30H ;取十位 MOV R4,31H ;取个位 MOV A,R6 SUBB A,#07H JNC LARGER ;大于5s跳到LARGER,小于等于5s会提醒 MOV A,R0 CJNE A,#0AH,FULL ;1s中0.5s向下运行 CLR RING AJMP CHECKFULL: CJNE A,#14H,CHECK ;下面是1s的情况,响并显示号数并清R0,重新计 SETB RING MOV A,R6 JZ QUIT ;计时完毕 MOV R0,#00H DEC R6 ;一秒标志减1 AJMP CHECKLARGER: MOV A,R0 CJNE A,#14H,CHECK ;如果1s向下运行,否者跳到“停/显示” DEC R6 ;计时一秒R6自动减1 MOV R0,#00HCHECK: JNB P3.1,QUIT ;如按下停止键退出 JNB OK,CHECKK ;只在回答倒计时才有效 AJMP NEXTTCHECKK:JNB P3.0,REPEAT ;判断是否使用锦囊NEXTT: ACALL DISPLAY JB OK,ACCOUT;如果是抢答倒计时,如是则查询抢答,否者跳过查询继续倒数(这里起到锁抢答作用) AJMP RECOUNTACCOUT:MOV A,DATA0 JNB ACC.0,TRUE1 JNB ACC.1,TRUE2 JNB ACC.2,TRUE3 JNB ACC.3,TRUE4 JNB ACC.4,TRUE5 JNB ACC.5,TRUE6 JNB ACC.6,TZ7 JNB ACC.7,TZ8 AJMP RECOUNT TZ7: AJMP TRUE7 TZ8: AJMP TRUE8 QUIT: CLR OK ;如果按下了“停止键”执行的程序 CLR RING AJMP START 正常抢答处理程序:TRUE1: ACALL BARK MOV A,R2 MOV R6,A ;抢答时间R2送R6 MOV R3,#01H CLR OK ;因为答题的计时不再查询抢答,所以就锁了抢答 AJMP COUNTTRUE2:ACALL BARK MOV A,R2 MOV R6,A MOV R3,#02H CLR OK AJMP COUNTTRUE3:ACALL BARK MOV A,R2 MOV R6,A MOV R3,#03H CLR OK AJMP COUNTTRUE4:ACALL BARK MOV A,R2 MOV R6,A MOV R3,#04H CLR OK AJMP COUNTTRUE5: ACALL BARK MOV A,R2 MOV R6,A MOV R3,#05H CLR OK AJMP COUNTTRUE6: ACALL BARK MOV A,R2 MOV R6,A MOV R3,#06H CLR OK AJMP COUNTTRUE7: ACALL BARK MOV A,R2 MOV R6,A MOV R3,#07H CLR OK AJMP COUNTTRUE8: ACALL BARK MOV A,R2 MOV R6,A MOV R3,#08H CLR OKAJMP COUNT犯规抢答程序:ERROR: MOV R0,#00H MOV TH1,
#3CH MOV TL1,#
0B0H MOV 34H,R3 ;犯规号数暂存与(34H) HERE: MOV A,R0 CJNE A,#06H,FLASH ;0.3s向下运行->灭并停响 CLR RING MOV R3,#0AH MOV R4,
#0AH MOV R5,#
0AH ;三灯全灭 AJMP CHECK1 FLASH: CJNE A,#0CH,CHECK1 ;下面是0.8s的情况,响并显示号数并清R0,重新计 SETB RING MOV R0,#00H MOV R3,34H ;取回号数 MOV R5,
#0BH MOV R4,#
0BH ;显示FF和号数 AJMP CHECK1CHECK1: JNB P3.1,QUIT1 ACALL DISPLAY AJMP HEREQUIT1: CLR RING CLR OK AJMP START显示程序:DISPLAY:MOV DPTR,#DAT1 ;查表显示程序,利用P0口做段选码口输出/P2低三位做位选码输出 MOV A,R3 MOVC A,@A+DPTR MOV P2,#0feH MOV P0,A ACALL DELAY MOV DPTR,#DAT2 MOV A,R5 MOVC A,@A+DPTR MOV P2,#0fdH MOV P0,A ACALL DELAY MOV A,R4 MOVC A,@A+DPTR MOV P2,#0fbH MOV P0,A ACALL DELAY RETDAT1:DB 00h,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,00H,71H ;"灭","1","2","3","4","5","6","7","8","9","灭","F"DAT2:DB 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,00H,71H;第一个为零,其他与上相同,因为十位如果为零显示熄灭加减时间延时(起到不会按下就加N个数):DELAY1: MOV 35H,#08HLOOP0: ACALL DISPLAY DJNZ 35H,LOOP0 RET延时(显示和去抖动用到):DELAY: MOV 32H,
#20LOOP: MOV 33H,#
125LOOP1: DJNZ 33H,LOOP1 DJNZ 32H,LOOP RET发声程序:BARK: SETB RING ACALL DELAY1 ACALL DELAY1 CLR RING ;按键发声 RETTO溢出中断(响铃程序) :T0INT: MOV TH0,
#0ECH MOV TL0,#
0FFH JNB RING,OUT; CPL P3.7 ;RING标志位为1时候P3.7口不断取反使喇叭发出一定频率的声音OUT: RETIT1溢出中断(计时程序):T1INT: MOV TH1,
#3CH MOV TL1,#
0B0H INC R0 RETI中断服务程序: INTT0: MOV DATA0,P1 CLR EX0 RETI END
程序如上,望解惑
2013年05月20日 05点05分
