图中
1~8号按键选手按键
9:复位键
10:开始/重答键
11:停止/确定键
12:抢答时间调节键
13 :回答时间调节键
14:时间调节、分数调节加一键
15:时间调节、分数调节减一键
16:分数查看/犯规处理/回答完毕
使用说明:
1、抢答、答题
在E EE 状态(初始状态)下,按下键10,则开始进入抢答中,若无人抢答,当计时结束后跳回初始状态。若有人抢答,则进入回答等待状态,当再次按下键10则开始计时,在计时没结束之前可以按下键10 重新回答。当计时结束或按下键16表示回答完毕,进入分数修改程序。按键14/15修改分数后,再按键11返回。
2、查看分数
当数码管显示E EE状态时,点击键16会进入分数查看程序,初始时显示选手1的等分情况,每位选手初试分数为10分,当长按下各选手的抢答开关,就会显示对应选手的得分。开关断开,又会回到初始状态,当按下键11 即可恢复到E EE状态。
3、抢答犯规程序
当数码管显示E EE时,若有选手抢答则是违规的,数码将显示抢答位数,点击键16进入分数修改程序,按键14/15实现对分数的加减,修改完毕 按键11, 确定并退出。
4、抢答时间/回答时间修该
按下键12/13进入分数修改程序,按键14/15实现对分数的加减,修改完毕 按键11, 确定并退出。
5、复位
按下键9则复位单片机,清除一切数据。
程序:
OK EQU 20H ; 抢答开始标志位
RING EQU 22H ; 响铃标志位
ORG 0000H
AJMP MAIN
ORG 0003H
AJMP QTIM0
ORG 000BH
AJMP OVERR
ORG 0013H
AJMP ASKTIM0
ORG 001BH
AJMP OVERT
ORG 0040H
MAIN:
MOV R1,#20 ; 初设抢答时间为20s
MOV R2,#60 ; 初设答题时间为60s
MOV 50H ,#10
MOV 51H ,#10
MOV 52H ,#10
MOV 53H ,#10
MOV 54H ,#10
MOV 55H ,#10
MOV 56H ,#10
MOV 57H ,#10 ; 初始化各选说分数为10分
MOV TMOD,#11H ; 设置定时器/不受外部中断控制/定时/模式1 MOV TH0,#0F0H
MOV TL0,#0FFH ; 越高发声频率越高, 越尖
MOV TH1,#3CH
MOV TL1,#0B0H ;50ms 为一次溢出中断
SETB EA ;CPU 开中断
SETB ET0
SETB ET1
SETB EX0
SETB EX1 ; 允许四个中断,T0/T1/INT0/INT1 CLR OK
CLR RING
SETB TR1
SETB TR0 ; 一开始就运行定时器, 以开始显示E EE. 如果想重新计数, 重置TH1/TL1就可以了
;*****查询程序*****
START:
MOV R5,#0BH
MOV R4,#0BH
MOV R3,#0BH
ACALL XIANSHI ; 未开始抢答时候显示E EE
JNB P3.6,SCOCH
JB P3.0,NEX ; 如果" 开始键" 按下就向下执行, 否者跳到非法抢答查询
ACALL BARK ; 按键发声
MOV A,R1
MOV R6,A ; 送R1->R6,因为R1中保存了抢答时间
SETB OK ; 抢答标志位, 用于BACKT 只程序中判断是否查询抢答
MOV R7,#01H ; 读抢答键数据信号标志,这里表示只读一次有用信号
MOV R3,#0AH ; 抢答只显示计时, 灭号数
AJMP BACKT ; 进入倒计时程序," 查询有效抢答的程序" 在BACKT 里面
NEX:
AJMP NEXT
;*****分数查询******
STAR:
ACALL BARK
AJMP START
SCOCH:
ACALL BARK
AJMP SCOCHA
SCOCHA:
JNB
JNB
JNB
JNB
JNB
JNB
JNB
JNB
JNB
S1:
MOV
MOV
AJMP
S2:
MOV
MOV
AJMP
S3:
MOV
MOV
AJMP
S4:
MOV
MOV
AJMP
S5:
MOV
MOV
AJMP
S6:
MOV
MOV
AJMP P3.1,STAR P1.0,S1 P1.1,S2 P1.2,S3 P1.3,S4 P1.4,S5 P1.5,S6 P1.6,S7 P1.7,S8 R3,#01H A,50H SS R3,#02H A,51H SS R3,#03H A,52H SS R3,#04H A,53H SS R3,#05H A,54H SS R3,#06H A,55H SS
S7:
MOV R3,#07H
MOV A,56H
AJMP SS
S8:
MOV R3,#08H
MOV A,57H
AJMP SS
SS: MOV B,#0AH
DIV AB
MOV R5,A
MOV R4,B
ACALL DELAY1
AJMP SCOCHA
NEXT:
MOV A, P1
MOV 36H,A
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,FALSE7
JNB P1.7,FALSE8
AJMP START
;*****非法抢答处理程序*****
FALSE1:
MOV R3,#01H
AJMP ERROR
FALSE2:
MOV R3,#02H
AJMP ERROR
FALSE3:
MOV R3,#03H
AJMP ERROR
FALSE4:
MOV R3,#04H
AJMP ERROR
FALSE5:
MOV R3,#05H
AJMP ERROR
FALSE6:
MOV R3,#06H
AJMP ERROR
FALSE7:
MOV R3,#07H
AJMP ERROR
FALSE8:
MOV R3,#08H
AJMP ERROR
;*****抢答时间R1调整程序*****
QTIM0:
ACALL BARK
QTIME:
MOV A,R1
MOV B,#0AH
DIV AB
MOV R5,A
MOV R4,B
MOV R3,#0AH
ACALL XIANSHI ; 先在两个时间LED 上显示R1
JNB P3.4,INC0 ;P3.4为+1s键, 如按下跳到INCO
JNB P3.5,DEC0 ;P3.5为-1s 键, 如按下跳到DECO
JNB P3.1,BACK0 ;P3.1为确定键, 如按下跳到BACKO
AJMP QTIME
INC0:
ACALL BARK
MOV A,R1
CJNE A,#63H,ADD0 ; 如果不是99,R2加1, 如果加到99,R1就置0,重新加起。
MOV R1,#00H
ACALL DELAY1
AJMP QTIME
ADD0:
ACALL BARK
INC R1
ACALL DELAY1
AJMP QTIME
DEC0:
ACALL BARK
MOV A,R1
JZ SETR1 ; 如果R1为0, R1就置99,
DEC R1
AJMP QTIME
SETR1:
ACALL BARK
MOV R1,#63H
ACALL DELAY1
AJMP QTIME
BACK0:
RETI
;*****回答时间R2调整程序*****
ASKTIM0:
CLR OK
CLR RING
ACALL BARK
ASKTIME:
MOV A,R2
MOV B,#0AH
DIV AB
MOV R5,A
MOV R4,B
MOV R3,#0AH
ACALL XIANSHI
JNB P3.4,INC1
JNB P3.5,DEC1
JNB P3.1,BACK1
AJMP ASKTIME
INC1:
ACALL BARK
MOV A,R2
CJNE A,#63H,ADD1
MOV R2,#00H
ACALL DELAY1
AJMP ASKTIME
ADD1:
INC R2
ACALL DELAY1
AJMP ASKTIME
DEC1:
ACALL BARK
MOV A,R2
JZ SETR2
DEC R2
AJMP ASKTIME
SETR2:
MOV R2,#63H
ACALL DELAY1
AJMP ASKTIME
BACK1:
RETI
;*********分数修改********
SCORES:
MOV A,R7
MOV B,#0AH
DIV AB
MOV R5,A
MOV R4,B
ACALL XIANSHI
JNB P3.4,INC2
JNB P3.5,DEC2
JNB P3.1,BACK2
AJMP SCORES
INC2:
ACALL BARK
MOV A,R7
CJNE A,#63H,ADD2
MOV R7,#00H
ACALL DELAY1
AJMP SCORES
ADD2:
INC R7
ACALL DELAY1
AJMP SCORES
DEC2:
ACALL BARK
MOV A,R7
JZ SETR3 ; 若A 为零转SETR2
DEC R7
ACALL DELAY1
AJMP SCORES
SETR3:
MOV R7,#63H
ACALL DELAY1
AJMP SCORES
BACK2:
RET
;*****抢答倒计时和回答倒计时程序*****
REASK:
MOV A,R2 ; 重答重新计时
MOV R6,A
CLR RING
BACKT:
MOV R0,#00H ; 重置定时器中断次数
MOV TH1,#3CH
MOV TL1,#0B0H ; 重置定时器
BACKTIM:
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 ;(A)-CY-#07H-->A
JNC LARGER ; 大于5s 跳到LARGER, 小于等于5s 会提醒 MOV A,R0
CJNE A,#0AH,FULL ;1s 中0.5s 向下运行
CLR RING
AJMP CHECK
FULL:
CJNE A,#14H,CHECK ; 下面是1s 的情况, 响并显示号数并清R0, 重新计 SETB RING
MOV A,R6
JZ TUICH00 ; 计时完毕
MOV R0,#00H
DEC R6 ; 一秒标志减1
AJMP CHECK
LARGER:
MOV A,R0
CJNE A,#14H,CHECK ; 如果1s 向下运行, 否者跳到查" 停/显示" DEC R6 ; 计时一秒R6自动减1
MOV R0,#00H
CHECK:
JNB OK,AGAIN ; 只在回答倒计时才有效
JNB P3.1,TUICHU ;如按下停止键退出
AJMP NEXTT
AGAIN:
JNB P3.0,REASK ; 判断是否重新答题
JNB P3.6,TUICH00 ;是否预先结束
NEXTT:
ACALL XIANSHI
JB OK,FIND ; 如果是抢答倒计时, 如是则查询抢答, 否者跳过查询继续倒数(这里起到锁抢答作用)
AJMP BACKTIM
TUICH00:
JB OK,TUICHU ; 判断退出时是否在抢答中
AJMP TUICHU0
FIND:
MOV A,36H
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,TRUE7
JNB ACC.7,TR8
AJMP BACKTIM
TR8:
AJMP TRUE8
TUICHU:
CLR OK ; 如果按下了" 停止键" 执行的程序
CLR RING
ACALL BARK
SETB P2.7 ; 指示灯熄灭
AJMP START
;*****正常抢答处理程序*****
TRUE1:
ACALL BARK
MOV A,R2
MOV R6,A ; 答题时间R2送R6
MOV R3,#01H
CLR P2.4
CLR P2.5
CLR P2.6 ; 显示抢答结果
AJMP TRUEE
TRUE2:
ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#02H
SETB P2.4
CLR P2.5
CLR P2.6
AJMP TRUEE
TRUE3:
ACALL BARK
MOV
MOV
MOV
CLR
SETB
CLR
AJMP
TRUE4:
ACALL
MOV
MOV
MOV
SETB
SETB
CLR
AJMP
TRUE5:
ACALL
MOV
MOV
MOV
CLR
CLR
SETB
AJMP
TRUE6:
ACALL
MOV
MOV
MOV
SETB A,R2 R6,A R3,#03H P2.4 P2.5 P2.6 TRUEE BARK A,R2 R6,A R3,#04H P2.4 P2.5 P2.6 TRUEE BARK A,R2 R6,A R3,#05H P2.4 P2.5 P2.6 TRUEE BARK A,R2 R6,A R3,#06H P2.4
CLR P2.5
SETB P2.6
AJMP TRUEE
TRUE7:
ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#07H
CLR P2.4
SETB P2.5
SETB P2.6
AJMP TRUEE
TRUE8:
ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#08H
SETB P2.4
SETB P2.5
SETB P2.6
AJMP TRUEE
TRUEE:
CLR P2.7 ; 启动74138
CLR OK ; 封锁抢答
ASK:
MOV A,R6 ;R6保存了倒计时的时间, 之前先将抢答时间或回答时间给R6
MOV B,#0AH
DIV AB ; 除十分出个位/十位
MOV 30H,A ; 十位存于(30H)
MOV 31H,B ; 个位存于(31H)
MOV R5,30H ; 取十位
MOV R4,31H
ACALL XIANSHI
JB P3.0, ASK ; 等待开始答题指令
ACALL BARK
AJMP BACKT
;*****选择分数修改位*****
TUICHU0:
CLR OK
CLR RING
MOV A,36H
JNB ACC.0,SCO1
JNB ACC.1,SCO2
JNB ACC.2,SCO3
JNB ACC.3,SCO4
JNB ACC.4,SCO5
JNB ACC.5,SCO6
JNB ACC.6,SCO7
JNB ACC.7,SC8
SC8:
AJMP SCO8
TUICHUU:
SETB P2.7
AJMP START
SCO1:
ACALL BARK
MOV R7 ,50H
MOV R3,#01H
ACALL SCORES
MOV 50H,R7
AJMP TUICHUU
SCO2:
ACALL BARK
MOV R7 ,51H
MOV R3,#02H
ACALL SCORES
MOV 51H,R7
AJMP TUICHUU
SCO3:
ACALL BARK
MOV R7 ,52H
MOV R3,#03H
ACALL SCORES
MOV 52H,R7
AJMP TUICHUU
SCO4:
ACALL BARK
MOV R7 ,53H
MOV R3,#04H ; 指示灯熄灭
ACALL SCORES
MOV 53H,R7
AJMP TUICHUU
SCO5:
ACALL BARK
MOV R7 ,54H
MOV R3,#05H
ACALL SCORES
MOV 54H,R7
AJMP TUICHUU
SCO6:
ACALL BARK
MOV R7 ,55H
MOV R3,#06H
ACALL SCORES
MOV 55H,R7
AJMP TUICHUU
SCO7:
ACALL BARK
MOV R7 ,56H
MOV R3,#07H
ACALL SCORES
MOV 56H,R7
AJMP TUICHUU
SCO8:
ACALL BARK
MOV R7 ,57H
MOV R3,#08H
ACALL SCORES
MOV 57H,R7
AJMP TUICHUU
;*****抢答犯规程序*****
ERROR:
MOV R0,#00H
MOV TH1,#3CH
MOV TL1,#0B0H
MOV 34H,R3
HERE:
MOV A,R0
CJNE A,#06H,FLASH
CLR RING
MOV R3,#0AH
MOV R4,#0AH
MOV R5,#0AH ; 犯规号数暂存与(34H) ; 0.3s向下运行->灭并停响 ; 三灯全灭
FLASH:
CJNE A,#0CH,CHECK1 ; 下面是0.8s 的情况, 响并显示号数并清R0, 重新计
SETB RING
MOV R0,#00H
MOV R3,34H ; 取回号数
MOV R5,#0BH
MOV R4,#0BH ; 显示EE 和号数
AJMP CHECK1
CHECK1:
JNB P3.6,TUICHU1 ; 处理犯规
JNB P3.1,STOP ; 退出犯规处理
ACALL XIANSHI
AJMP HERE
TUICHU1:
CLR RING
CLR OK
AJMP TUICHU0
STOP:
AJMP TUICHU
;*****显示程序*****
XIANSHI:
MOV DPTR,#DAT1 ; 查表显示程序, 利用P0口做段选码口输出/P2低三位做位选码输出,
MOV A,R3
MOVC A,@A+DPTR
SETB P2.2
CLR P2.0
MOV P0,A
ACALL DELAY2
MOV DPTR,#DAT2
MOV A,R5
MOVC A,@A+DPTR
SETB P2.0
CLR P2.1
MOV P0,A
ACALL DELAY2
MOV A,R4
MOVC A,@A+DPTR
CLR P2.2
MOV P0,A
ACALL DELAY2
RET
DAT1:
DB 00H,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,00H,79H
;" 灭","1","2","3","4","5","6","7","8","9"," 灭","E"
DAT2:
DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,00H,79H
; 第一个为零, 其他与上相同, 因为十位如果为零显示熄灭
;****加减时间延时******
DELAY1:
MOV 35H,#08H
LOOP0:
ACALL XIANSHI
DJNZ 35H,LOOP0
RET
;*****延时去抖动用到*****
DELAY:
MOV 32H,#10H
LOOP:
MOV 33H,#0AFH
LOOP1:
DJNZ 33H,LOOP1
DJNZ 32H,LOOP
RET
;*****延时用于显示*****
DELAY2:
MOV 32H,#43H
LOOP3:
MOV 33H,#1EH
MOV A,R7 ; 每隔60~70个机器周期读一次P1口, 全为1时为无效数据, 继续读, 有一个不为1时, 转到正常抢答处理
JNZ READ0 ; 没读到有效数据时继续转到READ0 LOOP2:
DJNZ 33H,LOOP2
DJNZ 32H,LOOP3
RET
;*****读抢答按键数据口程序*****
; 由于在读抢答数据口的时候,单片机首先进入倒计时程序,再调用显示程序,最后才检测
按键口
; 然而在检测按键口时动态扫描要调用三次延时程序. 这样就会导致读数据口出现滞后, 造成1号优先最高.8号最低.
; 故采用在延时子程序中加了读数据口程序. 保证了灵敏度和可靠性
READ0:
MOV A,P1
CJNE A,#0FFH,AA1 ; 当不全为1时的数据为有效数据
AA0:
MOV 36H,A ; 将有效数据送到36H 暂存
AJMP LOOP2
AA1:
DEC R7
AJMP AA0
;*****发声程序*****
BARK:
SETB RING
ACALL DELAY1
ACALL DELAY1
CLR RING ; 按键声
CLR P3.7
RET
;*****溢出响铃程序*****
OVERR:
MOV TH0,#0ECH
MOV TL0,#0FFH
JNB RING ,OUT ;
CPL P3.7 ;RING 标志位为1时候P3.7口不短取反使喇叭发出一定频率的声音
OUT:
RETI
;*****溢出计时程序*****
OVERT:
MOV TH1,#3CH
MOV TL1,#0B0H
INC R0
RETI
END
图中
1~8号按键选手按键
9:复位键
10:开始/重答键
11:停止/确定键
12:抢答时间调节键
13 :回答时间调节键
14:时间调节、分数调节加一键
15:时间调节、分数调节减一键
16:分数查看/犯规处理/回答完毕
使用说明:
1、抢答、答题
在E EE 状态(初始状态)下,按下键10,则开始进入抢答中,若无人抢答,当计时结束后跳回初始状态。若有人抢答,则进入回答等待状态,当再次按下键10则开始计时,在计时没结束之前可以按下键10 重新回答。当计时结束或按下键16表示回答完毕,进入分数修改程序。按键14/15修改分数后,再按键11返回。
2、查看分数
当数码管显示E EE状态时,点击键16会进入分数查看程序,初始时显示选手1的等分情况,每位选手初试分数为10分,当长按下各选手的抢答开关,就会显示对应选手的得分。开关断开,又会回到初始状态,当按下键11 即可恢复到E EE状态。
3、抢答犯规程序
当数码管显示E EE时,若有选手抢答则是违规的,数码将显示抢答位数,点击键16进入分数修改程序,按键14/15实现对分数的加减,修改完毕 按键11, 确定并退出。
4、抢答时间/回答时间修该
按下键12/13进入分数修改程序,按键14/15实现对分数的加减,修改完毕 按键11, 确定并退出。
5、复位
按下键9则复位单片机,清除一切数据。
程序:
OK EQU 20H ; 抢答开始标志位
RING EQU 22H ; 响铃标志位
ORG 0000H
AJMP MAIN
ORG 0003H
AJMP QTIM0
ORG 000BH
AJMP OVERR
ORG 0013H
AJMP ASKTIM0
ORG 001BH
AJMP OVERT
ORG 0040H
MAIN:
MOV R1,#20 ; 初设抢答时间为20s
MOV R2,#60 ; 初设答题时间为60s
MOV 50H ,#10
MOV 51H ,#10
MOV 52H ,#10
MOV 53H ,#10
MOV 54H ,#10
MOV 55H ,#10
MOV 56H ,#10
MOV 57H ,#10 ; 初始化各选说分数为10分
MOV TMOD,#11H ; 设置定时器/不受外部中断控制/定时/模式1 MOV TH0,#0F0H
MOV TL0,#0FFH ; 越高发声频率越高, 越尖
MOV TH1,#3CH
MOV TL1,#0B0H ;50ms 为一次溢出中断
SETB EA ;CPU 开中断
SETB ET0
SETB ET1
SETB EX0
SETB EX1 ; 允许四个中断,T0/T1/INT0/INT1 CLR OK
CLR RING
SETB TR1
SETB TR0 ; 一开始就运行定时器, 以开始显示E EE. 如果想重新计数, 重置TH1/TL1就可以了
;*****查询程序*****
START:
MOV R5,#0BH
MOV R4,#0BH
MOV R3,#0BH
ACALL XIANSHI ; 未开始抢答时候显示E EE
JNB P3.6,SCOCH
JB P3.0,NEX ; 如果" 开始键" 按下就向下执行, 否者跳到非法抢答查询
ACALL BARK ; 按键发声
MOV A,R1
MOV R6,A ; 送R1->R6,因为R1中保存了抢答时间
SETB OK ; 抢答标志位, 用于BACKT 只程序中判断是否查询抢答
MOV R7,#01H ; 读抢答键数据信号标志,这里表示只读一次有用信号
MOV R3,#0AH ; 抢答只显示计时, 灭号数
AJMP BACKT ; 进入倒计时程序," 查询有效抢答的程序" 在BACKT 里面
NEX:
AJMP NEXT
;*****分数查询******
STAR:
ACALL BARK
AJMP START
SCOCH:
ACALL BARK
AJMP SCOCHA
SCOCHA:
JNB
JNB
JNB
JNB
JNB
JNB
JNB
JNB
JNB
S1:
MOV
MOV
AJMP
S2:
MOV
MOV
AJMP
S3:
MOV
MOV
AJMP
S4:
MOV
MOV
AJMP
S5:
MOV
MOV
AJMP
S6:
MOV
MOV
AJMP P3.1,STAR P1.0,S1 P1.1,S2 P1.2,S3 P1.3,S4 P1.4,S5 P1.5,S6 P1.6,S7 P1.7,S8 R3,#01H A,50H SS R3,#02H A,51H SS R3,#03H A,52H SS R3,#04H A,53H SS R3,#05H A,54H SS R3,#06H A,55H SS
S7:
MOV R3,#07H
MOV A,56H
AJMP SS
S8:
MOV R3,#08H
MOV A,57H
AJMP SS
SS: MOV B,#0AH
DIV AB
MOV R5,A
MOV R4,B
ACALL DELAY1
AJMP SCOCHA
NEXT:
MOV A, P1
MOV 36H,A
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,FALSE7
JNB P1.7,FALSE8
AJMP START
;*****非法抢答处理程序*****
FALSE1:
MOV R3,#01H
AJMP ERROR
FALSE2:
MOV R3,#02H
AJMP ERROR
FALSE3:
MOV R3,#03H
AJMP ERROR
FALSE4:
MOV R3,#04H
AJMP ERROR
FALSE5:
MOV R3,#05H
AJMP ERROR
FALSE6:
MOV R3,#06H
AJMP ERROR
FALSE7:
MOV R3,#07H
AJMP ERROR
FALSE8:
MOV R3,#08H
AJMP ERROR
;*****抢答时间R1调整程序*****
QTIM0:
ACALL BARK
QTIME:
MOV A,R1
MOV B,#0AH
DIV AB
MOV R5,A
MOV R4,B
MOV R3,#0AH
ACALL XIANSHI ; 先在两个时间LED 上显示R1
JNB P3.4,INC0 ;P3.4为+1s键, 如按下跳到INCO
JNB P3.5,DEC0 ;P3.5为-1s 键, 如按下跳到DECO
JNB P3.1,BACK0 ;P3.1为确定键, 如按下跳到BACKO
AJMP QTIME
INC0:
ACALL BARK
MOV A,R1
CJNE A,#63H,ADD0 ; 如果不是99,R2加1, 如果加到99,R1就置0,重新加起。
MOV R1,#00H
ACALL DELAY1
AJMP QTIME
ADD0:
ACALL BARK
INC R1
ACALL DELAY1
AJMP QTIME
DEC0:
ACALL BARK
MOV A,R1
JZ SETR1 ; 如果R1为0, R1就置99,
DEC R1
AJMP QTIME
SETR1:
ACALL BARK
MOV R1,#63H
ACALL DELAY1
AJMP QTIME
BACK0:
RETI
;*****回答时间R2调整程序*****
ASKTIM0:
CLR OK
CLR RING
ACALL BARK
ASKTIME:
MOV A,R2
MOV B,#0AH
DIV AB
MOV R5,A
MOV R4,B
MOV R3,#0AH
ACALL XIANSHI
JNB P3.4,INC1
JNB P3.5,DEC1
JNB P3.1,BACK1
AJMP ASKTIME
INC1:
ACALL BARK
MOV A,R2
CJNE A,#63H,ADD1
MOV R2,#00H
ACALL DELAY1
AJMP ASKTIME
ADD1:
INC R2
ACALL DELAY1
AJMP ASKTIME
DEC1:
ACALL BARK
MOV A,R2
JZ SETR2
DEC R2
AJMP ASKTIME
SETR2:
MOV R2,#63H
ACALL DELAY1
AJMP ASKTIME
BACK1:
RETI
;*********分数修改********
SCORES:
MOV A,R7
MOV B,#0AH
DIV AB
MOV R5,A
MOV R4,B
ACALL XIANSHI
JNB P3.4,INC2
JNB P3.5,DEC2
JNB P3.1,BACK2
AJMP SCORES
INC2:
ACALL BARK
MOV A,R7
CJNE A,#63H,ADD2
MOV R7,#00H
ACALL DELAY1
AJMP SCORES
ADD2:
INC R7
ACALL DELAY1
AJMP SCORES
DEC2:
ACALL BARK
MOV A,R7
JZ SETR3 ; 若A 为零转SETR2
DEC R7
ACALL DELAY1
AJMP SCORES
SETR3:
MOV R7,#63H
ACALL DELAY1
AJMP SCORES
BACK2:
RET
;*****抢答倒计时和回答倒计时程序*****
REASK:
MOV A,R2 ; 重答重新计时
MOV R6,A
CLR RING
BACKT:
MOV R0,#00H ; 重置定时器中断次数
MOV TH1,#3CH
MOV TL1,#0B0H ; 重置定时器
BACKTIM:
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 ;(A)-CY-#07H-->A
JNC LARGER ; 大于5s 跳到LARGER, 小于等于5s 会提醒 MOV A,R0
CJNE A,#0AH,FULL ;1s 中0.5s 向下运行
CLR RING
AJMP CHECK
FULL:
CJNE A,#14H,CHECK ; 下面是1s 的情况, 响并显示号数并清R0, 重新计 SETB RING
MOV A,R6
JZ TUICH00 ; 计时完毕
MOV R0,#00H
DEC R6 ; 一秒标志减1
AJMP CHECK
LARGER:
MOV A,R0
CJNE A,#14H,CHECK ; 如果1s 向下运行, 否者跳到查" 停/显示" DEC R6 ; 计时一秒R6自动减1
MOV R0,#00H
CHECK:
JNB OK,AGAIN ; 只在回答倒计时才有效
JNB P3.1,TUICHU ;如按下停止键退出
AJMP NEXTT
AGAIN:
JNB P3.0,REASK ; 判断是否重新答题
JNB P3.6,TUICH00 ;是否预先结束
NEXTT:
ACALL XIANSHI
JB OK,FIND ; 如果是抢答倒计时, 如是则查询抢答, 否者跳过查询继续倒数(这里起到锁抢答作用)
AJMP BACKTIM
TUICH00:
JB OK,TUICHU ; 判断退出时是否在抢答中
AJMP TUICHU0
FIND:
MOV A,36H
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,TRUE7
JNB ACC.7,TR8
AJMP BACKTIM
TR8:
AJMP TRUE8
TUICHU:
CLR OK ; 如果按下了" 停止键" 执行的程序
CLR RING
ACALL BARK
SETB P2.7 ; 指示灯熄灭
AJMP START
;*****正常抢答处理程序*****
TRUE1:
ACALL BARK
MOV A,R2
MOV R6,A ; 答题时间R2送R6
MOV R3,#01H
CLR P2.4
CLR P2.5
CLR P2.6 ; 显示抢答结果
AJMP TRUEE
TRUE2:
ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#02H
SETB P2.4
CLR P2.5
CLR P2.6
AJMP TRUEE
TRUE3:
ACALL BARK
MOV
MOV
MOV
CLR
SETB
CLR
AJMP
TRUE4:
ACALL
MOV
MOV
MOV
SETB
SETB
CLR
AJMP
TRUE5:
ACALL
MOV
MOV
MOV
CLR
CLR
SETB
AJMP
TRUE6:
ACALL
MOV
MOV
MOV
SETB A,R2 R6,A R3,#03H P2.4 P2.5 P2.6 TRUEE BARK A,R2 R6,A R3,#04H P2.4 P2.5 P2.6 TRUEE BARK A,R2 R6,A R3,#05H P2.4 P2.5 P2.6 TRUEE BARK A,R2 R6,A R3,#06H P2.4
CLR P2.5
SETB P2.6
AJMP TRUEE
TRUE7:
ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#07H
CLR P2.4
SETB P2.5
SETB P2.6
AJMP TRUEE
TRUE8:
ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#08H
SETB P2.4
SETB P2.5
SETB P2.6
AJMP TRUEE
TRUEE:
CLR P2.7 ; 启动74138
CLR OK ; 封锁抢答
ASK:
MOV A,R6 ;R6保存了倒计时的时间, 之前先将抢答时间或回答时间给R6
MOV B,#0AH
DIV AB ; 除十分出个位/十位
MOV 30H,A ; 十位存于(30H)
MOV 31H,B ; 个位存于(31H)
MOV R5,30H ; 取十位
MOV R4,31H
ACALL XIANSHI
JB P3.0, ASK ; 等待开始答题指令
ACALL BARK
AJMP BACKT
;*****选择分数修改位*****
TUICHU0:
CLR OK
CLR RING
MOV A,36H
JNB ACC.0,SCO1
JNB ACC.1,SCO2
JNB ACC.2,SCO3
JNB ACC.3,SCO4
JNB ACC.4,SCO5
JNB ACC.5,SCO6
JNB ACC.6,SCO7
JNB ACC.7,SC8
SC8:
AJMP SCO8
TUICHUU:
SETB P2.7
AJMP START
SCO1:
ACALL BARK
MOV R7 ,50H
MOV R3,#01H
ACALL SCORES
MOV 50H,R7
AJMP TUICHUU
SCO2:
ACALL BARK
MOV R7 ,51H
MOV R3,#02H
ACALL SCORES
MOV 51H,R7
AJMP TUICHUU
SCO3:
ACALL BARK
MOV R7 ,52H
MOV R3,#03H
ACALL SCORES
MOV 52H,R7
AJMP TUICHUU
SCO4:
ACALL BARK
MOV R7 ,53H
MOV R3,#04H ; 指示灯熄灭
ACALL SCORES
MOV 53H,R7
AJMP TUICHUU
SCO5:
ACALL BARK
MOV R7 ,54H
MOV R3,#05H
ACALL SCORES
MOV 54H,R7
AJMP TUICHUU
SCO6:
ACALL BARK
MOV R7 ,55H
MOV R3,#06H
ACALL SCORES
MOV 55H,R7
AJMP TUICHUU
SCO7:
ACALL BARK
MOV R7 ,56H
MOV R3,#07H
ACALL SCORES
MOV 56H,R7
AJMP TUICHUU
SCO8:
ACALL BARK
MOV R7 ,57H
MOV R3,#08H
ACALL SCORES
MOV 57H,R7
AJMP TUICHUU
;*****抢答犯规程序*****
ERROR:
MOV R0,#00H
MOV TH1,#3CH
MOV TL1,#0B0H
MOV 34H,R3
HERE:
MOV A,R0
CJNE A,#06H,FLASH
CLR RING
MOV R3,#0AH
MOV R4,#0AH
MOV R5,#0AH ; 犯规号数暂存与(34H) ; 0.3s向下运行->灭并停响 ; 三灯全灭
FLASH:
CJNE A,#0CH,CHECK1 ; 下面是0.8s 的情况, 响并显示号数并清R0, 重新计
SETB RING
MOV R0,#00H
MOV R3,34H ; 取回号数
MOV R5,#0BH
MOV R4,#0BH ; 显示EE 和号数
AJMP CHECK1
CHECK1:
JNB P3.6,TUICHU1 ; 处理犯规
JNB P3.1,STOP ; 退出犯规处理
ACALL XIANSHI
AJMP HERE
TUICHU1:
CLR RING
CLR OK
AJMP TUICHU0
STOP:
AJMP TUICHU
;*****显示程序*****
XIANSHI:
MOV DPTR,#DAT1 ; 查表显示程序, 利用P0口做段选码口输出/P2低三位做位选码输出,
MOV A,R3
MOVC A,@A+DPTR
SETB P2.2
CLR P2.0
MOV P0,A
ACALL DELAY2
MOV DPTR,#DAT2
MOV A,R5
MOVC A,@A+DPTR
SETB P2.0
CLR P2.1
MOV P0,A
ACALL DELAY2
MOV A,R4
MOVC A,@A+DPTR
CLR P2.2
MOV P0,A
ACALL DELAY2
RET
DAT1:
DB 00H,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,00H,79H
;" 灭","1","2","3","4","5","6","7","8","9"," 灭","E"
DAT2:
DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,00H,79H
; 第一个为零, 其他与上相同, 因为十位如果为零显示熄灭
;****加减时间延时******
DELAY1:
MOV 35H,#08H
LOOP0:
ACALL XIANSHI
DJNZ 35H,LOOP0
RET
;*****延时去抖动用到*****
DELAY:
MOV 32H,#10H
LOOP:
MOV 33H,#0AFH
LOOP1:
DJNZ 33H,LOOP1
DJNZ 32H,LOOP
RET
;*****延时用于显示*****
DELAY2:
MOV 32H,#43H
LOOP3:
MOV 33H,#1EH
MOV A,R7 ; 每隔60~70个机器周期读一次P1口, 全为1时为无效数据, 继续读, 有一个不为1时, 转到正常抢答处理
JNZ READ0 ; 没读到有效数据时继续转到READ0 LOOP2:
DJNZ 33H,LOOP2
DJNZ 32H,LOOP3
RET
;*****读抢答按键数据口程序*****
; 由于在读抢答数据口的时候,单片机首先进入倒计时程序,再调用显示程序,最后才检测
按键口
; 然而在检测按键口时动态扫描要调用三次延时程序. 这样就会导致读数据口出现滞后, 造成1号优先最高.8号最低.
; 故采用在延时子程序中加了读数据口程序. 保证了灵敏度和可靠性
READ0:
MOV A,P1
CJNE A,#0FFH,AA1 ; 当不全为1时的数据为有效数据
AA0:
MOV 36H,A ; 将有效数据送到36H 暂存
AJMP LOOP2
AA1:
DEC R7
AJMP AA0
;*****发声程序*****
BARK:
SETB RING
ACALL DELAY1
ACALL DELAY1
CLR RING ; 按键声
CLR P3.7
RET
;*****溢出响铃程序*****
OVERR:
MOV TH0,#0ECH
MOV TL0,#0FFH
JNB RING ,OUT ;
CPL P3.7 ;RING 标志位为1时候P3.7口不短取反使喇叭发出一定频率的声音
OUT:
RETI
;*****溢出计时程序*****
OVERT:
MOV TH1,#3CH
MOV TL1,#0B0H
INC R0
RETI
END