毕业设计做的项目,用proteus和keil软件做的抢答器,下面是仿真原理图:
单片机汇编语言源程序如下:
- SO BIT 2FH.0 ;发声标志
- RESET EQU P2.0 ;抢答复位与设定时间
- STA EQU P2.1 ;抢答开始
- TTIME EQU 10H ;暂存时间16进制
- TIME EQU 15H ;时间10进制
- PL EQU 12H ;抢答到的人
- TEAM EQU 39H ;抢答到的人所在组
- ;LCD n的程序为显示子程序
- ;F0为时间是否已到与
- KEY0 EQU P3.3
- KEY1 EQU P3.4
- FLAGT EQU 2FH.1 ;是否进HOLDON循环标志
- ANS EQU P2.2 ;回答按键
- FLAG0 EQU 2FH.2 ;选手编号跳出循环标志
- WRO EQU P2.6 ;抢答正确与否
- RIG EQU P2.7
- ORG 0000H
- LJMP MAIN
- ORG 000BH
- LJMP T00
- ORG 001BH
- LJMP T11
- ;******************************************************************************************************
- ;初始设置
- MAIN:
- MOV SP,#50H
- MOV 18H,#0FFH
- MOV TMOD,#11H
- MOV TH0,#3CH
- MOV TL0,#0B0H
- MOV TH1,#0FCH
- MOV TL1,#18H
- SETB EA
- SETB ET0
- SETB ET1
- SETB TR1
- CLR F0
- CLR SO
- CLR KEY0 ;矩阵式键盘初始化
- SETB KEY1
- ;******************************************************************************************************
- ;复位位置
- INI:
- CLR SO ;停止发声
- CLR FLAGT
- CLR FLAG0
- CLR TR0
- MOV TTIME,#30 ;设置30S计时时间
- MOV PL,#00
- MOV A,TTIME ;计时时间10进制
- MOV B,#10
- DIV AB
- SWAP A
- ADD A,B
- MOV TIME,A ;TIME计时时间10进制
- MOV 11H,#20 ;设置11H计时中间点1秒
- LCALL Init_M7219 ;数码管等器件初始显示
- LCALL LCD2 ;显示ready
- LCALL DELAYX
- ;******************************************************************************************************
- ;判断开关是否按下
- ST0:
- LCALL DISPLAY
- JB RESET,ST1 ;判断是否需要调整时间
- JNB SO,NEXT1
- JNB RESET,INI ;作弊复位
- NEXT1:
- LCALL DELAYX
- INC TTIME ;这里设置为加1调整,
- MOV A,TTIME
- MOV B,#10
- DIV AB
- SWAP A
- ADD A,B
- MOV TIME,A ;显示时间进制转换
- MOV A,TTIME
- CLR C
- CJNE A,#31,ST1 ;最高允许30s,也是默认值
- MOV TTIME,#01H
- MOV TIME,#01H ;超出30s重置为1s开始
- ;******************************************************************************************************
- ;判断是否有人作弊
- ST1:
- LCALL MAT
- MOV A,P1
- CPL A
- MOV B,A
- JZ NEXT
- MOV CHEATER,#00H;
- DEAL0: ;将P0口读到的数据转换至对应作弊选手编号(移位)
- CLR C ;移位前准备
- RRC A
- CLR C
- INC CHEATER ;移位计数,获得作弊选手号
- JNZ DEAL0
- MOV A,CHEATER
- MOV A,#00H
- ADD A,TEAM
- ADD A,CHEATER ;得到编号
- MOV B,#10
- DIV AB
- MOV TEAM,A
- MOV CHEATER,B
- SETB SO ;发声报警
- LCALL LCD1
- NEXT:
- JB STA,ST0 ;没有开关按下,返回判断是否修正时间,否则执行抢答
- LCALL LCD3
- SETB F0 ;循环标志,后续用于跳出循环,时间到可使之置0
- SETB TR0 ;启动定时
- LCALL DELAYSO ;短暂发声
- ;******************************************************************************************************
- ;关键循环,用于判断是否有按下
- START:
- JNB F0,HOLDON ;时间是否已到
- LCALL MAT ;矩阵式键盘子程序
- MOV A,P1
- XRL A,#0FFH
- JNZ HOLDON
- LJMP START
- ;******************************************************************************************************
- ;时间到或者有人抢答,转入此循环等待
- HOLDON:
- MOV 17H,A ;A数据暂存
- CLR TR0 ;有人抢答停止计时
- H1:
- JB F0,H2
- LCALL LCD4 ;LCD显示结束
- H2:
- JNB F0,HOLD
- LCALL LCD5 ;LCD显示抢答成功
- HOLD:
- MOV A,17H ;数据恢复
- JZ CONTINUE ;用于下面移位转换循环的执行条件
- MOV PL,#00H;
- SETB FLAGT ;有人抢答才置1
- DEAL: ;转换
- CLR C
- RRC A
- CLR C ;移位转换
- INC PL
- JNZ DEAL
- CONTINUE:
- JB FLAG0,KO
- ADD A,TEAM
- ADD A,PL ;得到编号
- MOV B,#10
- DIV AB
- MOV TEAM,A
- MOV PL,B
- SETB FLAG0
- MOV 17H,#00H
- SJMP KO
- ST00:
- LJMP INI
- KO:
- JNB FLAGT,$+6
- JNB ANS,ANSWER ;回答倒计时
- JNB RESET,ST00 ;按下复位键后回到起始状态,但由于此处转移字节已超过128B,所以迂回使用了LJMP
- SETB SO
- LCALL DISPLAY
- AJMP HOLD ;否则维持状态
- ;******************************************************************************************************
- ;回答倒计时
- ANSWER:
- CLR SO ;停止报警
- MOV TTIME,#31 ;默认回答倒计时30S
- SETB TR0
- LCALL LCD6 ;LCD显示
- L1:
- JNB TR0,L3 ;封锁
- JB WRO,L2 ;回答正确与否
- LCALL LCD7
- CLR TR0
- L2:
- JB RIG,L1
- LCALL LCD8
- CLR TR0
- L3:
- JB RESET,$
- LJMP INI
- ;******************************************************************************************************
- ;矩阵式键盘子程序
- MAT:
- CPL KEY0
- CPL KEY1
- JB KEY0,ELSE0
- MOV TEAM,#00H
- RET
- ELSE0:
- MOV TEAM,#08H
- RET
- ;******************************************************************************************************
- ;MAX7219显示程序
- M7219_CLK BIT P3.2
- M7219_DIN BIT P3.0
- M7219_LOAD BIT P3.1
- LED_BUF EQU 50H
- SET_MODEL EQU 0FFH
- SET_BRIGHT EQU 04H
- SET_LIMIT EQU 03H
- SET_NORMAL EQU 01H
- SET_START EQU 01H
- DISPLAY:
- MOV A,#00H
- JNB FLAGT,GVA0;是否抢答
- MOV A,PL
- GVA0:
- MOV B,A;TTIME送端口
- MOV A,#01H
- LCALL w_7219;放入MAX7290子程序
- JB FLAGT,GVA
- MOV A,#00H
- SJMP GVA2
- GVA:
- MOV A,TEAM
- GVA2:
- MOV B,A
- MOV A,#02H
- LCALL w_7219
- MOV A,TIME
- ANL A,#0FH
- MOV B,A
- MOV A,#03H
- LCALL w_7219
- MOV A,TIME
- SWAP A
- ANL A,#0FH
- MOV B,A
- MOV A,#04H
- LCALL w_7219
- LCALL DELAY
- RET
- INIT_M7219: ;初始化MAX7219
- MOV A,#0BH
- MOV B,#SET_LIMIT
- LCALL W_7219
- MOV A,#09H
- MOV B,#SET_MODEL
- LCALL W_7219
- MOV A,#0AH ;设置亮度
- MOV B,#SET_BRIGHT ;15/32亮度
- LCALL W_7219
- MOV A,#0FH
- MOV B,#SET_NORMAL
- LCALL W_7219
- MOV A,#0CH
- MOV B,#SET_START
- LCALL W_7219
- RET
- DISP:
- MOV R0,#LED_BUF
- MOV R4,#01H
- MOV R3,#SET_LIMIT
- DISP1:
- MOV A,@R0
- MOV B,A
- MOV A,R4
- LCALL W_7219
- INC R0
- INC R4
- DJNZ R3,DISP1
- RET
- W_7219:
- CLR M7219_CLK
- CLR M7219_DIN
- CLR M7219_LOAD ;置LOAD=0
- LCALL SD_7219 ;传送7219的地址
- MOV A,B
- LCALL SD_7219 ;传送数据
- SETB M7219_LOAD ;数据装载
- CLR M7219_DIN
- RET
- SD_7219: ;向7219送地址与数据
- MOV R2,#08H
- C_SD: CLR C
- CLR M7219_CLK
- RLC A
- MOV M7219_DIN,C ;准备数据
- NOP
- SETB M7219_CLK ;上升沿将数据传入
- NOP
- NOP
- CLR M7219_CLK
- DJNZ R2,C_SD
- RET
- ;******************************************************************************************************
- ;LCD显示程序
- RS EQU P2.3
- RW EQU P2.4
- E EQU P2.5
- LCD EQU P0
- BF EQU P0.7
- CHEATER EQU 36H
- ;LCD显示区 (LCD显示内容)
- LCD1:
- LCALL LCDINI
- MOV A,#84H
- LCALL W_CMD
- MOV DPTR,#TAB
- MOV R7,#0 ;CHEAT
- LP1:
- MOV A,R7
- MOVC A,@A+DPTR
- LCALL W_DATA
- INC R7
- CJNE R7,#06,LP1
- MOV A,#32;空格
- LCALL W_DATA
- MOV A,#30H
- ADD A,TEAM
- LCALL W_DATA
- MOV A,#30H
- ADD A,CHEATER
- LCALL W_DATA
- MOV A,#0C6H
- ACALL W_CMD
- LP2:
- MOV A,R7
- MOVC A,@A+DPTR
- LCALL W_DATA
- INC R7
- CJNE R7,#11,LP2
- RET
- LCD2:
- LCALL LCDINI
- MOV A,#85H
- LCALL W_CMD
- MOV DPTR,#READY
- MOV R7,#0 ;READY
- LP11:
- MOV A,R7
- MOVC A,@A+DPTR
- LCALL W_DATA
- INC R7
- CJNE R7,#5,LP11
- RET
- LCD3:
- LCALL LCDINI
- MOV A,#84H
- LCALL W_CMD
- MOV DPTR,#REACING
- MOV R7,#0 ;REACING
- LP111:
- MOV A,R7
- MOVC A,@A+DPTR
- LCALL W_DATA
- INC R7
- CJNE R7,#7,LP111
- RET
- LCD4:
- LCALL LCDINI
- MOV A,#86H
- LCALL W_CMD
- MOV DPTR,#OVER
- MOV R7,#0 ;OVER
- LP1111:
- MOV A,R7
- MOVC A,@A+DPTR
- LCALL W_DATA
- INC R7
- CJNE R7,#4,LP1111
- RET
- LCD5:
- LCALL LCDINI
- MOV A,#86H
- LCALL W_CMD
- MOV DPTR,#DONE
- MOV R7,#0 ;DONE
- LP11111:
- MOV A,R7
- MOVC A,@A+DPTR
- LCALL W_DATA
- INC R7
- CJNE R7,#4,LP11111
- RET
- LCD6:
- LCALL LCDINI
- MOV A,#83H
- LCALL W_CMD
- MOV DPTR,#ANSWERING
- MOV R7,#0 ;ANSWERING
- LP111111:
- MOV A,R7
- MOVC A,@A+DPTR
- LCALL W_DATA
- INC R7
- CJNE R7,#9,LP111111
- RET
- LCD7:
- LCALL LCDINI
- MOV A,#85H
- LCALL W_CMD
- MOV DPTR,#RIGHT
- MOV R7,#0 ;RIGHT
- LP1111111:
- MOV A,R7
- MOVC A,@A+DPTR
- LCALL W_DATA
- INC R7
- CJNE R7,#5,LP1111111
- RET
- LCD8:
- LCALL LCDINI
- MOV A,#85H
- LCALL W_CMD
- MOV DPTR,#WRONG
- MOV R7,#0 ;WRONG
- LP111111111:
- MOV A,R7
- MOVC A,@A+DPTR
- LCALL W_DATA
- INC R7
- CJNE R7,#5,LP111111111
- RET
- ;LCD初始化
- LCDINI:
- MOV A,#38H
- LCALL W_CMD
- MOV A,#0CH
- LCALL W_CMD
- MOV A,#06H
- LCALL W_CMD
- MOV A,#01H
- LCALL W_CMD
- RET
- W_CMD:
- ACALL WAIT
- CLR RS
- CLR RW
- MOV LCD,A
- SETB E
- CLR E
- RET
- W_DATA:
- ACALL WAIT
- SETB RS
- CLR RW
- MOV LCD,A
- SETB E
- CLR E
- RET
- WAIT:
- MOV R6,#20
- W1:
- MOV R5,#250
- DJNZ R5,$
- DJNZ R6,W1
- RET
- ;******************************************************************************************************
- ;延迟1
- DELAY: ;延迟用于MAX7219,7219在循环中写入不能过快
- MOV R7,#02H
- DELAY0:
- MOV R6,#0AH
- DELAY1:
- MOV R5,#0AH
- DELAY2:
- DJNZ R5,DELAY2
- DJNZ R6,DELAY1
- DJNZ R7,DELAY0
- RET
- ;延迟2
- DELAYX: ;RESET键软件防抖动,以及长按设置时间时的时间轮转速度
- LCALL DELAY
- LCALL DELAY
- LCALL DELAY
- LCALL DELAY
- DJNZ 18H,DELAYX
- RET
- ;延迟3
- DELAYSO: ;开始开关按下短时发声延时
- SETB SO
- ACALL DELAYX
- CLR SO
- RET
- ;******************************************************************************************************
- ;中断
- ;定时器T0中断
- T00: ;定时器t0中断
- MOV TH0,#3CH
- MOV TL0,#0B0H ;50ms定时
- DJNZ 11H,RETI1
- MOV 11H,#20 ;1s定时
- MOV A,TTIME
- DEC A
- MOV B,#10
- DIV AB
- SWAP A
- ADD A,B
- MOV TIME,A ;定时进制转换16转10
- LCALL DISPLAY
- DJNZ TTIME,RETI1
- CLR TR0 ;自停止
- CLR F0 ;时间到无人抢答清零F0跳出检测循环
- SETB SO ;发声
- RETI1:
- RETI
- ;定时器1中断,频率1KHZ,用于喇叭发声
- T11:
- MOV TH1,#0FCH
- MOV TL1,#18H
- JNB SO, RETT11 ;判断发声标志位SO
- CPL P3.7
- RETT11:
- RETI
- ;******************************************************************************************************
- ;LCD显示表
- TAB:
- DB 'PLAYER'
- DB 'CHEAT'
- READY:
- DB 'READY'
- REACING:
- DB 'REACING'
- OVER:
- DB 'OVER'
- DONE:
- DB 'DONE'
- ANSWERING:
- DB 'ANSWERING'
- RIGHT:
- DB 'RIGHT'
- WRONG:
- DB 'WRONG'
- END
复制代码
所有资料51hei提供下载:
程序及仿真.rar
(36.86 KB, 下载次数: 25)
|