深入浅出串口编程之DOS的串口编程Word格式文档下载.docx

上传人:b****1 文档编号:15394038 上传时间:2022-10-30 格式:DOCX 页数:11 大小:46.02KB
下载 相关 举报
深入浅出串口编程之DOS的串口编程Word格式文档下载.docx_第1页
第1页 / 共11页
深入浅出串口编程之DOS的串口编程Word格式文档下载.docx_第2页
第2页 / 共11页
深入浅出串口编程之DOS的串口编程Word格式文档下载.docx_第3页
第3页 / 共11页
深入浅出串口编程之DOS的串口编程Word格式文档下载.docx_第4页
第4页 / 共11页
深入浅出串口编程之DOS的串口编程Word格式文档下载.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

深入浅出串口编程之DOS的串口编程Word格式文档下载.docx

《深入浅出串口编程之DOS的串口编程Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《深入浅出串口编程之DOS的串口编程Word格式文档下载.docx(11页珍藏版)》请在冰豆网上搜索。

深入浅出串口编程之DOS的串口编程Word格式文档下载.docx

#defineSTR"

author:

sbh"

unionREGSinregs,outregs;

main()

{

 //设置串口参数

 init_rs232();

 //写串口的例子

 write_rs232(STR,strlen(STR));

 //读串口的例子

 read_rs232();

 return(0);

}

init_rs232()

{

 do{

  inregs.h.ah=0;

//AH=0表示初始化端口

  inregs.h.al=0xe7;

  inregs.x.dx=0;

//COM1

  int86(0x14,&

inregs,&

outregs);

 }while(outregs.h.ah>

=0x80);

write_rs232(char*string,intlen)

 inti;

  inregs.h.ah=1;

//发送AL寄存器的字符

  inregs.h.al=*string;

 }while(outregs.h.al>

 for(i=1;

i<

len;

i++)

 {

  inregs.h.al=*(string+i);

 }

read_rs232()

  inregs.h.ah=2;

//读取AL寄存器中的字符

 }while(outregs.h.al!

=3||outregs.h.ah>

  其中使用的int86函数的原型为:

int_Cdeclint86(intintno,unionREGS*inregs,unionREGS*outregs);

  int86()函数可以调用BIOS功能,现在的程序员们已经很少接触这个函数,80%的程序员甚至都未曾见过这个函数。

其实,在茹毛饮血的DOS时代,int86()函数几乎是最常用和最核心的函数之一。

几乎可以说,在那个时代,不会int86()就等于不会编程。

而与int86配合使用的,就是REGS这样一个联合体,定义为:

unionREGS{

 structWORDREGSx;

 structBYTEREGSh;

};

  其中的WORDREGS定义为:

structWORDREGS{

 unsignedintax,bx,cx,dx,si,di,

 cflag/*进位标志*/,

 flags/*标志寄存器*/;

  而BYTEREGS则定义为:

structBYTEREGS{

 unsignedcharal,ah,bl,bh,cl,ch,dl,dh;

  原来WORDREGS和BYTEREGS是16位的8086处理器内部的寄存器啊!

因此,当CPU发展到286、386以后,再安装DOS也是建立在利用CPU实模式的基础上的!

  另外一个函数与int86()的功能是类似的:

Int_Cdeclint86x(intintno,unionREGSinregs,unionREGSoutregs,structSREGSsegregs);

  其中的SREGS为段寄存器结构体,定义为:

structSREGS

 unsignedintes;

 unsignedintcs;

 unsignedintss;

 unsignedintds;

  int86和int86x这两个函数的功能都是执行一个由参数intno指定的8086软中断。

在执行软中断之前,两个函数都把inregs中的内容放置到各寄存器中(int86x还把segregs.x.es和segregs.x.ds的值存到相应的段寄存器中),软中断返回后,这两个函数都把当前寄存器的值存到outregs,并把系统进位标志拷贝到outregs.s.cflag中,把8086标志寄存器值存到outregs.x.flag中(int86x还恢复DS,并设置Segregs.es和Segregs.ds的值为对应段寄存器的值)。

  查阅BIOS中断调用手册,发现绝大多数调用都未用到ES和DS段寄存器,故在程序设计中经常只利用了int86函数。

2.硬件中断

  为了给读者一个直观的印象,我们通过在Windows操作系统中查看COM的资源属性获得某COM对应的中断号,如图2(该对话框中设备管理器中开启)。

图2COM中断号

  实际上COM的确直接对应于一个中断,而系统也按照一定的规律为各类硬件分配了一个较固定的中断号,如表1。

  表1中断向量表

INT(Hex)

IRQ

CommonUses

08

0

SystemTimer

09

1

Keyboard

0A

2

Redirected

0B

3

SerialComms.COM2/COM4

0C

4

SerialComms.COM1/COM3

0D

5

Reserved/SoundCard

0E

6

FloppyDiskController

0F

7

ParallelComms.

70

8

RealTimeClock

71

9

Reserved

72

10

73

11

74

12

PS/2Mouse

75

13

MathsCo-Processor

76

14

HardDiskDrive

77

15

Reserved

  通过编写COM对应的中断服务程序,我们也可以操作串口,涉及到的相关函数有:

  

(1)设置中断向量表

/*dos.h*/

void_Cdeclsetvect(intinterruptno,voidinterrupt(*isr)());

  例如,COM3对应的中断号是4,那么对应中断向量表中的地址是0x0C,设置0x0C对应中断程序的函数为:

setvect(0x0C,PORT1INT);

  其中的中断服务程序PORT1INT为:

voidinterruptPORT1INT()

 intc;

 do

  c=inportb(PORT1+5);

  if(c&

1)

  {

   buffer[bufferin]=inportb(PORT1);

   bufferin++;

   if(bufferin==1024)

    bufferin=0;

  }

 while(c&

1);

  outportb(0x20,0x20);

  上述中断服务程序检查是否有字符可接收,其后将其通过inportb(PORT1)语句将其从UART中读出并放入输入buffer。

持续的检查UART,以便能在一次中断里读取所有可获得的数据。

  最后的"

outportb(0x20,0x20);

"

语句告诉可编程中断控制器(ProgrammableInterruptController,PIC)中断已经完成。

  

(2)读取中断向量表

voidinterrupt(*_Cdeclgetvect(intinterruptno))();

  例如:

oldport1isr=getvect(INTVECT);

  其中的oldport1isr定义为:

voidinterrupt(*oldport1isr)();

  我们融合setvect()函数、中断服务程序和getvect()函数,给出一个由CraigPeacock编写的完备例程:

/*Name:

SampleComm'

sProgram-1024ByteBuffer-buff1024.c*/

/*WrittenBy:

CraigPeacock<

cpeacock@.au>

*/

conio.h>

#definePORT10x3F8/*PortAddressGoesHere*/

#defineINTVECT0x0C/*ComPort'

sIRQhere(MustalsochangePICsetting)*/

/*DefinesSerialPortsBaseAddress*/

/*COM10x3F8*/

/*COM20x2F8*/

/*COM30x3E8*/

/*COM40x2E8*/

intbufferin=0;

intbufferout=0;

charch;

charbuffer[1025];

voidinterrupt(*oldport1isr)();

voidinterruptPORT1INT()/*InterruptServiceRoutine(ISR)forPORT1*/

   {

   }

voidmain(void)

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

当前位置:首页 > 表格模板 > 书信模板

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

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