KAI BIT P3.7 开始
------------------------------------------
ORG 0000H
JMP START
START:
----------------------下面是清零(复位)
MOV P0, #0C0H显示0
MOV P2, #255 熄灯
MOV R4, #0
----------------------下面等待按下洞友"开始"键
KAISHI:
JBKAI, KAISHI 没有按"开始",就循环
CALL DELAY延时
JBKAI, KAISHI 消抖
JNB KAI, $ 等待释放
----------------------
MOV P0, #0CH 显示P
WAIT: 等待抢答
MOV A, P1
CPL A
JZWAIT 继续等待
----------------------
XS:查找选谈做手按键的位置
CPL A
MOV P2, A
JNB ACC.0, J0
JNB ACC.1, J1
JNB ACC.2, J2
JNB ACC.3, J3
JNB ACC.4, J4
JNB ACC.5, J5
JNB ACC.6, J6
JMP J7
J7: INC R4
J6: INC R4
J5: INC R4
J4: INC R4
J3: INC R4
J2: INC R4
J1: INC R4
J0: INC R4
MOV A, R4
MOV DPTR, #D_TAB
MOVC A, @A + DPTR
MOV P0, A
----------------------下面等待按下复位键
W_FW:
JBKAI, W_FW没有按,则转
CALL DELAY延时
JBKAI, W_FW消抖
JNB KAI, $ 等待释放
JMP START
------------------------
D_TAB:
DB 0C0H,0F9H,0A4H,0B0H, 99H 共阳极0-9
DB92H, 82H,0F8H, 80H, 90H,0BFH -
------------------------------------------
DELAY: 延时约10ms
MOV R6, #20
DJNZ R7, $
DJNZ R6, $ - 2
RET
==========================================
END
以上纳侍槐程序已经调好。
先来桥拿如个汇编敏誉的程序,P1接一个共阳极数码管,P0低敏启4位接4个抢答按键,主持人复位采用单片机复位按钮实现。ORG 0000H
START: MOV A,P0
ORL A,#0F0H
CJNE A,#0FFH,PL0
SJMP START
PL0: LCALL DELAY
MOV A,P0
ORL A,#0F0H
CJNE A,#0FFH,PL1
SJMP START
PL1:JNB ACC.0,K1
JNB ACC.1,K2
JNB ACC.2,K3
JNB ACC.3,K4
LJMP START
K1:MOV P1,#0F9H
SJMP $
K2:MOV P1,#0A4H
SJMP $
K3:MOV P1,#0B0H
SJMP $
K4:MOV P1,#99H
SJMP $
DELAY:MOV R6,#15
DEL2: MOV R7,#200
DJNZ R7,$
DJNZ R6,DEL2
RET
END
OK EQU 20H抢答开始标志位RING EQU 22H响铃标志位
ORG 0000H
AJMP MAIN
ORG 0003H
AJMP INT0SUB
ORG 000BH
AJMP T0INT
ORG 0013H
AJMP INT1SUB
ORG 001BH
AJMP T1INT
ORG 0040H
MAIN: MOV R1,#30初设抢答时间为30s
MOV R2,#60初设答题时间为60s
MOV TMOD,#11H设置未定时器/模式1
MOV TH0,#0F0H
MOV TL0,#0FFH越高发声频率越高,越尖
MOV TH1,#3CH
MOV TL1,#0B0H50ms为一次溢出中断
SETB EA
SETB ET0
SETB ET1
SETB EX0
SETB EX1允许四个中断,T0/T1/INT0/册链INT1
CLR OK
CLR RING
SETB TR1
SETB TR0一开始就运行定时器,以开始显示隐咐FFF.如果想重新计数,重置TH1/TL1就可以了
=====查询程序=====
START: MOV R5,#0BH
MOV R4,#0BH
MOV R3,#0BH
ACALL DISPLAY未开始抢答时候显示FFF
JB P3.0,NEXTddddddd
ACALL DELAY
JB P3.0,NEXT去抖动,如果"开始键"按下就向下执行,否者跳到非法抢答查询
ACALL BARK按键发声
MOV A,R1
MOV R6,A送R1->R6,因为R1中保存了抢答时间
SETB OK抢答标志位,用于COUNT只程序中判断是否查询抢答
MOV R7,#01H 读抢答键数据信号标志,这里表示只读一次有用信号
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,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
=====INT0(抢答时间R1调整程序)=====
INT0SUB:MOV A,R1
MOV B,#0AH
DIV AB
MOV R5,A
MOV R4,B
MOV R3,#0AH
州携孙ACALL DISPLAY先在两个时间LED上显示R1
JNB P3.4,INC0P3.4为+1s键,如按下跳到INCO
JNB P3.5,DEC0P3.5为-1s键,如按下跳到DECO
JNB P3.1,BACK0P3.1为确定键,如按下跳到BACKO
AJMP INT0SUB
INC0: MOV A,R1
CJNE A,#63H,ADD0如果不是99,R2加1,如果加到99,R1就置0,重新加起。
MOV R1,#00H
ACALL DELAY1
AJMP INT0SUB
ADD0: INC R1
ACALL DELAY1
AJMP INT0SUB
DEC0: MOV A,R1
JZ SETR1如果R1为0, R1就置99,
DEC R1
ACALL DELAY1
AJMP INT0SUB
SETR1: MOV R1,#63H
ACALL DELAY1
AJMP INT0SUB
BACK0: RETI
=====INT1(回答时间R2调整程序)=====
INT1SUB:MOV A,R2
MOV B,#0AH
DIV AB
MOV R5,A
MOV R4,B
MOV R3,#0AH
ACALL DISPLAY
JNB P3.4,INC1
JNB P3.5,DEC1
JNB P3.1,BACK1
AJMP INT1SUB
INC1: MOV A,R2
CJNE A,#63H,ADD1
MOV R2,#00H
ACALL DELAY1
AJMP INT1SUB
ADD1: INC R2
ACALL DELAY1
AJMP INT1SUB
DEC1: MOV A,R2
JZ SETR2
DEC R2
ACALL DELAY1
AJMP INT1SUB
SETR2: MOV R2,#63H
ACALL DELAY1
AJMP INT1SUB
BACK1: RETI
=====倒计时程序(抢答倒计时和回答倒计时都跳到改程序)=====
REPEAT:MOV A,R2 使用锦囊时重新计时
MOV R6,A
CLR RING
COUNT: MOV R0,#00H重置定时器中断次数
MOV TH1,#3CH
MOV TL1,#0B0H重置定时器
RECOUNT:MOV A,R6R6保存了倒计时的时间,之前先将抢答时间或回答时间给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,FULL1s中0.5s向下运行
CLR RING
AJMP CHECK
FULL: CJNE A,#14H,CHECK下面是1s的情况,响并显示号数并清R0,重新计
SETB RING
MOV A,R6
JZ QUIT计时完毕
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 P3.1,QUIT如按下停止键退出
JNB OK,CHECKK 只在回答倒计时才有效
AJMP NEXTT
CHECKK:JNB P3.0,REPEAT判断是否使用锦囊
NEXTT: ACALL DISPLAY
JB OK,ACCOUT如果是抢答倒计时,如是则查询抢答,否者跳过查询继续倒数(这里起到锁抢答作用)
AJMP RECOUNT
ACCOUT:
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,TZ1
JNB ACC.7,TZ2
AJMP RECOUNT
TZ1:JMP TRUE7
TZ2:JMP 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 COUNT
TRUE2:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#02H
CLR OK
AJMP COUNT
TRUE3:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#03H
CLR OK
AJMP COUNT
TRUE4:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#04H
CLR OK
AJMP COUNT
TRUE5:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#05H
CLR OK
AJMP COUNT
TRUE6: ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#06H
CLR OK
AJMP COUNT
TRUE7:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#07H
CLR OK
AJMP COUNT
TRUE8:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#08H
CLR OK
AJMP COUNT
=====犯规抢答程序=====
ERROR: MOV R0,#00H
MOV TH1,#3CH
MOV TL1,#0B0H
MOV 34H,R3犯规号数暂存与(34H)
HERE: MOV A,R0
CJNE A,#06H,FLASH0.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 CHECK1
CHECK1: JNB P3.1,QUIT1
ACALL DISPLAY
AJMP HERE
QUIT1: 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 DELAY2
MOV DPTR,#DAT2
MOV A,R5
MOVC A,@A+DPTR
MOV P2,#0fdH
MOV P0,A
ACALL DELAY2
MOV A,R4
MOVC A,@A+DPTR
MOV P2,#0fbH
MOV P0,A
ACALL DELAY2
RET
DAT1: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,#08H
LOOP0: ACALL DISPLAY
DJNZ 35H,LOOP0
RET
=====延时4236个机器周期(去抖动用到)=====
DELAY: MOV 32H,#12H
LOOP: MOV 33H,#0AFH
LOOP1: DJNZ 33H,LOOP1
DJNZ 32H,LOOP
RET
=====延时4236个机器周期(显示用到)=====
DELAY2: MOV 32H,#43H
LOOP3: MOV 33H,#1EH
MOV A,R7 每隔60~70个机器周期读一次P1口,全为1时为无效数据,继续读,有一个不为1时,转到正常抢答处理
JNZ AAAA1 没读到有效数据时继续转到AAAA1
LOOP2: DJNZ 33H,LOOP2
DJNZ 32H,LOOP3
RET
=====读抢答按键数据口程序=====
由于在读抢答数据口的时候,单片机首先进入倒计时程序,再调用显示程序,最后才检测按键口
然而在检测按键口时动态扫描要调用三次(4ms)延时程序.这样就会导致读数据口出现滞后,造成1号优先最高.8号最低.
故采用在延时子程序中加了读数据口程序.保证了灵敏度和可靠性
AAAA1: 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按键发声
RET
=====TO溢出中断(响铃程序)=====
T0INT: MOV TH0,#0ECH
MOV TL0,#0FFH
JNB RING,OUT
CPL P3.6RING标志位为1时候P3.6口不短取反使喇叭发出一定频率的声音
OUT:RETI
=====T1溢出中断(计时程序)=====
T1INT: MOV TH1,#3CH
MOV TL1,#0B0H
INC R0
RETI
END
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)