2机通信接口与通信课程设计.docx
《2机通信接口与通信课程设计.docx》由会员分享,可在线阅读,更多相关《2机通信接口与通信课程设计.docx(20页珍藏版)》请在冰豆网上搜索。
2机通信接口与通信课程设计
一.原理介绍
1.设计目的:
设计一套系统,要求能在两台计算机之间以中断方式和查询方式实现串行通信,数据可以采用ASCII字符方式和二进制方式传送。
2、串行口的有关硬件资料和实现方法:
(1).线路控制寄存器(口地址3FBH/2FBH)
D7
D6
D5
D4
D3
D2
D1
D0
字长选择位0
字长选择位1
停止位个数位
奇偶校验允许位
偶校验选择位
跟随校验
断线检测
分频门闩位(DLAB)
其中:
D4D3奇偶校验D2停止位D1D0字长
X0无校验01005
01奇11.5(字长为5位时)016
11偶12(字长6,7,8位时)107
118
(2).线路状态寄存器(3FDH/2FDH)
D7
D6
D5
D4
D3
D2
D1
D0
接收数据准备好(RDA
超时错
奇偶校验错
贞错
线路中断
发送保持寄存器空(TBE)
发送移位寄存器空
≡0
(3).中断允许寄存器(3F9H/2F9H,且DLAB=0)
D7
D6
D5
D4
D3
D2
D1
D0
允许接收寄存器好中断
允许发送保持寄存中断
允许线路故障中断
允许Modem中断
=0
=0
=0
=0
(4).MODEM控制寄存器(3FCH/2FCH)
D7
D6
D5
D4
D3
D2
D1
D0
数据终端准备好(DTR)
请求发送(RTS)
OUT1
OUT2
返环
=0
=0
=0
(5).MODEM状态寄存器(3FEH/2FEH)
D7
D6
D5
D4
D3
D2
D1
D0
CTS位发生改变
DSR位发生改变
收到震铃指示后沿
线路信号测试
清除发送
数据装置准备好
震铃指示
接收线路载波检测
二.连接说明
1、9芯RS-232C接口标准:
1.引脚1:
CD,载体检测;
2.引脚2:
RXD,接收数据;
3.引脚3:
TXD,发送数据;
4.引脚4:
DTR,终端准备好;
5.引脚5:
信号地;
6.引脚6:
DSR,DODEM准备好;
7.引脚7:
RTS:
请求发送;
8.引脚8:
CTS:
清除发送;
9.引脚9:
RI:
响玲指示;
2、当通信距离较近时,可不需要Modem,通信双方可以直接连接,这种情况下,只需使用少数几根信号线。
最简单的情况,在通信中根本不需要RS-232C的控制联络信号,只需三根线(发送线、接收线、信号地线)便可实现全双工异步串行通信。
下面是零MODEM的最简单接法。
单接法(3线接法)
图中的2号线与3号线交叉连接是因为在直连方式时,把通信双方都当作数据终端设备看待,双方都可发也可收。
在这种方式下,通信双方的任何一方,只要请求发送RTS有效和数据终端准备好DTR有效就能开始发送和接收。
3、设计所需的设备有IBM-PC机,RS-232C插座与连线。
此设计是利用接口RS-232C来实现两机通讯。
通过8250芯片来控制COM1和COM2端口来传输和接收数据。
(在IBM-PC中,COM1与COM2都是RS-232C接口)。
三.程序流程图
程序说明和源码
主程序
voidmain()
{
charc;
intkey=1;
while(key)
{
clrscr();
printf("\n");
printf("\t\t1.Sendstrings\n\n");
printf("\n");
printf("\t\t2.Receivestrings\n\n");
printf("\n");
printf("\t\t3.Sendfile\n\n");
printf("\n");
printf("\t\t4.Receivefile\n\n");
printf("\n");
printf("\t\t5.Exit\n\n");
printf("\n\n\t\t\Pleasechoose:
");
scanf("%c",&c);
switch(c)
{
case'1':
clrscr();
P8250();
sendChar();
break;
case'2':
clrscr();
P8250();
receiveChar();
break;
case'3':
clrscr();
P8250();
sendFile();
break;
case'4':
clrscr();
P8250();
receiveFile();
break;
case'5':
key=0;
}
}
}
程序运行界面:
由截图中可看到有4个功能选项
1、发送字符串
2、接收字符串
3、发送文件
4、接收文件
5、退出程序
初始化8250的程序段
voidP8250()
{
outportb(0x2FB,0x80);
outportb(0x2F8,0x01);
outportb(0x2F9,0x00);
outportb(0x2FB,0x0B);
outportb(0x2F9,0x00);
outportb(0x2FC,0x03);
}
发送字符,接收字符:
voidsendChar()/*发送字符*/
{
intkey=1;
charch;
printf("Input:
");
while(key)
{
Lsend();
ch=getch();
printf("%c",ch);
if(ch!
=13)
{
outportb(0x2F8,ch);
}
else
{
printf("\n\n\t\tSendcompleted!
\n");
Lsend();
outportb(0x2F8,'\n');
key=0;
getch();
}
}
}
voidreceiveChar()/*接收字符*/
{
charch;
printf("\t\t\nreceivestring:
");
Lreceive();
ch=inportb(0x2F8);
while(ch!
='\n')
{
printf("%c",ch);
Lreceive();
ch=inportb(0x2F8);
}
printf("\n\t\tReceivecomplete!
\n");
getch();
}
发送之前查询发送寄存器是否为空,输入字符不是回车符继续发送,发送字符到发送寄存器
发送之前查询发送寄存器是否为空,输入字符不是回车符继续发送,发送字符到发送寄存器
发送文件和接收文件
voidsendFile()/*发送文件*/
{
FILE*fp;
charbuf[SIZE];
charch;
longlength[4];
charfilename[20];
longfilesize;
longsize;
intt,i=0;
printf("\nFilename:
");
scanf("%s",filename);
for(t=0;t<20;t++)
{
Lsend();
outport(0x2f8,filename[t]);
}
if((fp=fopen(filename,"rb+"))==NULL)
printf("\t\tCann'topenthefile!
\n");
filesize=getFilesize(fp);
size=filesize;
Lsend();
printf("\t\tfilesize=%3.2fkb\n",filesize*1.0/1024);
outportb(0x2F8,'S');
length[0]=filesize>>24;
length[1]=filesize<<8;
length[1]=length[1]>>24;
length[2]=filesize<<16;
length[2]=length[2]>>24;
length[3]=filesize<<24;
length[3]=length[3]>>24;
Lsend();
for(i=0;i<4;i++)
{
Lsend();
outportb(0x2F8,length[i]);
}
Lreceive();
Msign=inportb(0x2F8);
while(Msign!
='y')
{
Lreceive();
Msign=inportb(0x2F8);
}
printf("\t\tsendingfile....\n");
while(size>SIZE)
{
fread(buf,SIZE,1,fp);
for(i=0;i{
Lsend();
outportb(0x2F8,buf[i]);
}
size-=SIZE;
Lsend();
outportb(0x2F8,'?
');
Lreceive();
ch=inportb(0x2F8);
if(ch!
='!
')
{
fseek(fp,SIZE,SEEK_CUR);
size+=SIZE;
}
}
if(size>0)
{
fread(buf,size,1,fp);
for(i=0;i{
Lsend();
outportb(0x2F8,buf[i]);
}
}fclose(fp);
printf("\n\t\tSendcompleted!
");
getch();
}
以二进制方式打开文件,获得文件大小,发送等待,发送开始字符,发送文件开始的握手信号,首先发送文件长度,通过移位把32位的数据截成4个8位数据,发送文件长度大小给接收方,发送等待,发送文件的大小,发送文件长度结束,接收等待,如果接方创建文件失败,则返回一个信息给发送方,接收等待,开始发送文件,每发16k字节发一个字母当校验用,把文件的16k字节读到缓存,发送文件,文件大小减少16k,发送一个标志'?
'用于检查接收方是否已经接收完16k字节,接收等待,如果对方发送回来提示效检字节错,则重发16k字节,文件指针前移16k字节把剩余的不到16k的字节发送完,关闭文件.
voidreceiveFile()/*接收文件*/
{
intt,j=0;
FILE*fp;
charbuf[SIZE];
charch,w;
charfilepath[20];
charfilename[20];
longsize;
longlength[4];
printf("\n\t\tDoyouwanttoreceivefile:
");
for(t=0;t<20;t++)
{
Lreceive();
ch=inportb(0x2f8);
filename[t]=ch;
if((ch>='0'&&ch<='9')||(ch>='A'&&ch<='z')||(ch=='.'))printf("%c",ch);
}
printf("\n\t\tYesorNo(y/n)?
");
ch=getch();
if(ch!
='Y'&&ch!
='y')
{
printf("\n\t\tRefusethefiletranslation");
getch();
return;
}
Lreceive();
Msign=inportb(0x2F8);
while(Msign!
='S')
{
Lreceive();
Msign=inportb(0x2F8);
}
printf("\n\t\tGetthesizeofthefile!
\n");
for(j=0;j<4;j++)
{
Lreceive();
length[j]=inportb(0x2F8);
}
length[0]=length[0]<<24;
length[1]=length[1]<<16;
length[2]=length[2]<<8;
size=length[0]|length[1]|length[2]|length[3];
printf("\t\tThereceivingfile'ssizeis:
%3.2fkb\n",size*1.0/1024);
printf("\n\t\tDoyouwanttorenamefile?
(y/n)\n");
w=getch();
if(w=='Y'&&ch=='y')
{
printf("\n\n\tInputfile:
");
scanf("%s",filepath);
if((fp=fopen(filepath,"wb"))==NULL)
printf("\n\t\tCann'topenthefile%s!
",filepath);
}
else{if((fp=fopen(filename,"wb"))==NULL)
printf("\n\t\tCann'topenthefile%s!
",filepath);
}
Lsend();
outportb(0x2F8,'y');
printf("\n\t\tStartreceive\n");
printf("Receiving................");
while(size>SIZE)
{
printf("Receiving................");
for(j=0;j{
Lreceive();
buf[j]=inportb(0x2F8);
}
Lreceive();
if(inportb(0x2F8)=='?
')
{
fwrite(buf,j,1,fp);
size-=SIZE;
Lsend();
outportb(0x2F8,'!
');
}
else
{
Lsend();
outportb(0x2F8,0x00);
}
}
if(size>0)
{
for(j=0;j{
Lreceive();
buf[j]=inportb(0x2F8);
}
fwrite(buf,j,1,fp);
}
clrscr();
printf("\n\n\t\tReceivecompleted!
");
getch();
fclose(fp);
}
首先是是否接受文件选项,计算文件的大小,是否重命名,如果创建文件成功就发送一个字符'y'给发送方,循环接收16k字节,接收文件数据,当接收到一个标志'?
'时,表示已经接收完16k字节,把接收的数据写到文件中,发送等待,发送一个标志'!
'用于答复发送方已经把16k数据写入了文件中,当没有接收到一个标志'?
'时,表示需要重发刚才的16k字节,接收完剩下的不到16k的字节,写到文件中,接收完成
六、心得体会
通过此次串口通信实验,使我掌握了用RS-232C的零MODEM连接法实现两机通讯的基本原理,熟悉了Intel8250的初始化方式和传送信息的方法。
刚开始做的时候不知道从哪方面着手,将各个功能模块拼凑起来之后,问题相当的严重,之后很多问题都是自己查书和慢慢调试一点一滴解决,通过这次实验,使我对接口通信方面的开发和调试获益良多。
通过了这次的课程设计,使我对计算机的串行接口和收发信息有了比较深入的了解,增加了我对借口通讯的浓烈兴趣。
尤其是通过编程对各芯片有了深刻的理解,逐步摸清各个寄存器的工作原理,再对其编程。
调试时,发现各个功能都不够好,无论发送字符还是发送文件都时常出现错误,但通过不断的考虑修改最终搞好了。
发掘了其中的乐趣,但其中还是有许多的不足,不尽人意的地方。