⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cross.asm

📁 自动交通管理系统 用红、绿、黄三支共两组发光二极管表示交通信号灯
💻 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 + -