在 51 单片机系统中使用 8155
扫描二维码
随时随地手机看文章
单片机自身的 RAM 存储空间和引脚数目往往有些不足,当需要在外部拓展不太多的时候,8155 芯片就是首选了。
一片 8155,可以提供 256 字节的 RAM,3 个并行 IO 接口和一个 14 位的定时器。
8155 的内部还集成了地址锁存器,如果只是需要扩展 8155,就可以省去常用的地址锁存器 74LS373。
下面,先写一个使用单片机自身资源来驱动 16 个 LED 进行流水的程序。
然后,再把它改造为利用 8155 来驱动。
利用 51 单片机驱动 16 个 LED 流水灯的汇编语言程序如下。
;=========================================================
; 16 个 LED 接到 P0, P2。
ORG 0000H
START:
MOV 30H, #254 ;片内 RAM
MOV 31H, #255 ;30H 31H 中仅有一个低电平
;-------------------------------------
MOV R2, #16 ;循环 16 遍
LOOP:
MOV P0, 30H ;输出到 LED
MOV P2, 31H
CALL DLY200MS ;延时
CALL SHIFT_L ;移位
DJNZ R2, LOOP ;循环 16 遍
SJMP START ;再从头开始
;-------------------------------------
SHIFT_L: ;16位数左移一位
MOV A, 30H
RLC A ;高位移入Cy
MOV 30H, A
;---------------
MOV A, 31H
RLC A ;Cy移入低位,且高位移入Cy
MOV 31H, A
;---------------
MOV A, 30H
MOV ACC.0, C ;把Cy(高位)写入低位
MOV 30H, A
;---------------
RET
;-------------------------------------
DLY200MS: ;延时200ms,误差0us
MOV R6, #197 ;
DL0:
MOV R7, #250 ;1
DJNZ R7, $ ;2 * 250 = 500
DJNZ R7, $ ;2 * 256 = 512
DJNZ R6, DL0 ;(1 + 500 + 512 + 2) * 197 = 199955
MOV R7, #19 ;1
DJNZ R7, $ ;2 * 19 = 38
NOP ;1
RET ;1 + 199955 + 1 + 38 + 1 + 2 = 199998
;-------------------------------------
END
;=========================================================
上述程序所对应的电路,太简单了,就不在这里显示插图了,读者可自行画图。
当在电路中加入了一片 8155,电路可以如下连接:
图中,由于使用了 P2.7 和 P2.0 连接到 CS 和 IO/M,所以,8155 的接口地址、存储器地址分别为:
;I/O 地址:
COMMAND EQU 7F00H
PORTA EQU 7F01H
PORTB EQU 7F02H
PORTC EQU 7F03H
TIMER_L EQU 7F04H
TIMER_H EQU 7F05H
;MEM 地址:
;7E00H ~ 7EFFH
因此,前面的流水灯程序,就要如下修改:
;=========================================================
;51单片机流水灯(16个灯)
;P0, P2 外接 16 个 LED--改为 PA, PB
;30H, 31H 片内RAM ----改为 片外
ORG 0000H
START:
MOV DPTR, #COMMAND
MOV A, #00000011B;PA方式0输出,PB方式0输出
MOVX @DPTR, A
INC DPTR ;转到PA
MOV A, #00110011B;测试共阳极7段数码管
MOVX @DPTR, A
INC DPTR ;转到PB
MOV A, #00001111B
MOVX @DPTR, A
; MOV 30H, #254 ;--改为 7E30H
; MOV 31H, #255 ;--改为 7E31H
MOV DPTR, #7E30H
MOV A, #254
MOVX @DPTR, A
MOV DPTR, #7E31H ;片外 RAM 7E30H 7E31H
MOV A, #255 ;中仅有一个低电平
MOVX @DPTR, A
;-------------------------------------
MOV R2, #16 ;循环 16 遍
LOOP:
; MOV P0, 30H ;输出到 LED
; MOV P2, 31H
MOV DPTR, #7E30H
MOVX A, @DPTR
MOV DPTR, #PORTA
MOVX @DPTR, A
MOV DPTR, #7E31H
MOVX A, @DPTR
MOV DPTR, #PORTB
MOVX @DPTR, A
CALL DLY200MS ;延时
CALL SHIFT_L ;移位
DJNZ R2, LOOP ;循环 16 遍
SJMP START ;再从头开始
;-------------------------------------
SHIFT_L: ;16位数左移一位
; MOV A, 30H
MOV DPTR, #7E30H
MOVX A, @DPTR
RLC A ;高位移入Cy
; MOV 30H, A
MOVX @DPTR, A
;---------------
; MOV A, 31H
MOV DPTR, #7E31H
MOVX A, @DPTR
RLC A ;Cy移入低位,且高位移入Cy
; MOV 31H, A
MOVX @DPTR, A
;---------------
; MOV A, 30H
MOV DPTR, #7E30H
MOVX A, @DPTR
MOV ACC.0, C ;把Cy(高位)写入低位
; MOV 30H, A
MOVX @DPTR, A
;---------------
RET
;-------------------------------------
DLY200MS: ;延时200ms,误差0us
MOV R6, #197 ;
DL0:
MOV R7, #250 ;1
DJNZ R7, $ ;2 * 250 = 500
DJNZ R7, $ ;2 * 256 = 512
DJNZ R6, DL0 ;(1 + 500 + 512 + 2) * 197 = 199955
MOV R7, #19 ;1
DJNZ R7, $ ;2 * 19 = 38
NOP ;1
RET ;1 + 199955 + 1 + 38 + 1 + 2 = 199998
;-------------------------------------
END
;=========================================================
原来程序中,凡是对 30H、31H 读写的指令,都改成对片外 RAM 读写。
凡是对 P0、P2 输出的指令,都改成对片外 PA、PB 输出。
这样写,程序的长度,将近增加了一倍。呵呵,没有办法,只能这样。
经过修改,即可利用 8155 的资源,进行流水灯的实验了。
显示的效果,是只有一个 LED 流动发光,比较简单,就不在这里插图了。