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

📄 a.asm

📁 多功能智能抢答器系统
💻 ASM
字号:
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 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,#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 
;=====倒计时程序(抢答倒计时和回答倒计时都跳到改程序)=====
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
        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 + -