上图就是西门子品牌的电传打字机,怎么样,帅吧。还是拆了看下里面的电路板吧,你要是有兴趣的话,还可以找一找串口在哪里。
时光荏苒,个人计算机出现了,这些已有的串口设备毫无疑问地成为了最初的外设,自然而然地rs232标准被个人计算机采纳。但是设备制造商倾向于体积更小,成本更低的接口,因此,将db25中未使用的和支持同步模式的引脚去掉,形成db9。
最初的情况相当混乱,因为db9只定义了信号,却没有指定信号和引脚的对应关系,各个制造商只能自行定义。幸运的是,ibm的pc成了工业标准,db9逐渐统一到ibm的定义上来。
db9只有9根线,遵循rs232标准。定义如下:
dtr,dsr------dte设备准备好/dce设备准备好。主流控信号。
rts,cts------请求发送/清除发送。用于半双工时,收发切换。属于辅助流控信号。半双工的意思是说,发的时候不收,收的时候不发。那么怎么区分收发呢?缺省时是dce向dte发送数据,当dte决定向dce发数据时,先有效rts,表示dte希望向dce发送,一般dce不能马上转换收发状态,dte就通过监测cts是否有效来判断可否发送,这样避免了dte在dce未准备好时发送所导致的数据丢失。
全双工时,这两个信号一直有效即可。
后来,计算机普及了,很多非rs232的串口也要接入pc机,如果为每一种新出现的串口都增加一个新的i/o口显然不现实,因为pc后面板位置有限,因此,将rs232串口和非rs232串口都通过rs232口接入是最佳方案。uart的u(通用)指的就是这个意思。
早期rom bios和dos里的通信软件都是为rs232设计的,在没有检测到dcd有效前不会发送数据,因此,就连发送一个字符这样朴素的应用也要给出dcd、dtr、dsr等控制信号。因此,串口接头上要将一些控制线短接,或者干脆绕过系统软件自己写通信程序。
下面给出一个当年的dos下编写的串口驱动,大家体会下串口的具体操作过程。
#include <stdio.h>
#include "dos.h"
#include "conio.h"
#define bufflen 1024
void initcom();/* 初始化串口 */
void openport();/* 打开串口 */
void closeport();/* 关闭串口,释放串口资源 */
void interrupt asyncint();/* 新的中断函数 */
void interrupt(*asyncoldvect)();/* 中断向量:用于保护中断现场 */
unsigned char buffer[bufflen];
int buffin = 0;
int buffout = 0;
void openport()
{
unsigned char uctemp;
initcom();
asyncoldvect = getvect(0x0c);
disable();
inportb(0x3f8);
inportb(0x3fe);
inportb(0x3fb);
inportb(0x3fa);
outportb(0x3fc, 0x08|0x0b);
outportb(0x3f9, 0x01);
uctemp = inportb(0x21)&0xef;
outport(0x21, uctemp);
setvect(0x0c, asyncint);
enable();
}
void interrupt asyncint()
{
buffer[buffin++] = inportb(0x3f8);
if(buffin >= bufflen) buffin = 0;
outportb(0x20, 0x20);
}
void closeport(void)
{
disable();
outportb(0x3f9, 0x00);
outportb(0x3fc, 0x00);
outportb(0x21, inportb(0x21)&0x10);
enable();
setvect(0x0c, asyncoldvect);
}
void initcom()
{
outportb(0x3fb, 0x80);
outportb(0x3f8, 0x0c);/* 波特率设置为9600 */
outportb(0x3f9, 0x00);
outportb(0x3fb, 0x03);
outportb(0x3fc, 0x08|0x0b);
outportb(0x3f9, 0x01);
}
unsigned char read_char(void)
{
unsigned unch;
if(buffout != buffin)
{
unch = buffer[buffout];
buffout++;
if(buffout >= bufflen) buffout = 0;
return(unch);
}
else
return(0xff);
}
void send_char(unsigned char unch)
{
while(((inp(0x3f8+5)) & 0x40) ==0);
outportb(0x3f8, unch);
}
void main()
{
unsigned char unchar;
short bexit_flag = 0;
openport();
fprintf(stdout, "\n\nready to receive data\n"
"press [sec] to quit...\n\n");
do
{
if(kbhit())
{
unchar = getch();
switch(unchar)
{
case 0x1b:
bexit_flag = 1;
break;
}
if(!bexit_flag)
send_char(unchar);
}
unchar = read_char();
if(unchar!= 0xff)
{
fprintf(stdout,"%c", unchar);
}
}while(!bexit_flag);
closeport();
}
就在uart冠以通用二字,准备一统江湖的时候,制造商们不满于它的速度、体积和灵活性(软件可配置),推出了usb和1394串口。目前,台式机和笔记本上的uart串口有被取消的趋势,有串口的计算机主板已经是凤毛麟角了,因而有资深的网友发出了“没有串口,吾谁与归”的慨叹,古今多少事,都付笑谈中,usb取代uart是后话,暂且不表。