⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 改进型.txt

📁 我设计的是八路抢答器
💻 TXT
字号:

;说明:改进后解决了1号抢答优先的问题,并增加了锦囊的设置,当
;参赛选手在回答问题时要求使用锦囊,则主持人按下抢答开始键,
;计时重新开始。
;============================================================
;================    八路抢答器程序   =======================
;================        刘新发       =======================
;================    2007  年  5 月   =======================
;============================================================
        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;ddddddd

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

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

         JNB P3.1,BACK0;P3.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,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;如按下停止键退出

       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,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 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.6;RING标志位为1时候P3.6口不短取反使喇叭发出一定频率的声音

OUT:    RETI

;=====T1溢出中断(计时程序)=====

T1INT:  MOV TH1,#3CH

        MOV TL1,#0B0H

    INC R0

    RETI

END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -