单片机八人抢答器程序设计

单片机八人抢答器程序设计,第1张

------------------------------------------

KAI BIT P3.7 开始

------------------------------------------

ORG 0000H

JMP START

START:

----------------------下面是清零(复位)

MOV P0, #0C0H显示0

MOV P2, #255 熄灯

MOV R4, #0

----------------------下面等待按下洞友"开始"键

KAISHI:

JBKAI, KAISHI 没有按"开始",就循环

CALL DELAY延时

JBKAI, KAISHI 消抖

JNB KAI, $ 等待释放

----------------------

MOV P0, #0CH 显示P

WAIT: 等待抢答

MOV A, P1

CPL A

JZWAIT 继续等待

----------------------

XS:查找选谈做手按键的位置

CPL A

MOV P2, A

JNB ACC.0, J0

JNB ACC.1, J1

JNB ACC.2, J2

JNB ACC.3, J3

JNB ACC.4, J4

JNB ACC.5, J5

JNB ACC.6, J6

JMP J7

J7: INC R4

J6: INC R4

J5: INC R4

J4: INC R4

J3: INC R4

J2: INC R4

J1: INC R4

J0: INC R4

MOV A, R4

MOV DPTR, #D_TAB

MOVC A, @A + DPTR

MOV P0, A

----------------------下面等待按下复位键

W_FW:

JBKAI, W_FW没有按,则转

CALL DELAY延时

JBKAI, W_FW消抖

JNB KAI, $ 等待释放

JMP START

------------------------

D_TAB:

DB 0C0H,0F9H,0A4H,0B0H, 99H 共阳极0-9

DB92H, 82H,0F8H, 80H, 90H,0BFH -

------------------------------------------

DELAY: 延时约10ms

MOV R6, #20

DJNZ R7, $

DJNZ R6, $ - 2

RET

==========================================

END

以上纳侍槐程序已经调好。

先来桥拿如个汇编敏誉的程序,P1接一个共阳极数码管,P0低敏启4位接4个抢答按键,主持人复位采用单片机复位按钮实现。

ORG 0000H

START: MOV A,P0

ORL A,#0F0H

CJNE A,#0FFH,PL0

SJMP START

PL0: LCALL DELAY

MOV A,P0

ORL A,#0F0H

CJNE A,#0FFH,PL1

SJMP START

PL1:JNB ACC.0,K1

JNB ACC.1,K2

JNB ACC.2,K3

JNB ACC.3,K4

LJMP START

K1:MOV P1,#0F9H

SJMP $

K2:MOV P1,#0A4H

SJMP $

K3:MOV P1,#0B0H

SJMP $

K4:MOV P1,#99H

SJMP $

DELAY:MOV R6,#15

DEL2: MOV R7,#200

DJNZ R7,$

DJNZ R6,DEL2

RET

END

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,#0B0H50ms为一次溢出中断

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,NEXTddddddd

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

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

JNB P3.1,BACK0P3.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,R6R6保存了倒计时的时间,之前先将抢答时间或回答时间给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,FULL1s中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,FLASH0.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.6RING标志位为1时候P3.6口不短取反使喇叭发出一定频率的声音

OUT:RETI

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

T1INT: MOV TH1,#3CH

MOV TL1,#0B0H

INC R0

RETI

END


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12512679.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存