📄 cross.asm
字号:
; 端口设置
IO8155CS EQU 8000H ;8155控制口地址
IO8155A EQU 8001H ;8155A口地址
IO8155B EQU 8002H ;8155B口地址
ADC0809 EQU 8020H ;0809端口地址
ORG 0000H ;主程序入口地址
LJMP MAIN ;转到主程序
ORG 0003H ;外部中断0入口地址
LJMP INT0P ;转到外部中断0中断服务子程序
ORG 0100H ;主程序起始地址
MAIN:
;主程序
;初始化
MOV SP,#60H ;为子程序调用初始化堆栈
MOV DPTR,#IO8155CS ;DPTR指向8155控制口
MOV A,#00000011B
;计数器空操作,禁止中断,A口B口基本输出,C口输入
MOVX @DPTR,A ;向8155输出方式命令
;应用程序代码
SETB EA ;开中断
SETB EX0 ;开外部中断0
MOV 32H,#10H ;初始化水平方向闯灯显示
MOV 33H,#10H ;初始化垂直方向闯灯显示
MOV P1,#00000000B ;灯全灭,扬声器关
LOOP:
;对交通灯进行循环显示,每一轮60秒
;水平方向绿灯亮的程序段,时间为25秒
CLR P1.5 ;水平方向红灯灭
SETB P1.7 ;水平方向绿灯亮
CLR P1.3 ;垂直方向黄灯灭
SETB P1.2 ;垂直放向红灯亮
MOV 30H,#02H ;水平方向绿灯时间设置为24秒
MOV 31H,#04H
MOV 34H,#02H ;垂直方向红灯时间设置为29秒
MOV 35H,#09H
HGREEN:
MOV R2,#160 ;延时约160*6ms=960ms
HGDL1s:
MOV DPTR,#ADC0809 ;DPTR指向ADC0809
MOV A,#00H ;选择0通道
MOVX @DPTR,A ;启动AD转换
LCALL DISP ;6ms软件延时>转换时间100us
CLR RS0 ;设置第0组寄存器
CLR RS1
MOV DPTR,#ADC0809 ;DISP中修改了DPTR,这里使DPTR重新指向ADC0809
MOVX A,@DPTR ;读取转换结果
CLR C ;清空借位位
SUBB A,#90H ;判断垂直方向是否有人闯红灯
JC HGNWARN ;未发现闯红灯则转移
MOV 33H,#11H ;否则进行闯灯显示
SETB P1.0 ;声音报警
HGNWARN:
DJNZ R2,HGDL1s ;1s时间未到则转移
MOV R1,#35H ;R1指向垂直方向时间显示数据区低位
DEC @R1 ;垂直方向红灯时间低位减1
CJNE @R1,#0FFH,HGNCARRY ;无借位则转移
MOV @R1,#09H ;有借位低位置为9
DEC R1 ;R1指向垂直方向时间显示数据区高位
DEC @R1 ;垂直方向红灯时间高位减1
HGNCARRY:
MOV R0,#31H ;R0指向水平方向时间显示数据区低位
DEC @R0 ;水平方向绿灯时间低位减1
CJNE @R0,#0FFH,HGREEN ;无借位则转移
MOV @R0,#09H ;有借位低位置为9
DEC R0 ;R0指向水平方向时间显示数据区高位
DEC @R0 ;水平方向绿灯时间高位减1
CJNE @R0,#0FFH,HGREEN ;水平方向绿灯时间到则退出
;水平方向黄灯亮的程序段,时间为5秒
CLR P1.7 ;水平方向绿灯灭
SETB P1.6 ;水平方向黄灯亮
MOV 30H,#00H ;水平方向黄灯时间设置为4秒
MOV 31H,#04H
HYELLOW:
MOV R2,#160 ;延时约160*6ms=960ms
HYDL1s:
MOV DPTR,#ADC0809 ;DPTR指向ADC0809
MOV A,#00H ;选择0通道
MOVX @DPTR,A ;启动转换
LCALL DISP ;6ms软件延时>转换时间100us
CLR RS0 ;设置第0组寄存器
CLR RS1
MOV DPTR,#ADC0809 ;DISP中修改了DPTR,这里使DPTR重新指向ADC0809
MOVX A,@DPTR ;读取转换结果
CLR C ;清空借位位
SUBB A,#90H ;判断垂直方向是否有人闯红灯
JC HYNWARN ;未发现闯红灯则转移
MOV 33H,#11H ;否则进行闯灯显示
SETB P1.0 ;声音报警
HYNWARN:
DJNZ R2,HYDL1s ;1s时间未到则转移
MOV R0,#31H ;R0指向水平方向时间显示数据区低位
DEC @R0 ;水平方向黄灯时间低位减1
DEC 35H ;垂直方向红灯时间低位减1
CJNE @R0,#0FFH,HYELLOW ;水平方向黄灯时间到则退出
;垂直方向绿灯亮的程序段,时间为25秒
CLR P1.6 ;水平方向黄灯灭
SETB P1.5 ;水平方向红灯亮
CLR P1.2 ;垂直方向红灯灭
SETB P1.4 ;垂直方向绿灯亮
MOV 30H,#02H ;水平方向红灯时间设置为29秒
MOV 31H,#09H
MOV 34H,#02H ;垂直方向绿灯时间设置为24秒
MOV 35H,#04H
VGREEN:
MOV R2,#160 ;延时约160*6ms=960ms
VGDL1s:
MOV DPTR,#ADC0809 ;DPTR指向ADC0809
MOV A,#00H ;选择0通道
MOVX @DPTR,A ;启动转换
LCALL DISP ;6ms软件延时>转换时间100us
CLR RS0 ;设置第0组寄存器
CLR RS1
MOV DPTR,#ADC0809 ;DISP中修改了DPTR,这里使DPTR重新指向ADC0809
MOVX A,@DPTR ;读取转换结果
CLR C ;清空借位位
SUBB A,#70H ;判断水平方向是否有人闯红灯
JNC VGNWARN ;未发现闯红灯则转移
MOV 32H,#11H ;否则进行闯灯显示
SETB P1.0 ;声音报警
VGNWARN:
DJNZ R2,VGDL1s ;1s时间未到则转移
MOV R1,#31H ;R1指向水平方向时间显示数据区低位
DEC @R1 ;水平方向红灯时间低位减1
CJNE @R1,#0FFH,VGNCARRY ;无借位则转移
MOV @R1,#09H ;有借位低位置为9
DEC R1 ;R1指向水平方向时间显示数据区高位
DEC @R1 ;水平方向红灯时间高位减1
VGNCARRY:
MOV R0,#35H ;R0指向垂直方向时间显示数据区低位
DEC @R0 ;垂直方向绿灯时间低位减1
CJNE @R0,#0FFH,VGREEN ;无借位则转移
MOV @R0,#09H ;有借位低位置为9
DEC R0 ;R0指向垂直方向时间显示数据区高位
DEC @R0 ;垂直方向绿灯时间高位减1
CJNE @R0,#0FFH,VGREEN ;垂直方向绿灯时间到则退出
;垂直方向黄灯亮的程序段,时间为5秒
CLR P1.4 ;垂直方向绿灯灭
SETB P1.3 ;垂直方向黄灯亮
MOV 34H,#00H ;垂直方向黄灯时间设置为04秒
MOV 35H,#04H
VYELLOW:
MOV R2,#160 ;延时约160*6ms=960ms
VYDL1s:
MOV DPTR,#ADC0809 ;DPTR指向ADC0809
MOV A,#00H ;选择0通道
MOVX @DPTR,A ;启动转换
LCALL DISP ;6ms软件延时>转换时间100us
CLR RS0 ;设置第0组寄存器
CLR RS1
MOV DPTR,#ADC0809 ;DISP中修改了DPTR,这里使DPTR重新指向ADC0809
MOVX A,@DPTR ;读取转换结果
CLR C ;清空借位位
SUBB A,#70H ;判断水平方向是否有人闯红灯
JNC VYNWARN ;未发现闯红灯则转移
MOV 32H,#11H ;否则进行闯灯显示
SETB P1.0 ;声音报警
VYNWARN:
DJNZ R2,VYDL1s ;1s时间未到则转移
MOV R0,#35H ;R0指向垂直方向时间显示数据区低位
DEC @R0 ;垂直方向黄灯时间低位减1
DEC 31H ;水平方向红灯时间低位减1
CJNE @R0,#0FFH,VYELLOW ;垂直方向黄灯时间到则退出
LJMP LOOP ;进行下一轮60秒的显示
;
DISP:
;用6ms显示30~35H的内容
;使用第3組R0R2,DPTR,A
;调用DL1ms
SETB RS0 ;设置第3组寄存器
SETB RS1
MOV R0,#30H ;显示数据区首地址
MOV R2,#80H ;初始化位选择码
LDISP:
MOV A,R2 ;取出位选择码
RL A ;位选择码左移1位,选择下一位
MOV R2,A ;保存当前位选择码
MOV DPTR,#IO8155A ;DPTR指向8155的A口
MOVX @DPTR,A ;输出位选择码,进行位选择
MOV A,@R0 ;从显示数据区取出要显示的数据
INC R0 ;显示数据区地址指针加1
ADD A,#03H ;调整查表偏移量
MOVC A,@A+PC ;查段码表
LJMP LIST ;跳过段码表
;段码表
DB 3FH,06H,5BH,4FH ;0~3
DB 66H,6DH,7DH,07H ;4~7
DB 7FH,6FH,77H,7CH ;8~B
DB 39H,5EH,79H,71H ;C~F
DB 40H,63H ;-,闯灯,
LIST:
MOV DPTR,#IO8155B ;DPTR指向8155的B口
MOVX @DPTR,A ;输出段码,进行显示
LCALL DL1ms ;持续显示1ms
CJNE R2,#20H,LDISP ;未显示完则重复下一步
RET;显示子程序返回
DL1ms:
;延时1ms
;第3組R7
SETB RS0 ;设置第3组寄存器
SETB RS1
MOV R7,#250 ;延时250*2T*2us/T=1ms
DL7: DJNZ R7,DL7;1ms未到则转移
RET ;延时子程序返回
;中断处理
INT0P:
;外部中断0中断服务程序,清除已有的报警状态
MOV 32H,#10H ;清空水平方向闯灯显示
MOV 33H,#10H ;清空垂直方向闯灯显示
CLR P1.0 ;关闭扬声器
RETI ;中断服务程序返回
END ;全部程序结束
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -