求以单片机AT89C51设计的八路抢答器的汇编语言,能有8个LED灯显示就行了!!谢谢

如题所述

ORG 0000H

        AJMP MAIN

        ORG 0003H

        AJMP INT0SUB

        ORG 000BH

        AJMP T0INT

        ORG 001BH

        AJMP T1INT

OK      EQU 20H     ;   抢答开始标志位

RING    EQU 22H   ;   响铃标志位

        ORG 0040H

MAIN:  MOV R1,#0FH; 初设抢答时间为15s

        MOV R2,#0AH; 初设答题时间为10s

        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,FALSE7

         JNB P1.7,FALSE8

         AJMP START

//非法抢答处理程序:

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,#08H

        AJMP ERROR

//倒计时程序(包括有效抢答程序):

 COUNT:  MOV R0,#00H;     重置定时器中断次数

         MOV TH1,#3CH

         MOV TL1,#0B0H; 重置定时器

RECOUNT: MOV A,R6;        R6保存了倒计时的时间

          MOV B,#0AH

          DIV AB;          除十分出个位/十位

          MOV 30H,A;   十位存于(30H)

          MOV 31H,B;   个位存于(31H)

          MOV R5,30H  ;  取十位

          MOV R4,31H  ;  取个位

          MOV A,R6

          CLR  C

          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

          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,TRUE7

          JNB P1.7,TRUE8

          AJMP RECOUNT

QUIT:     CLR OK        ;  如果按下了"停止键"重新回到开始

          CLR RING

          ACALL BARK

          AJMP START

//正常抢答处理程序:

TRUE1: ACALL BARK; 按键发声

       MOV A,R2

       MOV R6,A;  抢答时间R2送R6

       MOV R3,#01H

       CLR OK;  

       AJMP LOOP2

TRUE2:ACALL BARK;

       MOV A,R2

       MOV R6,A

       MOV R3,#02H

       CLR OK

       AJMP LOOP2

TRUE3:ACALL BARK;

       MOV A,R2

       MOV R6,A

       MOV R3,#03H

       CLR OK

       AJMP LOOP2

TRUE4:ACALL BARK;

       MOV A,R2

       MOV R6,A

       MOV R3,#04H

       CLR OK

       AJMP LOOP2

TRUE5:  ACALL BARK;

        MOV A,R2

        MOV R6,A

        MOV R3,#05H

        CLR OK

        AJMP LOOP2

TRUE6:  ACALL BARK;

        MOV A,R2

        MOV R6,A

        MOV R3,#06H

        CLR OK

        AJMP LOOP2

TRUE7:  ACALL BARK;

        MOV A,R2

        MOV R6,A

        MOV R3,#07H

        CLR OK

        AJMP LOOP2

TRUE8:  ACALL BARK;

        MOV A,R2

        MOV R6,A

        MOV R3,#08H

        CLR OK

AJMP LOOP2

LOOP2:  AJMP DISPLAY       ;抢答后停止计时,等待返回

SETB RING

        JNB  P3.1 , QUIT

        AJMP  LOOP2

//犯规抢答程序:

ERROR:  SETB RING        ;犯规响铃

        MOV R5,#0BH

        MOV R4,#0BH;  显示FF和犯规号数

LOOP3:  ACALL DISPLAY   

        JNB   P3.1 , QUIT1;   等待"停止"键按下

        AJMP  LOOP3 

QUIT1:  CLR RING

        CLR OK

        AJMP START

//显示程序:

DISPLAY:MOV DPTR,#DAT1;  查表显示程序,利用P0口做段选码口输出/P2低三位做位选码输出

       MOV A,R5

       MOVC A,@A+DPTR

       MOV P2,#01H

       MOV P0,A

       ACALL DELAY

       MOV DPTR,#DAT2

       MOV A,R4

       MOVC A,@A+DPTR

       MOV P2,#02H

  MOV P0,A

  ACALL DELAY

  MOV A,R3

  MOVC A,@A+DPTR

      MOV P2,#04H

  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

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

        ACALL DELAY1

 ACALL DELAY1

  ACALL DELAY1

        CLR RING;   按键发声

        RET

//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.2,INC0; P3.2为+1s键,如按下跳到INCO

        JNB P3.3,DEC0; P3.3为-1s键,如按下跳到DECO

        JNB P3.4,BACK0; P3.4为确定键,如按下跳到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

//TO溢出中断(响铃程序):

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

温馨提示:答案为网友推荐,仅供参考
相似回答