DOS程序员参考手册介绍
131页
第7章 串行设备
现代计算机世界的串行设备是非常吸引人的。感谢串行设备,借助这样的设备,再利
用如CompuServe或MCI Mial的系统,我们就能与世界各地不同的人们进行通信联系。
本章的主题是有关串行设备为什么能以目前的方式运行,以及我们怎样才能利用它们的
特性。
在这一章里,都要以与其它计算机进行通信这种方式而与串行设备一起工作——这
是当前这种通信方式最常见的用户。串行通信还可以用于打印机、传感器和许多其它的设
备。并且这种通信不必是双向的。例如,与打印机的通信占主导地位的是单向的:从计算
机到打印机。或者可以建立一个程序来读取Associated Press新闻电信,它是一个1200bps
(每秒位)的单向数据传送,或NOAA的天气信息,它是一个50bps的单向数据传送。
本章集中介绍一个简单的双向终端通信程序,该程序包括了串行通信的所有方面。但
在编写终端程序之前,应该知道串行接口的工作方式。定义一些基本术语后,就要提供有
关IBM PC串行接口芯片(UART)的工作方式方面的细节。然后讨论上升到硬件水平以
便用户了解怎样直接控制芯片。
借助一些基本原理,可以编写两个终端程序。第一个利用BIOS功能去访问串行端
口。将会看到:这种类型的程序用于重要的通信时太慢了。如果直接与UART芯片一起工
作,就可以获得一定的速度和控制。尽管第二个终端程序证明了这项技术,但即使是这样,
它对1200bps的实际通信也还是太慢了。一个真正的实用通信程序必须将本章中的技巧
与第11章“中断处理程序”中的内容结合在一起。编写一个中断驱动的通俗读物程序,并
非本书所涉及的主题,它是对任何PC程序员的耐心和他们的理解程度的考验。有关编写
这样的程序的实例可以参看《Advanced Assembly Language》,由Allen L,Wyatt编写(由
Que公司出版)。
从基本原理上讲,一个串行接口是将计算机内部数据的并行格式(8位字节)转变成
一个串行格式(1位),后者能在单根数据线上进行传递。这种转换能由软件来执行,但在
PC机中,硬件能更有效地完成它。
图7.1分析了串行接口的基本目的:将信息由并行格式转变成串行格式,或反过来。
数据从该接口的一边进入,从另一边产生和转换。接口把数据的每个字符转变成一个信息
“包”,从而将数据转变成串行格式;这个信息“包”能以发送和接收双方都认可的某种途径
来进行传递(有关串行格式的更详细讨论,见本章稍后部分)。只有在每个串行连接的终端
都使用同样的数据格式和相同的传递速度时,计算机之间才能成功地进行通信。
常用两种方法来传递串行信息。它们都称作定时方法,它们都是通过串行来传递和接
132页
图7.1串行接口将数据形式由并行的(内部的)变成串行的(外部的)
收信息的。第一种方法叫作同步通信,它维持对数据经连接而进行的传递和接收的严格控
制。在这个过程中,数据以精确定时的间隔进行传递。定时信息是与数据一起传递的,以
便接收方计算机能与要接收的信息同步。这类通信通常用于小型机或主机应用程序,有关
它的讨论则超出了本书的范围。
第二种方法叫做异步通信。在这种方法里,每个信息包放在通信线上,彼此之间并没
有精确限定的时间间隔。这些数据包能够一个挨一个地快速传递或每个传递之间间隔不
同的时间。这种方法对于大多数微机,包括IBM系列都是适合的。
尽管可以为其它类型的串行通信(如前面提到的同步方法)购买硬件接口设备,但异
步通信应该能满足大多数通常目的的需要。
图7.2显示了通信线上的串行信息包(可以作为异步通信的时间功能)。该线路通常
保持标记状态(高电压)。当下降到空闲状态(低电压)时,就是给信号说明字符开始了(开
始位)。要确定下一个位是高或低,可以用以位频率为基础的精确时间间隔来对线路进行
抽样。在标记状态时,数据位后会紧跟一个或更多的停止位,从而有足够的时间用于字符
处理和用于系统准备下一个字符。
图7.2串行传递
7.1串行接口
在进行异步通信的更详细讨论之前,应该了解基本的通信术语。我们还要看到,串行
接口将并行格式数据转换成容易经过串行通信连接进行传递的信息包形式。这些信息包
133页
油许多特定的信息位构成。每个位都有一个特定的目的:开始位、数据位、停止位以及奇偶
性。下面定义这些和其它几个重要的术语:
·开始位在实际字符数据之前送出的一个位,用来警告接收方计算机:一个字符
就要来了。该位由串行设备自动送出。
·数据位该位代表正在传递的单个字符。(数据位的个数通常即是字的长度)。在
计算机奇偶性的情况下,串行设备的正常通信使用7位的字长度(见下列定义);
否则就使用8位的字长度。 IBM PC上的串行通信芯片能够操纵5-8个数据位。
·奇偶性一个简单的字符水平“真假性”检查,接收方可以利用它来看看是否已正
确地接收到了字符。计算奇偶性的方法是:首先计数正在传递的信息包中数据部
分设置为1的位数,然后加上所希望的奇偶性类型位代表。对于EVEN(偶)奇偶
性,设置为1的数据位的总数再加上奇偶性位必须是一个偶数。相反,ODD(奇)奇
偶性中就会带来一个奇数。其他的奇偶性位可能的设置包括MARK(总是设置成
1),SPACE(总是设为0),或NONE(总是忽略)。
·停止位该位在数据包的结束处送出,以便给接收方时间,在下一个字符到来之
前处理已有的一个字符。对于将要操纵的所有通信,正常情况下只有一个停止位
(只有当通信以极低的速度,如110bps进行时才需要2个停止位)。
·波特率这是一个电气学名词,代表一条通信线的传输速率。它常常(尽管不正
确)用来指位速率。
·位速率传输速度,即每秒传送的位数,常常(尽管不正确)被称为波特率。位速率
是个更精确的词,故在本书中主要使用它。
·全双工一种通信手段,传递时,显示在屏幕上的信息就是输送给远处计算机的
字符的回送。
·半双工也是一种通信手段,其中传送给远处计算机的信息并未返回到送出的计
算机。
一台计算机与另一台计算机通信时,双方必须根据一系列预先限定的用来定义所传
递的信息格式的参数进行操作。如果两台计算机没有设置为相同值,它们之间的通信就是
不可靠的。计算机之间的通信没有象应有的那样普及,一个原因是程序员还没能在不需用
户去理解专业化的、复杂术语的通信标准上达到共识。
但许多配置却是相当标准的。通常,8个数据位,没有奇偶性,以及一个停止位或者7
个数据位,EVEN或ODD奇偶性以及一个停止位就可以工作了。对于大多数联机计算机
系统,位速率一般都建立在1200、2400或9600bps上。如果试试这些配置中的一个,那么
几乎总是能与联机计算机系统中的某台计算机匹配上。
传递信息之后,计时至关重要。通信线在接收到开始位之前是空闲的。开始位到达后,
就要在精确的时间间隔内对通信线进行采样,以接收构成字符的单个位。奇偶性位则用来
计算所传递的字符的正确程度,它紧跟在数据位之后,最后,得到并释放停止位,接收方又
在等待下一个开始位。
如果这些背景知识使人晕头转向,那么可以放松一下。IBM微机已安装了管理串行
134页
通信的低水平行为的硬件。在确定要使用的通信参数并把它们输入以后,串行转换硬件能
保证使用户得到所希望的东西。
7.2串行转换:UART
IBM微机(以及大多数兼容tA)都使用一个硬件芯片:它起初以8250 Universal Asyn-
chronous Receiver/Transmitter(8250通用异步接收/传送器)为基础,由National Semicon-
ductor(国家半导体)公司生产。在Pc机和Pc/xT的早期,就已经使用了这种芯片的其它
类型。最近的则是Pc16450和Pc16550。这类芯片在功能上都与8250等同,但能提供更
高的效率和速度。 Pc16550除了与8250兼容以外,还有一个使用了FIFO(先进、先出)数
据缓冲的操作方式,该数据缓冲大大地增加了吞吐量。在这一章里,这3个芯片简单地称
作UART(广泛的异步接收者/运输者)。
与一些依赖软件来管理通信的系统相比,UART让人迷惑不解。它参与到接收和传
递信息位的具体活动中,从而使程序员不用完成其它任务。
假定需穿过一系列电线来送出数据,而此时线上电压水平在不断变化。如果编写了程
序来管理这条线路,那么就能直接控制这条线,并告知任何需要的东西。听起来很困难,是
不是?理论上并不是这样,但过程是繁琐的,并易导致细微的出错。有些系统(例如,原始
的TSR80彩色计算机)只能以这种方式处理串行通信。
借助UART,就不必添麻烦去编写在通信线上开或关来获得数据的一个软件控制程
序。要花少得多的精力去编写和测试软件uART,UART芯片为使用者提供了大量的控
制,并允许与其他设备进行快速的、标准的通信。
8250和16450 UART分别有10个可以编程的1个字节寄存器;16550则有11个。
这些寄存器控制和监视串行端口。大多数寄存器用于初始化,只有几个用得有规律。所有
寄存器都可通过7个I/O端口地址进行访问。这些地址作为来自一个基地址的偏移值来
计算,基地址是随着所使用的通信端口而改变的。表7.1显示了coM1:到coM4:的基地
址;表7.2列举了这些地址的偏移值,它们分别控制每个UART寄存器。
表7.1 IBM通信端口的基地址
通信端口 基地址
COM1: 03F8h
COM2: 02F8h
COM3: 03E8h
COM4: 02E8h
表7.2 UART寄存器:来自基地址的值
偏移值 LST位7 意 义
0 0 传递保持者寄存器(THR)和接收者数据寄存器(RDR)
0 1 波特率除数值的低字节(BRDL)
135页
(续)
偏移值 LST位7 意 义
1 0 中断允许寄存器(IER)
1 1 波特率除数值的高字节(BRDH)
2 x 中断识别寄存器(IIR)和FIFO控制寄存器(FCR一16550UART独有)
3 x 线控制寄存器(LCR)
4 X 调制解调器控制寄存器(MCR)
5 X 线状态寄存器(LSR)
6 x 调制解调器状态寄存器(MSR)
读者可能已注意到,即使UART有10或11个寄存器去控制操作,但却只有7个端
口地址。这7个地址中的大多数支持一个以上的寄存器。在偏移值为0时,不论什么时候
向端口写,都可以访问THR,而不论什么时候从端口读都可以访问RDR。因为这两个寄
存器中没有一个需要同时的读和写访问,所以这两者的结合很有意思。这种安排与用在
16550 UART上的安排是相同的;IIR和FCT寄存器共享相同的寄存器。IIR是一个只读
的寄存器;FCR则是一个只写的寄存器。
当LSR第7位设置为1时,偏移值为0和1的寄存器则会执行另一项功能。当这种
情况发生时,这两个端口就会访问BRD寄存器(因为只有在芯片的初始化期间才访问
BRD寄存器,所以它们在通常操作期间能安全地保存起来)。
让我们看看每个UART寄存器都做些什么。
7.2.1发送保持寄存器(THR)
该寄存器保持有将要送出的数据字节。如果LSR的第5位指示该寄存器是空的,那
么就可以向它写入数据。
7.2.2接收数据寄存器(RDR)
该寄存器保持有最近从通信线上接收到的数据韶。如果LSR0位指示已接收到一
个字节,那么就可以读取该寄存器。
7.2.3波特率除数(BRD)
BRD是一个16位数,它指定UART使用的传输率(不是波特率,不考虑UART设计
考所给的正规名字)。它在两个8位端口(BRDt和BRDH)之间划分开来。要确定位传输
速率,就可用UART的内部时钟频率(1.832MHz)来除以BRD,如下所示:
BRD=时钟速度/16*期望的bps
使用该等式很容易确定不同位速度的设置。例如计算BRD为9,600,等式如下∶
BRD=1843200/16*1200=1843200/19200=96=0060h
于是,BRDH必须设置为0,而且BRDL必须设置成0Ch。
136页
可以使用该等式来构造表7.3所列举的典型位速率的BRD。
表7.3 波特率除数
位速率 BRDH BRDL
50 09h 00h
110 04h 17h
300 01h 80h
1200 00h 60h
2400 00h 30h
4800 00h 18h
9600 00h 0Ch
19200 00h 06h
注意IBM警告其BIOS早期版本用户,不要设置高于9600bps的位速率。但可在
19200bps(甚至更高)的位速率下安全地驱动UART。
要设置BRD,必须首先将LCR的第7位设置成1。然后可以安全地将所需除数输
出给它们的I/O地址(参见表7.2)。设置BRD后,应马上清除LCR的第7位。
7.2.4中断允许寄存器(IER)
IER控制UART产生的中断类型,一次可以允许一个或更多的中断,这依据编写中
断处理程序的方法而定。不论什么时候允许了一个中断,就必须采用一个特定的行为来清
除它。表7.4显示了寄存器位上所指定的中断以及需用来清除每个中断的合适行为。
表7.4中断允许寄存器
位 启 动 操 作
0 数据接收 读RDR
1 THR空 输出到THR
2 数据出错或中断 读LSR
3 MSR改变 读MSR
4~7 未用:总是设置为0
当表7.4中所示启动条件之一发生并且相应的IER设置为1时,中断就会产生。
7.2.5中断识别寄存器(IIR)
中断发生时通信程序能从IIR的位设置来识别该中断。表7.5列举了这些位的意义。
表7.5中断识别寄存器
位 意 义
0 已发生的中断超过1个
1~2 中断ID
3 中断ID(MsB~16550 UART独有;在其它UART上总是设置0)
4~5 未用;总是设置为0
6~7 FIFO缓冲允许标志(16550 UART独有;在其它UART上总是设置为0)
137页
如果软件是由中断驱动的,那么首先必须限定希望产生的中断的类型(参考表7.4)。
然后,接到一个中断请求后,必须检查IIR,看看发生的中断是哪种类型。表7.6指示用来
识别中断的三个位(8250和16450 UART只有第1位和第2位)的可能设置。
表7.6中断ID位设置
第三位 第二位 第一位 意义
0 0 0 MSR发生变化
0 0 1 THR空
1 1 0 接收FIFO字符超时
0 1 0 数据接收
0 1 1 数据接收出错或中断
7.2.6 FIFO控制寄存器(FCR)
16550 UART添加了一项功能,用于缓冲正在送出或接收的数据。该缓冲称为FI-
FO——(先进先出)。在UART的早期型号中,这种缓冲是没有用的。表7.7显示了该寄
存器各位的意义。
表7.7 FIFO控制寄存器
位 意义
0 允许和清除FIFO缓冲
1 接收重新设置的FIFO缓冲
2 传递重新设置的FIFO缓冲
3 DMA模式选择
4~5 保留
6 接收方触发器(LSB)
7 接收方触发器(MSB)
FCR的第6位及第7位用来指示应该用怎样的触发器水平来产生中断。这种水平即
是指示在中断产生之前,接收缓冲应该有多满。如果有快速中断设备途径,就可以设置高
水平触发器,并且较少中断主程序。表7.8显示了可能的触发器水平。
表7.8 FCR中断触发器水平
位 水平
00 1个字节
10 4个字节
01 8个字节
11 14个字节
7.2.7线控制寄存器(LCR)
它是串行线的主要控制寄存器。表7.9介绍该寄存器的位分配情况。
表7.9线控制寄存器
位 意义 设置 备注
0-1 字符长度
5个位 00
6个位 01
7个位 10
8个位 11
138页
位 意义 设置 备注
2 停止位
1个位 0
1.5个位 如果使用5位字符
2个位 1 如果使用6-、7-、8-位字符
3-5 奇偶性
16NORE 000
000 100
EVEN UA
MARK 101
SPACE 111
6 中断条件
禁止 0
许可 1
7 端口触发器
正常 0 使用THR/RDR和IER寄存器
可选的 1 使用BRDL和BRDH寄存器
7.2.8调制解调器控制寄存器(MCR)
MCR将控制线设置给调制解调器,并通过这些线告诉调制解调器计算机将要送出字
符,接收字符,或两者都要做。表7.10显示了该寄存器的位分配。
表7.10调制解调器控制寄存器
位 意义
0 设置DTR线活动
1 设置RTS线活动
2 用户输出#1(Hayes Reset)
3 用户输出#2(Enable Ints)
4 UART环路
5~7 未用;设置成零
数据终端就绪(DTR)线告诉调制解调器,计算机已打开并准备接收来自调制解调器
的信息。请求送出(RTS)线告诉解调器计算机准备向线上送出一些东西。平常情况下,可
以安全地将DTR和RTS都设置成1来打开这些线。一些解调器会忽视(或设置成会忽
视)这些信号,但;日式的解调器不会这样。第2位只能被特别的硬件(如Hayes SmartMo-
dem内部板,它使用第2位来重新设置解调器)所使用,并且应被初始化为0。第3位(用
户输出#2),它与UART的中断设备紧密结合在一起,如果它未设置成1,就会中断处
理。第4位允许对带有线上通信的程序进行测试。在这种环路状态下,送出端口的数据会
作为输入一样再次出现。
7.2.9线状态寄存器(LSR)
LSR会告知通信线的状态(见表7.11)。借助该寄存器,可以诊断通常的线路问题。
139页
表7.11线状态寄存器(LSR)
位 意 义
0 接收到的数据;RDR中的字节
1 因为下一个字节到达前,先前的字节还未被读取,就发生了超出错
2 奇偶性出错
3 传送不同步(字符读取后未发现停止位)而导致帧差错
4 中断探测
5 THR是空的;可以向线上输出一个字符
6 TSR空;TSR将来自THR的字符放在线上,每次放一个位
7 超时(在16450和16550 UART中总是设置成0)
7.2.10调制解调器状态寄存器(MSR)
调制解调器的状态决定于某个状态线是高还是低,以及自最后一个寄存器读取以后,
特定的线上的状态是否已发生了变化。表7.12显示了MSR中的位是如何分配的。
表7.12 MSR各位的意义
位 意 义
0 清除发送(CTS)发生变化
1 数据设置就绪(DsR)发生变化
2 环形指示器(RI)发生变化
3 数据携带者探测(DCD)发生改变
4 CTS设置为高电平
5 DSR设置为高电平
6 RI设置为高电平
7 DCD设置为高电平
调制解调器信号与连结计算机和串行设备的电信号线状态的改变相对应。依设备而
定,这些硬件信号可能用也可能不用。一些调制解调器没有利用它们而只是依赖Hayes命
令设置来处理通信。调制解调器(或其他串行设备)可能使用调制解调器信号,表7.13列
举了它们的意义。
表7.13调制解调器信号
信号 意 义
CTS 调制解调器准备接收来自计算机的字符。
DSR 调制解调器已打开并准备操作。
RI 电话线是环形的。因为线是环形的,所以RI保持高电
平,以便计算机能探测这些环线
DCD 调制解调器之间的联系
140页
7.3将通信端口初始化
直接与UART进行工作并没有看起来的那么容易。甚至初始化工作,也会变成一个
复杂的操作,它依赖于以正确的顺序来对寄存器排序,以便产生特定的效果。对于许多程
序(甚至那些打算直接访问UART的程序),不必直接初始化此芯片。可以通过目的是使
任务简单化的设计的BIOS功能来控制初始化过程。在这个编程领域(象其他地方一样),
并不需要做多少准备工作。
要访问对串行端口进行初始化的BIOS功能,将AH寄存器设置0,DX寄存器则设置
成代表将要初始化的通信端口的序号(从零开始计数,于是,0=COM1:,2=COM3:,3=
COM4:)。因为IBM BIOS的一些版本并非内在地支持4个通信端口,所以DX设置会只
限于0或1。而所有的PS/2系列都支持4个通信端口。
最后,将AL设置成所希望的初始化参数。表7.14列举了可能的AL设置。
表7.14 AL的BlOS通信端口初始化设置
位 意义 设置
0-1 字长
未用 00
未用 01
7个位 10
8个位 11
2 停止位
1个位 0
2个位 1
3~4 奇偶性
NONE 00
000 01
NONE 10
EVEN 11
5~7 位速率
110bps 000
150bps 001
300bps 010
600bps 011
1200Bps 100
2400bps 101
4800bpS 110
9600bps 111
在AH、AL和DX设置成必需的值以后,生成一个Int 14h,将通信端口根据所需规格
进行设置(有关BIOS功能所必需的寄存器设置,请见表7.17;有关该功能的进一步情况,
请参见第五部分“BIOS功能参考手册”一节的内容)。
141页
由表7.14可见,不能设置5个或6个位的数据长度,也不能设置低于110bps或高于
9600bps的位速率。对于某些应用程序,初始化选项是有限的。例如,当结合某个特殊化的
应用程序如NOAA天气信息时,它只有50bps和5位字长度,那么唯一的初始化选项就
是通过直接处理UART寄存器来对通信端口进行初始化。
IBM PS/2系列计算机,有另一个BIOS功能提供对通倍接口的一些附加的控制。要
访问此功能,可以将AH寄存器设置成4,而对于通常的BIOS功能,则可将DX寄存器设
置成代表需初始化的通信端口的值。然后,将AL设置成0或1,依据是否需要线上的中断
条件而定。通常,AL设置为0(没有中断)。BH必须设置成所需的奇偶性,如表7.15所示。
表7.15 BH(功能14/4)的奇偶性设置
设置 奇偶性意义
0 无
1 奇
2 偶
3 标记
4 SPACE
BL必须设置成所需的停止位的数字;0代表1个停止位,1代表1.5个(用于5位数
据长度)或2个停止位(用于6个、7个或8个位数据长度)。
CH中的数据长度是特定的,为5,比所需的数据位数校于是0代表5个数据位,3则
等于8个数据位。
最后,CL应设置成所需的位速率。位速率由表7.16中所列的设置而定。
表7.16 CL的位速率设置(功能14/4)
设置 位速率
本文地址:http://www.45fan.com/a/luyou/69076.html