微机原理课程设计报告书两台PC机之间进行串口通信.docx

上传人:b****3 文档编号:3504401 上传时间:2022-11-23 格式:DOCX 页数:16 大小:50.09KB
下载 相关 举报
微机原理课程设计报告书两台PC机之间进行串口通信.docx_第1页
第1页 / 共16页
微机原理课程设计报告书两台PC机之间进行串口通信.docx_第2页
第2页 / 共16页
微机原理课程设计报告书两台PC机之间进行串口通信.docx_第3页
第3页 / 共16页
微机原理课程设计报告书两台PC机之间进行串口通信.docx_第4页
第4页 / 共16页
微机原理课程设计报告书两台PC机之间进行串口通信.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

微机原理课程设计报告书两台PC机之间进行串口通信.docx

《微机原理课程设计报告书两台PC机之间进行串口通信.docx》由会员分享,可在线阅读,更多相关《微机原理课程设计报告书两台PC机之间进行串口通信.docx(16页珍藏版)》请在冰豆网上搜索。

微机原理课程设计报告书两台PC机之间进行串口通信.docx

微机原理课程设计报告书两台PC机之间进行串口通信

一、课程设计题目

两台PC机之间进行串口通信。

二、课程设计目的与要求

通过本次实训,加强学生们对微机原理与接口技术这门课程的理解和掌握,同时了解并掌握8250串口芯片和中断管理芯片8259的初始化编程和使用。

1.目的:

俩个PC机通过串行口互联,实现文件的无差错传输。

2.基本要求:

(1)PC机使用8250串口芯片。

中断管理芯片使用8259 

(2)要求用C语言或汇编语言完成程序的设计。

(3)程序必须用中断方式来实现。

(4)在U盘上自备TURBOC2.0编译环境。

因为机房的计算机(C和D盘要还原)安装有还原卡。

(5)自购DB9P公插头二个,2,3脚交叉连线,5脚直接连接,焊接。

电缆长度一米。

(6)不准带电拔插串行口插头。

三、实现方法

1.8250的初始化依据

8250(16550)的寄存器如下表所示:

基地址

读/写

寄存器缩写

注释

0

Write

-

发送保持寄存器(DLAB=0)

0

Read

-

接收数据寄存器(DLAB=0)

0

Read/Write

-

波特率低八位(DLAB=1)

1

Read/Write

IER

中断允许寄存器

1

Read/Write

-

波特率高八位(DLAB=1)

2

Read

IIR

中断标识寄存器

2

Write

FCR

FIFO控制寄存器

3

Read/Write

LCR

线路控制寄存器

4

Read/Write

MCR

MODEM控制寄存器

5

Read

LSR

线路状态寄存器

6

Read

MSR

MODEM状态寄存器

7

Read/Write

-

ScratchRegister

PC机支持1-4个串行口,即COM1-COM4,其基地址在BIOS数据区0000:

0400-0000:

0406中描述,对应地址分别为3F8/2F8/3E8/2E8,COM1及COM3使用PC机中断4,COM2及COM4使用中断3。

  在上表中,8250共有12个寄存器,使用了8个地址,其中部分寄存器共用一个地址,由DLAB=0/1来区分,在DLAB=1用于设定通讯所需的波特率。

常用的波特率参数见下表:

 

速率(BPS)

波特率高八位

波特率低八位

50

09h

00h

300

01h

80h

600

00h

C0h

2400

00h

30h

4800

00h

18h

9600

00h

0Ch

19200

00h

06h

38400

00h

03h

57600

00h

02h

115200

00h

01h

以下几个表格为8250的寄存器的功能描述:

  中断允许寄存器(IER):

注释

7

未使用

6

未使用

5

进入低功耗模式(16750)

4

进入睡眠模式(16750)

3

允许MODEM状态中断

2

允许接收线路状态中断

1

允许发送保持器空中断

0

允许接收数据就绪中断

  Bit0置1将允许接收到数据时产生中断,Bit1置1时允许发送保持寄存器空时产生中断,Bit2置1将在LSR变化时产生中断,相应的Bit3置位将在MSR变化时产生中断。

  中断识别寄存器(IIR):

注释

Bit6:

7=00

无FIFO

Bit6:

7=01

允许FIFO,但不可用

Bit6:

7=11

允许FIFO

Bit5

允许64字节FIFO(16750)

Bit4

未使用

Bit3

16550超时中断

Bit2:

1=00

MODEM状态中断(CTS/RI/DTR/DCD)

Bit2:

1=01

发送保持寄存器空中断

Bit2:

1=10

接收数据就绪中断

Bit2:

1=11

接收线路状态中断

Bit0=0

有中断产生

Bit0=1

无中断产生

IIR为只读寄存器,Bit6:

7用来指示FIFO的状态,均为0时则无FIFO,此时为8250或16450芯片,为01时有FIFO但不可以使用,为11时FIFO有效并可以正常工作。

Bit3用来指示超时中断(16550/16750)。

  Bit0用来指示是否有中断发生,Bit1:

2标识具体的中断类型,这些中断具有不同的优先级别,其中LSR中断级别最高,其次是数据就绪中断,然后是发送寄存器空中断,而MSR中断级别最低。

  FIFO控制寄存器(FCR):

注释

Bit7:

6=00

1Byte产生中断

Bit7:

6=01

4Byte产生中断

Bit7:

6=10

8Byte产生中断

Bit7:

6=11

14Byte产生中断

Bit5

允许64字节FIFO

Bit4

未使用

Bit3

DMA模式选择

Bit2

清除发送FIFO

Bit1

清除接收FIFO

Bit0

允许FIFO

  FCR可写但不可以读,该寄存器用来控制16550或16750的FIFO寄存器。

Bit0置1将允许发送/接收的FIFO工作,Bit1和Bit2置1分别用来清除接收及发送FIFO。

清除接收及发送FIFO并不影响移位寄存器。

Bit1:

2可自行复位,因此无需使用软件对其清零。

Bit6:

7用来设定产生中断的级别,发送/接收中断将在发送/接收到对应字节数时产生。

  线路控制寄存器(LCR):

注释

Bit7=1

允许访问波特率因子寄存器

Bit7=0

允许访问接收/发送及中断允许寄存器

Bit6

设置间断,0-禁止,1-设置

Bit5:

3=XX0

无校验

Bit5:

3=001

奇校验

Bit5:

3=011

偶校验

Bit5:

3=101

奇偶保持为1

Bit5:

3=111

奇偶保持为0

Bit2=0

1位停止位

Bit2=1

2位停止位(数据位6-8位),1.5位停止位(5位数据位)

Bit1:

0=00

5位数据位

Bit1:

0=01

6位数据位

Bit1:

0=10

7位数据位

Bit1:

0=11

8位数据位

  LCR用来设定通讯所需的一些基本参数。

Bit7为1指定波特率因子寄存器有效,为0则指定发送/接收及IER有效。

Bit6置1会将发送端置为0,这将会使接收端产生一个“间断”。

Bit3-5用来设定是否使用奇偶校验以及奇偶校验的类型,Bit3=1时使用校验,Bit4为0则为奇校验,1为偶校验,而Bit5则强制校验为1或0,并由Bit4决定具体为0或1。

Bit2用来设定停止位的长度,0表示1位停止位,为1则根据数据长度的不同使用1.5-2位停止位。

Bit0:

1用来设定数据长度。

  MODEM控制寄存器(MCR):

注释

Bit7

未使用

Bit6

未使用

Bit5

自动流量控制(仅16750)

Bit4

环路测试

Bit3

辅助输出2

Bit2

辅助输出1

Bit1

设置RTS

Bit0

设置DSR

  MCR寄存器可读可写,Bit4=1进入环路测试模式。

Bit3-0用来控制对应的管脚。

  线路状态寄存器(LSR):

注释

Bit7

FIFO中接收数据错误

Bit6

发送移位寄存器空

Bit5

发送保持寄存器空

Bit4

间断

Bit3

帧格式错

Bit2

奇偶错

Bit1

超越错

Bit0

接收数据就绪

  LSR为只读寄存器,当发生错误时Bit7为1,Bit6为1时标示发送保持及发送移位寄存器均空,Bit5为1时标示仅发送保持寄存器空,此时,可以由软件发送下一数据。

当线路状态为0时Bit4置位为1,帧格式错时Bit3置位为1,奇偶错和超越错分别将Bit2及Bit1置位为1。

Bit0置位为1表示接收数据就绪。

  MODEM状态寄存器(MSR):

注释

Bit7

载波检测

Bit6

响铃指示

Bit5

DSR准备就绪

Bit4

CTS有效

Bit3

DCD已改变

Bit2

RI已改变

Bit1

DSR已改变

Bit0

CTS已改变

  MSR寄存器的高4位分别对应MODEM的状态线,低4位表示MODEM的状态线是否发生了变化。

以上我们详细介绍了PC机的串行通讯硬件环境,以下将分别给出使用查询及中断驱动的方法编写的串行口驱动程序。

这些程序仅使用RXD/TXD,无需硬件握手信号。

2.程序源代码和部分注释

#include

#include

#include

#include

#include

#defineSER_RBR0/*接收缓冲寄存器RBR(读)DLAB=0*/

#defineSER_THR0/*发送保持寄存器THR(写)DLAB=0*/

#defineSER_IER1/*中断允许寄存器IER(读/写)DLAB=0*/

#defineSER_IIR2/*中断识别寄存器IIR(读)*/

#defineSER_LCR3/*通信线路控制寄存器LCR(读/写)*/

#defineSER_MCR4/*Model控制寄存器MCR(读/写)*/

#defineSER_LSR5/*通信线路状态寄存器LSR(读)*/

#defineSER_MSR6/*Modem状态寄存器MSR(读)*/

#defineSER_DLL0/*除数锁存器(波特率低8位)DLL(读/写)DLAB=1*/

#defineSER_DLH1/*除数锁存器(波特率高8位)DLH(读/写)DLAB=1*/

/*8250使用1.8432MHz的基准时钟输入,所以除数=1843200/(B*16)*/

#defineSER_BAUD_120096/*波特率为1200时,波特率因子(除数)为96*/

#defineSER_BAUD_240048/*波特率为2400时,波特率因子(除数)为48*/

#defineSER_BAUD_960012/*波特率为9600时,波特率因子(除数)为12*/

#defineSER_BAUD_192006/*波特率为19200时,波特率因子(除数)为6*/

#defineCOM_10x3F8/*COM1口8250内部寄存器基地址*/

#defineCOM_20x2F8/*COM2口8250内部寄存器基地址*/*/

#defineCOM_30x3E8/*COM3口8250内部寄存器8250基地址*/

#defineCOM_40x2E8/*COM4口8250内部寄存器8250基地址*/

#defineSER_STOP_10/*1位停止位*/

#defineSER_STOP_24/*2位停止位*/

#defineSER_BITS_50/*5位数据位*/

#defineSER_BITS_61/*6位数据位*/

#defineSER_BITS_72/*7位数据位*/

#defineSER_BITS_83/*8位数据位*/

#defineSER_PARITY_NONE0/*无校验*/

#defineSER_PARITY_ODD8/*奇校验*/

#defineSER_PARITY_EVEN24/*偶校验*/

#defineSER_DIV_LATCH_ON128/*DLAB=1*/

#definePIC_IMR0x21/*中断屏蔽寄存器*/

#definePIC_ICR0x20/*中断控制寄存器*/

#defineINT_SER_PORT_00x0C/*COM1与COM3中断向量编号*/

#defineINT_SER_PORT_10x0B/*COM2与COM4中断向量编号*/

/*函数声明*/

voidinterruptfarSerial_Isr();

voidinterruptfarSerial_File();

Open_Serial(intport_base,intbaud,intconfiguration);

Close_Serial(intport_base);

/*全局变量定义,可在各函数间传递参数*/

voidinterruptfar(*Old_Isr)();/*Old_Isr保存原来的串口中断向量*/

intold_int_mask;/*保存原来的中断屏蔽寄存器的值*/

intopen_port;/*当前打开的串口编号*/

unsignedchars[80];intj=0;

charch=0;

intdone=0;

main()

{

charpress;

chari;

charfname[80];

charfn[80];

/*初始化COM1端口*/

Open_Serial(COM_1,SER_BAUD_1200,SER_PARITY_EVEN|SER_BITS_8|SER_STOP_1);

printf("com:

1;bps:

1200;parity:

even;bits:

8;stopbit:

1");

printf("pressanykeytobeginsending\n");

enable();/*开中断*/

memset(s,0,sizeof(s));//初始化s为零,指针指向s

while

(1)

{

printf("SerialCommunication\n");

printf("1.SendChar\n");

printf("2.AcceptChar\n");

printf("3.SendFile\n");

printf("4.AcceptFile\n");

printf("5.Exit\n");

printf("pleaseselectnumber!

\n");

i=getch();

printf("%c\n",i);

switch(i)

{

case'1':

printf("pleaseenterachar:

\n");

press=getch();

Serial_Write(press);

break;

case'2':

Serial_Isr();

break;

case'3':

printf("Pleaseenterthefilenametobesent:

\n");

scanf("%s",&fname);

Serial_Write_File(fname);

break;

case'4':

printf("Pleaseenterthefilenametopreserve:

\n");

scanf("%s",&fn);

Serial_File(fn);

break;

case'5':

exit(0);

Close_Serial(COM_1);/*关闭串口COM1*/

break;

default:

printf("error!

!

!

");

break;

}

}

}

/*-----------初始化串口---------------*/

Open_Serial(intport_base,intbaud,intconfiguration)

{

open_port=port_base;

disable();/*关闭中断*/

outp(port_base+SER_LCR,SER_DIV_LATCH_ON);/*DLAB=1*/

outp(port_base+SER_DLL,baud);/*通过设置波特率因子来确定波特率*/

outp(port_base+SER_DLH,0);

outp(port_base+SER_LCR,configuration);/*通信方式设定,同时DLAB=0*/

outp(port_base+SER_IER,1);/*允许接收数据就绪中断,关闭其它中断*/

if(port_base==COM_1||port_base==COM_3)

{/*保存串口1、3原来的中断向量,以便在退出程序时恢复*/

Old_Isr=getvect(INT_SER_PORT_0);

/*为串口设置新的中断向量,在发生中断时就会调用执行用户所指定的中断服务程序*/

setvect(INT_SER_PORT_0,Serial_Isr);

printf("\nOpeningComPort#1/3...\n");

}

else

{

/*功能与上面的代码类似,只是处理的对象是串口2、4*/

Old_Isr=getvect(INT_SER_PORT_1);

setvect(INT_SER_PORT_1,Serial_Isr);

printf("\nOpeningComPort#2/4...\n");

}

old_int_mask=inp(PIC_IMR);/*读入中断屏蔽寄存器的值*/

/*对应位为0则允许该中断,允许3(串口1中断)、4(串口2中断)而不影响其它中断的屏蔽状态*/

outp(PIC_IMR,(port_base==COM_1)?

(old_int_mask&0xEF):

(old_int_mask&0xF7));

enable();/*允许中断*/

}

/*-------------关闭串口--------------*/

Close_Serial(intport_base)

{

outp(port_base+SER_MCR,0);

outp(port_base+SER_IER,0);/*禁止所有串口中断*/

outp(PIC_IMR,old_int_mask);/*恢复原来的中断屏蔽状态*/

if(port_base==COM_1)

{

setvect(INT_SER_PORT_0,Old_Isr);/*恢复原来的串口中断向量*/

printf("\nClosingComPort#1.\n");

}

else

{

setvect(INT_SER_PORT_1,Old_Isr);

printf("\nClosingComPort#2.\n");

}

}

/*--------------写串口-----------------*/

Serial_Write(charch)

{

while(!

(inp(open_port+SER_LSR)&0x20)){}/*如串口不空闲,则循环等待*/

disable();/*当上面条件不等,说明串口空闲,退出循环*/

outp(open_port+SER_THR,ch);/*开始发送数据*/

enable();/*开中断*/

}

/*-------------写文件----------------*/

Serial_Write_File()

{

FILE*fp;

while(!

(inp(open_port+SER_LSR)&0x20)){}/*如串口不空闲,则循环等待*/

disable();

fp=fopen(fname,"rb");

if(fp==NULL)

{

printf("Failuretoopenthefile!

\n");

return;

}

while((ch=fgetc(fp))!

=eof())

{

outp(open_port+SER_THR,ch);

}

fclose(fp);

enable();

}

/*-------------串口中断服务程序-----------------*/

voidinterruptfarSerial_Isr()

{

charch;

intx=inp(0x3fd);//读出线路状态寄存器的值给变量X

intj=1;

disable();

while(j<5)

{

x=inp(0x3fd);

if((x&0x01)==1)

{

ch=inp(0x3F8);/*开始接受数据*/

s[j]=ch;

printf("%d----%c\n",j,ch);

j++;

j=j%50;

}

}

j=1;

enable();

outp(PIC_ICR,0x20);

main();/*写入OCW2,向8259发普通EOI指令*/

}

voidinterruptfarSerial_File()

{

FILE*p;

charch;

intx=inp(0x3fd);

intj=1;

p=fopen(fn,"w");//用写入的方式打开当前目录名为fn的文件

disable();

while(j<1000)//从1循环到999

{

x=inp(0x3fd);//再次读出变化后的线路状态寄存器的值给变量X

if((x&0x01)==1)

{

ch=inp(0x3F8);/*开始接受数据*/

s[j]=ch;//将值给数组s[j]j在循环

fputc(ch,p);/*将ch中的字符输出到p指针中,也就是文件fn中*/

j++;

j=j%50;

}

}

j=1;

enable();

outp(PIC_ICR,0x20);

fclose(fp);/*写入OCW2,向8259发普通EOI指令*/

}

3.程序流程图

 

 

四.实训体会

经过一个星期的上机实践学习,使我对微机原理与接口技术这门课程有了更进一步的认识和了解,要想学好它要重在实践,要通过不断的对硬件操作才能更好地学习它,通过实践,我也发现我的好多不足之处,首先是自己在编程上比较差,对一些函数的认识和运用还不是很熟悉,其中曾遇到过很多问题,不过通过这次学习也有所改进;再有对8250的一些寄存器不太了解。

通过实践,使我在这几个方面的认识有所提高。

通过实践的学习,我认到学好计算机要重视实践操作,不仅仅是学习微机原理这门课程,还是其它的课程,以及其它的计算机方面的知识都要重在实践,所以后在学习过程中,我会更加注视实践操作,使自己便好地学好计算机。

备注:

由于设计的时间比较短暂,程序功能不是很完善,请老师批评指正!

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 农学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1