315764685 315764685
关注数: 196 粉丝数: 208 发帖数: 3,534 关注贴吧数: 104
求助基于单片机的八路抢答器 汇编程序讲解!!! 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; =====查询程序===== 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 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 =====倒计时程序(抢答倒计时和回答倒计时都跳到改程序)===== 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 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;如按下停止键退出 AJMP NEXTT 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 CLR RING AJMP CHECK1 FLASH: CJNE A,#0CH,CHECK1 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; 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 ; JNZ AAAA1 ;没读到有效数据时继续转到AAAA1 LOOP2: DJNZ 33H,LOOP2 DJNZ 32H,LOOP3 RET =====读抢答按键数据口程序===== 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
1 下一页