找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3328|回复: 1
打印 上一主题 下一主题
收起左侧

基于单片机的八路抢答器

[复制链接]
跳转到指定楼层
楼主
OK EQU 20H         ;抢答开始标志位
RING EQU 22H       ;响铃标志位
DATA0 EQU36H      ;抢答按键口数据存放地址
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,#45        ;初设答题时间为45s         
       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           ;一开始就运行定时器,以开始显示PPP.如果想重新计数,重置TH1/TL1就可以了
;查询程序
START:  MOV DATA0,#0FFH       ;初始化
         
        MOV R5,#0BH         
        MOV R4,#0BH         
        MOV R3,#0BH
ACALLDISPLAY               ;未开始抢答时候显示PPP         
        JNB P3.3 ,INT0SUB
        
        JNB P3.4,TZ1          ;倒计时调整         
        JB P3.0,NEXT           ;ddddddd
        ACALL DELAY
        JB P3.0,NEXT           ;去抖动,如果"开始键"按下就向下执行,否者跳到非法抢答查询
        SETB EX0                  ;开放INT0           
        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: ACALLBARK             ;按键发声         
        MOV R3,#01H     
   AJMP ERROR
FALSE2: ACALLBARK         
        MOV R3,#02H     
   AJMP ERROR
FALSE3: ACALLBARK         
        MOV R3,#03H     
   AJMP ERROR
FALSE4: ACALLBARK         
        MOV R3,#04H     
   AJMP ERROR
FALSE5: ACALLBARK         
        MOV R3,#05H     
   AJMP ERROR
FALSE6: ACALLBARK        
        MOV R3,#06H     
   AJMP ERROR
FALSE7: ACALLBARK
        MOV R3,#07H     
   AJMP ERROR
FALSE8: ACALLBARK         
        MOV R3,#08H     
   AJMP ERROR
;INT0(抢答时间R1调整程序)
INT0SUB: MOVA,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,R21,如果加到99,R1就置0,重新加起。
        
         MOV R1,#00H         
         ACALL DELAY1
AJMP INT0SUB
ADD0:   INC R1
        
        ACALL DELAY1         
        AJMP INT0SUB
DEC0:   MOV A,R1
         
        JZ SETR1                     ;如果R10, 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: MOVA,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      ;1s0.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: JNBP3.1,QUIT              ;如按下停止键退出
      
       ACALL DISPLAY
      
       JB OK,ACCOUT                 ;如果是抢答倒计时,如是则查询抢答,否者跳过查询继续倒数(这里起到锁抢答作用)
   
    AJMP RECOUNT
ACCOUT:      MOV A,DATA0               
            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: ACALLBARK                  ;按键发声
     
      MOV A,R2
     
      MOV R6,A                        ;抢答时间R2R6
     
      MOV R3,#01H
     
      CLR OK                         ;因为答题的计时不再查询抢答,所以就锁了抢答   
    AJMP COUNT
TRUE2: ACALLBARK;     
      MOV A,R2     
      MOV R6,A     
      MOV R3,#02H     
      CLR OK  
    AJMP COUNT
TRUE3: ACALLBARK;
      MOV A,R2     
      MOV R6,A     
      MOV R3,#03H     
      CLR OK  
    AJMP COUNT
TRUE4: ACALLBARK;     
      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         
      MOVR3,#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                 ;显示PP和号数     
   AJMP CHECK1
CHECK1: JNBP3.1,QUIT1         
        ACALL DISPLAY     
    AJMP HERE
QUIT1:  CLR RING         
        CLR OK
AJMP START
;显示程序
DISPLAY:MOVDPTR,#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:DB00h,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,00H,73H   
                               ;"","1","2","3","4","5","6","7","8","9","","P"
DAT2:DB3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,00H,73H
                             ;第一个为零,其他与上相同,因为十位如果为零显示熄灭  
;加减时间延时(起到不会按下就加N个数)
DELAY1: MOV35H,#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  
;INTT0中断服务程序
INTT0:MOVDATA0,P1
CLR EX0
RETI   
END     

仿真1.png (146.02 KB, 下载次数: 41)

仿真1.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:206853 发表于 2019-4-11 17:38 | 只看该作者
下载看看
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表