前面几讲介绍了单片机指令及内部功能单元等,本讲介绍单片机输入/输出(I/O)接口的扩展使用方法。在单片机应用系统中,一般都通过I/O接口连结多种外部设备,例如键盘、LED显示器、数字——模拟转换器、模拟——数字转换器等。怎样利用有限的I/O口连接多路外设,即I/O接口的扩展问题是单片机应用系统的基本问题之一。I/O接口扩展的基本方法大致可分为两种,一种是采用8155、8255等通用并行接口芯片进行扩展;另一种方法是用简单的三态门或锁存器直接在总线上进行扩展。这类芯片有74LS244、245、273、373、377等等。下面分别介绍这两种扩展方法并进行有关实验。
8155的扩展实验
8155内部包含有两个8位(PA、PB)、一个6位(PC)共22位I/O口线,一个14位的计数器以及256×8位的静态RAM,可见扩展一片8155芯片,就能获得如此众多的可用资源。

图1给出了TD-Ⅰ型机与8155芯片的连接电路,其中0AD~7AD、ALE、WR、RD-、RST-、VCC、E均与8031各条引线对应连接,IO/M-接0P2(8A),片选线CE-在这里被用作地址选通线,可由8031分配地址。由于TD-Ⅰ型机中6116RAM的地址是多重地址(7P2~3P2高位地址线悬空),若直接引出高位地址线作为8155的片选线CE-的地址选通线,那么当CPU对8155进行操作时有可能破坏6116RAM的内容。因此图2中采用了74LS138译码器,译码器的6Y-接8155的CE-,则当8155的地址范围为C000H~DFFFH(参见第七讲,1991年2期)。另外6116作为程序存储器使用时,地址必须从0000H开始;在手动编程时,由于P2口在上电复位时的状态全是高电平,要保证程序能输入,还要使6116在地址从E000H开始(7P2~5P2为全1)的地址区内被选通。为使在这两个地址时,6116均被选中,应将译码器的0Y-和7Y-经过两级与非门接到TD—Ⅰ型机中6116的片选端(需先将6116的18脚与地断开),这样6116的地址范围为0000H~1FFFH和E000H~FFFFH,8155的地址为C000H~DFFFH。手动输入程序时,7Y-有效;CPU读取存储器内容时,0Y-有效;对8155操作时,6Y-有效。这就保证了操作时地址不重复,避免相互干扰。
图中的两个与非门可以利用TD-Ⅰ型机中74LS00的两个空门或另接入一片74LS00。所有外扩芯片均应装在(万次多用)实验电路板上。
接线完毕可以对8155内部256字节的存储单元RAM进行操作。
8155内部256字节RAM地址区的低8位地址为00H~FFH,高8位地址由6Y-及0P2决定。当6Y-有效(即8031的7P2~5P2为110,地址在C000H~DFFFH范围内)且0P2=0时(即IO/M-=0)才选中8155的内部RAM,因此高8位地址应为110××××0,×若都取1,则高8位为DEH。故整个地址范围为DE 00 H~DEFFH。
下面一段程序可对8155内部RAM进行写数据,读者可将它输入学习机进行练习。
ORG 0000 H
LJMP MAIN
ORG 0030 H
MAIN: MOV R 2,#00H ;计数器R2置初值
MOV A, #00H ;置数据
MOV DPTR,#DE 00 H ;置8155RAM首地址
LOOP1:MOVX TR,A ;写入8155内部RAM
INC DPTR ;修改指针
DJNZ R2,LOOP1 ;256字节全部写毕否
MOV DPTR,#DE 00 H ;置8155 RAM首地址
MOV P2,#02H ;学习机0200H开始的单元
MOV R0,#00H ;存放数据
LOOP2:MOVX A,TR ;读8155内部RAM
MOVX ;写入0200H开始的RAM区
INC DPTR ;修改8155地址指针
INC R0 ;修改6116RAM地址指针
DJNZ R2,LOOP2 ;读写完否
LOOP3:SJMP LOOP3 ;等待
机器码为0000H:02 00 30H;0030H 00,74 00,90 DE 00,F0,A3,DA FC,90 DE 00,75 A0 02,78 00,E0,F2,A3,08,DA FA,80 FE。
运行结束后检查以0200H单元为首地址的256个单元内容应全部为00H。还可将0033H单元的00H改为其它数,运行并检查,结果应一致。
[实验2] 8155I/O口操作实验
图1中,当6Y-有效且0P2(IO/M-)为1时,8031可对8155的I/O口进行操作,此时地址的高8位为DFH,低8位地址由7AD~0AD(即7P0~0P0)统一编址如下:
7AD~0AD 8155的I/O口名 TD-I地址
×××××000 命令/状态字寄存器 DF 00H
×××××001 PA口 DF01H
×××××010 PB口 DF02H
×××××011 PC口 DF03H
×××××100 计数器低8位 DF04H
×××××101 计数器高8位 DF 05H
8155的PA口、PB口及计数器的工作方式是通过向命令/状态字寄存器地址DF00H写入命令字来选择的。命令字的各个位定义如下表:
7D 6D 5D 4D 3D 2D 1D 0D
TM2 TM1 IEB IEA PC2 PC1 PB PA
其中PA、PB分别定义PA口和PB口的工作方式。当PA(或PB)=0时,定义PA口(或PB口)为输入方式;当PA(或PB)=1时,定义PA口(或PB口)为输出方式。PC2、PC1定义PC口的工作方式。PC2、PC1为00时,PA口PB口定义为基本输入、输出方式,PC口为输入方式;当PC2、PC1为11时,PA口、PB口定义为基本输入、输出方式,PC口为输出方式;当PC2、PC1为01时,PA口为选通输入、输出方式,PB口为基本输入、输出方式,此时PC口的0PC、1PC、2PC三根线定义为PA口的联络线,3PC~5PC为输出方式;当PC2、PC1为10时,PA口、PB口都为选通输入、输出方式,此时0PC~2PC三根线为PA口的联络线,3PC~5PC三根线为PB口联络线,其中0PC、3PC分别为PA口、PB口的中继请求线,其余线为与外设的应答线。
IEA、IEB分别为PA口和PB口的中断允许位。当IEA=0时,PA口禁止中断;IEA=1时,PA口允许中断;当IEB=0时,PB口禁止中断;IEB=1时,PB口允许中断。
命令字的最高两位7D、6D用来控制计数器的启动或停止。当TM2、TM1为00时产生空操作;为01时停止计数;为10时,当计数器达到当前的计数终值后立即停止计数;为11时,启动,计数时,装入常数后立即计数,否则待计数器溢出后按新的工作方式和计数常数开始计数。
另外,当读出该寄存器内容时,读出的是当前I/O口和计数器的状态,状态格式如下:7D无效;6D为定时器中断(TIMER)状态位,当计数器满时置入高电平,在读出命令/状态字寄存器的状态或硬件复位时变为低电平;5D为PB口中断允许(INTEB)状态位;4D为PB口缓冲器满/空(BFB)状态位;3D为PB口中断请求(INTRB)状态位;2D为PA口中断允许(INTEA)状态位;ID为PA口缓冲器满/空(BFA)状态位;0D为PA口中断请求(INTRA)状态位。
对8155I/O口操作实验内容如下:设PA口为基本输入方式,PB口为基本输出方式。实验电路如图2所示,图中PA口的一组开关可以模拟输入数据,PB口的发光管能实时地将PA口的状态显示出来。根据PA口和PB口的工作方式设置要求,8155的命令控制率应为00000010B,即02H。
实验参考程序如下:
ORG 0000 H
LJMP MAIN
ORG 0030H
MAIN: MOV DPTR, #DF 00 H; DPTR指向命令口
MOV A,#02 H;将控制字02H
MOVXTR A;写入命令寄存器
MOV DPTP,#DF 01 H;DPTR指向PA口
MOVX A,TR;读取PA口的开关状态
INC DPTR;DPTR指向PB口
MOVXTR,A;将PA的内容输出到PB口
SJMP MAIN;循环
机器码如下:000H:02 00 30;0030H:90 DF 00,7402,F0,90 DF 01,E0,A3,F0,80 F2。\
按图2连好电路后再输入指令码,然后运行程序。反复改变PA口开关的状态,观察PB口发光管的显示状况。

[实验3]8155计数器操作实验。
8155片内的14位减法计数器由8155的04H(DF04H)寄存器和05H(DF05H)寄存器组成,其中04 H寄存器的8位构成14位计数器的低8位,05 H寄存器的低6位构成14位计数器的高6位。外部有两个引脚分别作为计数器的输入(TIN)和输出(TOUT)端,计数脉冲由TIN引脚输入,每输入一个脉冲计数器内容(从计数长度初值开始)减1,当达到最后计数值(指计数长度初值的一半)时,TOUT引脚输出状态进行翻转。TOUT的输出波形可以有4种不同选择,即单次方波、连续方波、终止计数时的单脉冲、连续脉冲。05H寄存器的最高两位M2、M1选择不同值时可获得不同的输出波形,M2、M1取00、01、10、11时,TOUT分别输出单次方波、连续方波、终止计数时的单脉冲、连续脉冲。M2、M1的值和计数长度初值由指令同时送入,计数长度初值的范围为0002H~3FFFH,如果写入计数器的计数长度初值为奇数,则输出方波不对称。例如计数长度初值为9时,则计数器输出方波在5个输入脉冲周期内为高电平,4个输入脉冲周期内为低电平。如将该计数器作为分频器用,则将分频系数N作为计数器的计数长度初值送入,在TOUT端就可获得N分频的连续方波,即输出方波的周期是输入脉冲周期的N倍(如上所述的9分频)。
下面的实验是利用8155的计数器作为分频器实现100分频。输入脉冲源可利用8031的ALE引脚输出的波形,其频率为fosc/6=1MHz。实验前,先将8155的TIN(3脚)和8031的ALE(30脚)相连。
实验参考程序如下:
ORG 0000H
LJMP MAIN
ORG 0030H
MAIN:MOV DPTR,#DF 04 H;计数器
MOV A,#64H;低8位送计数
MOVX TR A;初值100(64H)
INC DPTR
MOV A,#40H;置连续方波输出
MOVXTR,A;方式(M1、M2=1、0)
MOV DPTR,#DF00 H;指向命令口
MOV A #0C3 H
WAIT:MOVXTR,A;启动计数器
SJMP WAIT;循环等待
机器码为0000 H:02 00 30;0030 H:90 DF 04,74 64,F0,A3,74 40,F0,90 DF 00,74 C3,F0,80 FD。
程序运行后,TOUT脚就会产生连续方波输出,如果没有硬件复位,则输出将持续下去。TOUT的波形可用示波器观察并测出输出波形的频率。读者还可以练习如下内容:1)改变分频系数,即计数器初值(0033H中的内容);2)改变TOUT的输出方式即M2、M1的值,观察输出波形是否与所预期的一致。
如果没有示波器,可在TIN端输入一个频率较低的外接信号源,在TOUT引脚接一发光管,选择适当的分频系数,就能直接观察输出波形的周期大小,(用扬声器也能定性“听”出用期大小)。
有兴趣的读者还可利用8031的计数器来测出一个脉冲的周期。具体方法是:将TOUT接8031的0T端,并在TD-Ⅰ上输入如下参考程序:
ORG 0000 H
020030; LJMP MAIN
ORG 001BH
020070; LJMP INT
ORG 0030 H
758D3c;MAIN:MOV TH1,#3CH;0T,1T初始化,1T送
758BB0; MOV TL1,#B 0 H;定时常数100ms,0 T
758915; MOV TMOD,#15H;为外部计数方式。
90DF04; MOV DPTR,#DF 04 H;8155的计数
7464; MOV A #64H;器对ALE信号100分频。
F0; MOVX TR A
7440; MOV A,#40H;TOUT输出连续方波
A3; INC DPTR
F0; MOVX TR,A
90DF00; MOV DPTR,#DF00H
74C3; MOV A,#0C3H
D2AF; SETB EA; 1T开中断
D2AB; SETB ET1
D28C; SETB TR0;0T、1T计数开始
D28E; SETB TR1
F0; WAIT:MOVXTR,A;启动3155工作
80 FD; SJMP WAIT
ORG 0070 H
C083;INT: PUSH DPH
C082; PUSH DPL
C0E0; PUSH A
C28C; CLR TR0;0T停止计数
C28F; CLR TF1;清1T中断标志
900150; MOV DPTR,#0150H;将0T的计数器
E58A; MOV A TL0;结果送入0150H及
F0; MOVXTR,A;0151H,供检查
A3; INC DPTR
E58C; MOV A,TH0
F0; MOVX TR,A
D0E0; POP A
D082; POP DPL
D083; POP DPH
32; RETI
TH0、TL0内部读数为0T在100ms内记录的输入脉冲个数,因而可知TOUT的频率为TH0,TL0中的数值乘10。
需要指出的是,由ALE所得计数脉冲频率是不稳定的,当CPU执行程序存储器操作指令时,ALE的信号频率为fosc/6,而当CPU执行外部RAM指令时,ALE的信号频率约为fosc/8。
总线扩展方式实验
1.用三态门扩展输入口
事实上,三态门本身就是一个最简单的接口电路,利用地址线可以控制三态门的接通或断开。图3中的74 LS 244芯片就是一个具有8个三态门的集成芯片,8个三态门分成两组,其控制端G1-、G2-受地址线1Y-控制,当1Y-有效(即7P2、6P2、5P2=001时),244内部的三态门都被选通,其地址范为2000 H~3 FFFH,当执行指令MOV DPTR,#2000 H及MOVX A,TR时,就可读取该输入口的数据,而在其他时该,1Y-无效,244均处于悬浮状态。
用244也以构成输出口,但这个输出口没有锁存能力,口上的数据是暂态的。
2.用锁存器扩展输出口

图3中74LS373芯片是一个带有锁存输入、控制输出的8D触发器,其11脚(G)为输入锁存控制端。当G有效(高电平)时,将输入引脚的状态锁存到D触发器,当EN-(1脚)有效(低电平)时,D触发器状态才反映到输出引脚上。图4中,G被上拉为高电平,EN-接地址2Y-,其地址范围为4000H~5FFFH。每执行一次输出指令MOV DPTR,#4000H及MOVXTR,A输出口状态就被修改一次。当EN-无效时,该输出状态不会发生改变,我们称这样的输出口具有锁存能力。
[实验4]用244和373扩展的I/O口操作实验
按图3接好电路,244为输入口,373为输出口。输入口的8个开关可以模拟输入的数据,输出口的8个发光管用来指示输入端的状态。
实验程序如下:
ORG 0030H
902000;MAIN:MOV DPTR,#2OOOH
E0; MOVX A,TR;该输入口数据
904000; MOV DPTR,#4000 H
F0; MOVXTR,A;送到输出口
80F6; SJMP MAIN
实验内容可参阅实验2。(周振安)