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

📄 six-answer.asm

📁 AT89c52单片机六路抢答器汇编语言文件
💻 ASM
字号:
;六路抢答器
;需外扩八个小开关                                                                              
;1.如果想调节抢答时间或答题时间,按"抢答时间调节"键或"答题时间调节"键进入调节状态,此时会显示现在设定的抢答时间      
;或回答时间值,如想加一秒按一下"加1s"键,如果想减一秒按一下"-1s"键,时间LED上会显示改变后的时间,调整范围为0s~99s,    
;0s时再减1s会跳到99,99s时再加1s会变到0s。                                                                         
;2.主持人按"抢答开始"键,会有提示音,并立刻进入抢答倒计时(预设15s抢答时间),如有选手抢答,会有提示音,并会显示    
;其号数并立刻进入回答倒计时(预设10s抢答时间),不进行抢答查询,所以只有第一个按抢答的选手有效。倒数时间到小于5s   
;会每秒响一下提示音。                                                                                              
;3.如倒计时期间,主持人想停止倒计时可以随时按"停止"按键,系统会自动进入准备状态,等待主持人按"抢答开始"进入下次    
;抢答计时。                                                                                                        
;4.如果主持人未按"抢答开始"键,而有人按了抢答按键,犯规抢答,LED上不断闪烁FF和犯规号数并响个不停,直到按下"停止"   
;键为止。                                                                                                           
;*******************************************************************************************************************
;P1.0为开始抢答,P1.7为停止,p1.1-p1.6为六路抢答输入 数码管段选P0口,位选P2口,蜂鸣器输出为P3.6口。
;*******************************************************************************************************************
	OK EQU 20H;抢答开始标志位;将P1口与P2口互换,P3.0-P1.0,P3.1-P1.7
	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,#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 P1.0,NEXT;ddddddd
         ACALL DELAY
         JB P1.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.1,FALSE1
	   JNB P1.2,FALSE2
	   JNB P1.3,FALSE3
	   JNB P1.4,FALSE4
	   JNB P1.5,FALSE5
	   JNB P1.6,FALSE6
	   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

;=====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 P1.7,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 P1.7,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 
;=====倒计时程序(抢答倒计时和回答倒计时都跳到改程序)=====
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 P1.7,QUIT;如按下停止键退出
       ACALL DISPLAY
	  JB OK,ACCOUT;如果是抢答倒计时,如是则查询抢答,否者跳过查询继续倒数(这里起到锁抢答作用)
	  AJMP RECOUNT
ACCOUT:JNB P1.1,TRUE1
	  JNB P1.2,TRUE2
	  JNB P1.3,TRUE3
	  JNB P1.4,TRUE4
	  JNB P1.5,TRUE5
	  JNB P1.6,TRUE5
	  AJMP RECOUNT
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
;=====犯规抢答程序=====
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 P1.7,QUIT1
        ACALL DISPLAY
	   AJMP HERE
QUIT1:  CLR RING
        CLR OK
	   AJMP START
;=====显示程序=====
DISPLAY:MOV DPTR,#DAT1;查表显示程序,利用P0口做段选码口输出/P2低三位做位选码输出,
    MOV A,R5
	 MOVC A,@A+DPTR
	 MOV P2,#04H
	 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,#01H
	 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,#15H
LOOP:   MOV 33H,#0AFH
LOOP1:  DJNZ 33H,LOOP1
        DJNZ 32H,LOOP
	   RET
;=====发声程序=====
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 + -