一片8155,可以提供256字节的RAM,3个并行IO接口和一个14位的定时器。
8155的内部还集成了地址锁存器,如果只是需要扩展8155,就可以省去常用的地址锁存器74LS373。
下面,先写一个使用单片机自身资源来驱动16个LED进行流水的程序。
然后,再把它改造为利用8155来驱动。
利用51单片机驱动16个LED流水灯的汇编语言程序如下。
;=========================================================
;16个LED接到P0,P2。
ORG0000H
START:
MOV30H,#254;片内RAM
MOV31H,#255;30H31H中仅有一个低电平
;-------------------------------------
MOVR2,#16;循环16遍
LOOP:
MOVP0,30H;输出到LED
MOVP2,31H
CALLDLY200MS;延时
CALLSHIFT_L;移位
DJNZR2,LOOP;循环16遍
SJMPSTART;再从头开始
;-------------------------------------
SHIFT_L:;16位数左移一位
MOVA,30H
RLCA;高位移入Cy
MOV30H,A
;---------------
MOVA,31H
RLCA;Cy移入低位,且高位移入Cy
MOV31H,A
;---------------
MOVA,30H
MOVACC.0,C;把Cy(高位)写入低位
MOV30H,A
;---------------
RET
;-------------------------------------
DLY200MS:;延时200ms,误差0us
MOVR6,#197;
DL0:
MOVR7,#250;1
DJNZR7,$;2*250=500
DJNZR7,$;2*256=512
DJNZR6,DL0;(1+500+512+2)*197=199955
MOVR7,#19;1
DJNZR7,$;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地址:
COMMANDEQU7F00H
PORTAEQU7F01H
PORTBEQU7F02H
PORTCEQU7F03H
TIMER_LEQU7F04H
TIMER_HEQU7F05H
;MEM地址:
;7E00H~7EFFH
因此,前面的流水灯程序,就要如下修改:
;=========================================================
;51单片机流水灯(16个灯)
;P0,P2外接16个LED--改为PA,PB
;30H,31H片内RAM----改为片外
ORG0000H
START:
MOVDPTR,#COMMAND
MOVA,#00000011B;PA方式0输出,PB方式0输出
MOVX@DPTR,A
INCDPTR;转到PA
MOVA,#00110011B;测试共阳极7段数码管
MOVX@DPTR,A
INCDPTR;转到PB
MOVA,#00001111B
MOVX@DPTR,A
;MOV30H,#254;--改为7E30H
;MOV31H,#255;--改为7E31H
MOVDPTR,#7E30H
MOVA,#254
MOVX@DPTR,A
MOVDPTR,#7E31H;片外RAM7E30H7E31H
MOVA,#255;中仅有一个低电平
MOVX@DPTR,A
;-------------------------------------
MOVR2,#16;循环16遍
LOOP:
;MOVP0,30H;输出到LED
;MOVP2,31H
MOVDPTR,#7E30H
MOVXA,@DPTR
MOVDPTR,#PORTA
MOVX@DPTR,A
MOVDPTR,#7E31H
MOVXA,@DPTR
MOVDPTR,#PORTB
MOVX@DPTR,A
CALLDLY200MS;延时
CALLSHIFT_L;移位
DJNZR2,LOOP;循环16遍
SJMPSTART;再从头开始
;-------------------------------------
SHIFT_L:;16位数左移一位
;MOVA,30H
MOVDPTR,#7E30H
MOVXA,@DPTR
RLCA;高位移入Cy
;MOV30H,A
MOVX@DPTR,A
;---------------
;MOVA,31H
MOVDPTR,#7E31H
MOVXA,@DPTR
RLCA;Cy移入低位,且高位移入Cy
;MOV31H,A
MOVX@DPTR,A
;---------------
;MOVA,30H
MOVDPTR,#7E30H
MOVXA,@DPTR
MOVACC.0,C;把Cy(高位)写入低位
;MOV30H,A
MOVX@DPTR,A
;---------------
RET
;-------------------------------------
DLY200MS:;延时200ms,误差0us
MOVR6,#197;
DL0:
MOVR7,#250;1
DJNZR7,$;2*250=500
DJNZR7,$;2*256=512
DJNZR6,DL0;(1+500+512+2)*197=199955
MOVR7,#19;1
DJNZR7,$;2*19=38
NOP;1
RET;1+199955+1+38+1+2=199998
;-------------------------------------
END
;=========================================================
原来程序中,凡是对30H、31H读写的指令,都改成对片外RAM读写。
凡是对P0、P2输出的指令,都改成对片外PA、PB输出。
这样写,程序的长度,将近增加了一倍。呵呵,没有办法,只能这样。
经过修改,即可利用8155的资源,进行流水灯的实验了。
显示的效果,是只有一个LED流动发光,比较简单,就不在这里插图了。