一、MCS-51单片机的串行通信
MCS-51单片机具有一个串行通信口。这为与其它具有异步串行通信口的智能仪器通信奠定了物质基础,使智能仪器仪表的互连具有现实意义。
众所周知,单片机的串行通信口,具有多种工作方式,方式0主要用在扩展并行口方面,方式1用在异步通信方面,方式2则因其波特率选取范围受限而难于与计算机实现异步通信,方式3除在单片机系统中用于多机通信外,亦可用于与计算机的异步通信,若需带有奇偶校验时,使用方式3。由上述可知,方式1和方式3常常用作与计算机的异步通信,其中方式1的一帧为10位,即1位起始位,8位数据位,1位停止位,而方式3的一帧为11位,其中第9位作为奇偶校验用。
二、微机的异步通信
IBM微机及其兼容机,一般都有两个串行通信口,很容易实现与其它设备的异步通信。IBM微机异步通信的硬件核心是异步串行通信芯片8250。该芯片内部有10个寄存器,分别是发送保持寄存器(THR)、接收缓冲器(RBR)、MODEM状态寄存器(MSR)、MODEM控制寄存器(MCR)、中断使能寄存器(IER)、中断识别寄存器(IIR)、线路状态寄存器(LSR)、线路控制寄存器(LCR)、高字节除数寄存器(DLM)和低字节除数寄存器(DLL)。在IBM微机中分配给上述寄存器的地址如附表所示。

若与单片机通信,则使用电压接口方式,即使用端口的2,3,7(数据输出线,数据输入线和地)三根基本接口线。由于8250芯片使用的晶振是1.8432MHz的时钟,所以需要采用分频的方法来产生所要求的波特率,除数锁存器就是用来分频的[其内容为18432/(波特率×16)]。异步通信格式是通过对线路控制寄存器LCR写入状态字来实现的。对于8250来说通信格式比较多,使用比较灵活,通过对线路控制寄存器LCR写入适当的状态字,可以得到字长的选择,停止位个数的选择,奇偶校验的选择等。换句话说,异步通信格式可通过对线路控制寄存器写入状态字来设定。
在IBM微机系统中,还可以使异步通信工作于中断方式,其中断源为IRQ4(AT型机,COM1中断类型码为0CH),通过对中断允许寄存器写入适当的状态字决定中断的类型。例如,可以通过编程来指定四种中断之一或几个或全部。这些中断是:允许接收器数据就绪,允许传送器保持寄存器空,允许接收字符代码错或接收间断状态,允许改变调制解调器状态。如果要使用中断,必须使调制解调控制寄存器MCR的OUT2位设为l。这样8250产生的中断信号即可通过系统总线送给8259中断控制器。当8250引起中断后,在其中断服务程序中,通过读取中断识别IIR的值,由软件判断为何种中断以便转入相应的服务。
在IBM微机中,管理各种中断源的是8259中断控制器,它管理着软盘、硬盘、时钟等中断的处理,因此在使用异步通信中断时,要特别小心。若无特殊要求,建议在编程时不要破坏或随意改变原8259的状态,只就自己使用的某位进行操作(原8259的状态由微机上电复位时决定)。
三、MCS-51单片机与IBM微机串行通信举例
要实现二者通信,必须注意两点,一是通信的格式,二是通信的波特率,二者必须一致。如上所述单片机的异步通信只有发送和接收两条引线,而IBM微机的引线则较多,适合于较复杂的异步通信方式,因此选用最简单的电压接口方式,使用的引线主要有2,3,7三根,另外将串行通信的D型25针插头的4、5短路,6、20短路,MCS-5l单片机与IBM微机通信的原理如图所示。

大家知道,在电压接口方式下,对应逻辑0的电压范围是+3V~+12V,对应逻辑1的电压范围为-3V~-12V,而单片机的输出输入则是与TTL兼容的逻辑电平,因此必须进行逻辑电平转换。常用的器件是1488和1489。这两种芯片是专为RS232异步通信的电平转换而设计的,使用很方便,但需要±12V电源。若是通信距离不远,采用本文介绍的连接方法,在150~9600波特率下工作时,工作稳定。
四、编程举例
若选用通信波特率为1200,1位起始位,8位数据位,l位停止位,无奇偶校验,单片机时钟为6MHz,设有10个数据(存放在内部RAM中,起站地址为20H)需传送给IBM计算机,则单片机的程序可以如下编制:
9
ORG 2000H
MOV SCON,#01010000B ;串行口工作平方式1
MOV TMOD,#00100000B ;定时器1工作于方式1
MOV TL1, #0F3H ;时间常数
MOV TH1, #0F3H ;时间常数
SETB TR1 ;启动定时器1
MOV B,#10
MOV R0,#20H
LOOP:MOV A,@ R0
MOV SBUF,A
IN
LCALL 013BH ;调用20ms延时子程序
DJNZ B,LOOP
SJMP$
END
IBM微机以响应中断的方式接收数据,程序如下:
program AUX-sample;
uses dos;
var
i:byte;
x:array[1..10] of byte;procedure IntHandler(Flags,CS,IP,AX,BX,CX,DX,SI,DI,DS,ES,BP:wORD); Interrupt;
begin
i:=i+1; x[i]:=port[$3F8];
port[$20]:=$20;
asm
mov sp,bp
pop bp
pop es
pop ds
pop di
pop si
pop dx
pop ex
pop bx
pop ax
iret
end;
end;
begin
port[$3FB]:=$80;
port[$3F8]:=$60;
port[$3F9]:=$00;
port[$3FB]:=$03;
port[$3FC]:=$0F;
port[$3F9]:=$01;
Setintvec($0C,@IntHandler);{安装中断服务程序}
port[$21]:=port[$21]and$EF;{IRQ4使能}
port[$20];=$20;
i:=port[$3f8];;
i:=0;
repeat
untili=10;
Port[$21]:=ptort[$21]or $ 10;{恢复原来状态}
fof i:=1 to 10 do
writeln(’I=’,i,’DATA=’,x[i]);
writele(’Take date ok ’);
end.
本程序用到口地址20H和21H,它们分别是对8259进行。上列程序已被实践所验证。(王建校 杨拴科)