;实验目的:了解8255与交通灯模块
;实验连线:dg1-dg4接pc0-pc3,dr1-dr4接pc4-pc7,cs接8400
z8279 equ 0ff82h
d8279 equ 0ff80h
ledmod equ 00h
ledfeq equ 20h
ledcls equ 0c1h
c8255 equ 8406h
p8255a equ 8400h
p8255b equ 8402h
p8255c equ 8404h
org 0000h
ajmp start
org 0040h
start:
mov sp, #60h
lcall init8279
mov dptr,#c8255
mov a,#90h
movx @dptr,a
mov dptr,#p8255c
mov a,#00000000b ;交通灯全黄
movx @dptr,a
WAIT:
LCALL peek ;读键盘
CJNE A,#0FFH,peeka ;判断是否有键输入
sjmp wait
peeka: CJNE A,#0aH,peekb ;输入键是'a',进正常状态
sjmp auto_traffic
peekb: cjne a,#0bh,wait ;输入键是'b',进紧急状态
sjmp manual_traffic
auto_traffic:
mov r1,#60
loop1: LCALL start_traffic1
lcall disptime
dec r1
lcall delay
lcall delay
lcall delay
lcall delay
lcall delay
lcall peek
cjne a,#0bh,go_on1 ;输入"b"键,转manual_traffic紧急情况状态,交通灯全红
sjmp manual_traffic
go_on1: cjne r1,#0,loop1
mov r1,#60
loop2: lcall start_traffic2
lcall disptime
dec r1
lcall delay
lcall delay
lcall delay
lcall delay
lcall delay
lcall peek
cjne a,#0bh,go_on2 ;输入"b"键,转manual_traffic紧急情况状态,交通灯全红
sjmp manual_traffic
go_on2: cjne r1,#0,loop2
sjmp auto_traffic
manual_traffic:
mov dptr,#p8255c
mov a,#00001111b
movx @dptr,a
traffic:
lcall peek
traffic_c:
cjne a,#0ch,traffic_d
lcall start_traffic1
sjmp traffic
traffic_d:
cjne a,#0dh,traffic_e
lcall start_traffic2
sjmp traffic
traffic_e:
cjne a,#0eh, traffic
sjmp auto_traffic
nop
;************************************************
;
; 数据区
;
;************************************************
;LED显示常数表
LED: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H ;'0,1,2,3,4,5,6,7'
DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H ;'8,9,A,B,C,D,E,F'
DB 0BFH,86H,0DBH,0CFH,0E6H,0EDH,0FDH,087H ;'0.,1.,2.,3.,4.,5.,6.,7.'
DB 0FFH,0EFH,0F7H,0FCH,0B9H,0DEH,0F9H,0F1H ;'8.,9.,A.,B.,C.,D.,E.,F.'
DB 6DH,02H,08H,00H,59H,0FH,76H ;'U,-,_, ,I,O,P, '
;键盘键码表
KEYCODE:DB 30H,31H,32H,33H,34H,35H,36H,37H ;'1,2,Q,W,A,S,+,Z'
DB 38H,39H,3AH,3BH,3CH,3DH,3EH,3FH ;'3,4,E,R,D,F,X,C'
;********************************************************************
;所有子程序均在下面
start_traffic1:
PUSH DPH ;保存现场
PUSH DPL
PUSH acc
mov dptr,#p8255c
mov a,#01101001b ;东西绿,南北红
movx @dptr,a
POP acc ;恢复现场
POP DPL
POP DPH
ret
start_traffic2:
PUSH DPH ;保存现场
PUSH DPL
PUSH acc
mov dptr,#p8255c
mov a,#10010110b ;东西红,南北绿
movx @dptr,a
POP acc ;恢复现场
POP DPL
POP DPH
ret
;读取键盘子程序
PEEK: PUSH DPH ;保存现场
PUSH DPL
PUSH b
MOV DPTR,#Z8279
MOVX A,@DPTR ;读8279状态
ANL A,#0FH
JNZ PEEK1 ;判断是否有键输入
MOV A,#0FFH ;置标志(无键输入)
SJMP PEEKEND
PEEK1: MOV A,#40H ;读 FIFO RAM 命令
MOVX @DPTR,A
MOV DPTR,#D8279
MOVX A,@DPTR ;读键
MOV B,A
MOV A,#0C2H
KK: MOV DPTR,#Z8279
MOVX A,@DPTR
ANL A,#80H
JNZ KK
MOV A,B
PEEKEND:
POP b ;恢复现场
POP DPL
POP DPH
RET
INIT8279: ;8279初始化子程序
PUSH DPH ;保存现场
PUSH DPL
PUSH ACC
MOV DPTR ,#Z8279
MOV A,#LEDMOD ;置8279工作方式
MOVX @DPTR,A
MOV A,#LEDFEQ ;置键盘扫描速率
MOVX @DPTR,A
MOV A,#LEDCLS ;清除 LED 显示
MOVX @DPTR,A
POP ACC ;恢复现场
POP DPL
POP DPH
RET
;显示时间的子程序
;输入:A,输出:B,R1为进来的时间数
disptime:
push dph
push dpl
push acc
mov dptr,#z8279
mov a,#90h
movx @dptr,a
MOV A,R1
mov b,#10 ;显示秒低位
div ab
lcall disp
mov b,#10 ;显示秒高位
div ab
lcall disp
pop acc
pop dpl
pop dph
RET
; DISP子程序
;输入: ACC 要显示的字符ASCII码,B为进入显示的字符ASCII码
DISP: PUSH DPH ;保存现场
PUSH DPL
PUSH ACC
mov a,b
MOV DPTR,#LED ;置显示常数表起始位置
MOVC A,@A+DPTR ;查表
MOV DPTR,#D8279
MOVX @DPTR,A ;显示数据
POP ACC
POP DPL
POP DPH
RET
DELAY: ;延时子程序
PUSH 0 ;保存现场
PUSH 1
MOV 0,#0H
DELAY1: MOV 1,#0H
DJNZ 1,$
DJNZ 0,DELAY1 ;延时0.2秒左右
POP 1 ;恢复现场
POP 0
RET
end
POP DPH
RET
INIT8279: ;8279初始化子程序
PUSH DPH ;保存现场
PUSH DPL
PUSH ACC
MOV DPTR ,#Z8279
MOV A,#LEDMOD ;置8279工作方式
MOVX @DPTR,A
MOV A,#LEDFEQ ;置键盘扫描速率
MOVX @DPTR,A
MOV A,#LEDCLS ;清除 LED 显示
MOVX @DPTR,A
POP ACC ;恢复现场
POP DPL
POP DPH
RET
disptime:
push dph
push dpl
push acc
mov dptr,#z8279
mov a,#90h
movx @dptr,a
mov a,r1
mov b,#10
div ab
lcall disp
mov b,#10
div ab
lcall disp
pop acc
pop dpl
pop dph
RET
; DISP子程序
;输入: ACC 要显示的字符ASCII码
DISP: PUSH DPH ;保存现场
PUSH DPL
PUSH ACC
mov a,b
MOV DPTR,#LED ;置显示常数表起始位置
MOVC A,@A+DPTR ;查表
MOV DPTR,#D8279
MOVX @DPTR,A ;显示数据
POP ACC
POP DPL
POP DPH
RET
DELAY: ;延时子程序
PUSH 0 ;保存现场
PUSH 1
MOV 0,#0H
DELAY1: MOV 1,#0b3H
DJNZ 1,$
DJNZ 0,DELAY1 ;延时100.02ms秒
POP 1 ;恢复现场
POP 0
RET
end
评论0