+ -
当前位置:首页 → 问答吧 → 求高手帮我看下这些代码应该怎么改啊?

求高手帮我看下这些代码应该怎么改啊?

时间:2011-12-16

来源:互联网

这是在网上找的代码,能编译成功,但开电运行后,数码管显示1,3,4位都显示F,蜂鸣器一直响,按了按键一点变化也没有,求高手修改或根据功能和仿真图提供一个可运行的代码。万分感谢!!!
抢答器功能:

仿真图:

Assembly code

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,#0B0H    ;50MS为一次溢出中断
    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,NEXT
    ACALL DELAY
    JB P3.0,NEXT    ;去抖动,如果"开始键"按下就向下执行,否则跳到非法抢答查询
    ACALL BARK     ;按键发声
    MOV A,R1
    MOV R6,A        ;送R1->R6,因为R1中保存了抢答时间
    SETB OK         ;抢答标志位,用于COUNT只程序中判断是否查询抢答
    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:
    JMP FALSE7
TZ2:
    JMP FALSE8
;=====非法抢答处理程序========
FALSE1:
    ACALL BARK   ;按键发声
    MOV R3,#01H
    AJMP ERROR
FALSE2:
    ACALL BARK
    MOV R3,#02H
    AJMP ERROR
FALSE3:
    ACALL BARK
    MOV R3,#03H
    AJMP ERROR
FALSE4:
    ACALL BARK
    MOV R3,#04H
    AJMP ERROR
FALSE5:
    ACALL BARK
    MOV R3,#05H
    AJMP ERROR
FALSE6:
    ACALL BARK
    MOV R3,#06H
    AJMP ERROR
FALSE7:
    ACALL BARK
    MOV R3,#07H
    AJMP ERROR
FALSE8:
    ACALL BARK
    MOV R3,#08
    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,INC0      ;3.4为+1S键,如按下跳到INC0
    JNB P3.5,DEC0      ;3.5为-1S键,如按下跳到DEC0
    JNB P3.1,BACK0     ;3.1为确定键,如按下跑到BACK0
    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
    JMP 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
;======倒计时程序(抢答倒计时和回答倒计时都跳到该程序)=========
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 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     ;如按下停止键退出
    ACALL DISPLAY
    JB OK,ACCOUT      ;如果是抢答倒计时,如是则查询抢答,否则路过查询继续倒数(这里直到锁抢答作用)
    AJMP RECOUNT
ACCOUT:
    JNB P1.0,TRUE1
    JNB P1.1,TRUE2
    JNB P1.2,TRUE3
    JNB P1.3,TRUE4
    JNB P1.4,TRUE5
    JNB P1.5,TRUE6
    JNB P1.6,TZ3
    JNB P1.7,TZ4
    AJMP RECOUNT
TZ3:
    JMP TRUE7
TZ4:
    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,#0AH,FLASH     ;0.5S向下运行->灭并停响
    CLR RING
    MOV R3,#0AH
    MOV R4,#0AH
    MOV R5,#0AH     ;三灯全灭
    AJMP CHECK1
FLASH:
    CJNE A,#14H,CHECK1     ;下面是1S的情况,响并显示号数并清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 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
    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
;======延时(显示和去抖动用到)======
DELAY:
    MOV 32H,#12H
LOOP:
    MOV 33H,#0AFH
LOOP1:
    DJNZ 33H,LOOP1
    DJNZ 32H,LOOP
RET
;========发声程序=======
BARK:
    SETB RING
    ACALL DELAY1
    CLR RING   ;按键发声
    RET
;=======T0溢出中断(响铃程序)=======
T0INT:
    MOV TH0,#0ECH
    MOV TL0,#0FFH
    JNB RING,OUT
    CPL P3.6      ;RING标志位为1时候P3.6口不断取反使喇叭发出一定频率的声音
OUT:
    RETI
;=========T1溢出中断(计时程序)======
T1INT:
    MOV TH1,#3CH
    MOV TL1,#0B0H
    INC R0
    RETI
END

作者: xiazer   发布时间: 2011-12-16

注释的很详细了,自己改一下吧。

作者: mydo   发布时间: 2011-12-16