在本组程序中,函数setinterrupt()和clearinterrupt()设置和恢复串行通信中断向量;cominit()初始化指定串行口并开放相应中断;sendcomdata()和getcomeomdata()用于发送和接收数据串;com1()和com2()为中断例程,二者均调用fax2()函数,fax2()函数为实际处理数据接收和发送的例程。明确了串行口的工作原理,就不难理解其具体程序。
3。结论
上述程序采用C语言编写,在BORLANDC++2。0集成环境中调试通过,为简单起见,只考虑了使用发送/接收两条信号线的情况,并未考虑使用握手信号线。
在实际应用中这两组程序尚有一些可修改之处。比如,中断接收程序中的缓冲区可改为循环表,以防数据溢出,尽可能保留最新数据。由于笔者水平所限,文中不足疏漏之处尚希行家指正。
程序1:
staticintreceive_delay=10000;
intmay(unsignedpar,char*comm,char*ss)
{intcs=0,j=0;
char*p;
bioscom(0,par,0);//com1
loop:p=comm;
inportb(0x3f8);//reset
do{while((inportb(0x3f8+5)&0x20)==0);outportb(0x3f8,*p++);
}while(*p);//sendcommand
os=0;j=0;
do{if((inportb(0x3fd)&0x01)==0)
if(os〉receive_delay)break;
else{cs++;
continue;}ss[j++]=inportb(0x3f8);cs=0;
}while(l);
ss[j]=“0;
if(j)return0;
elsereturn1;
程序2:
#includestdio。h
#includestdlib。h
#includestring。h
#includebios。h
#inoludedos。h
#definemaxsize4096
#defineSEND2
#defineRECEIVE1
#defineCOM10
#defineCOM21
staticunsignedcharHardinterrupt=0;
structComInterrupt
{intportadd;
intintbit;
charbuf[maxsize],*comm;
intbufh,recount,sendcount;
}com={{0x3f8,0x0c,,,0,0,0},
{0x2f8,0x0b,,,0,0,0}};
voidstaticinterrupt(*old_com)(void);
voldinterruptcoml(vold);
voidinterruptcom2(void);
voidfax2(intcomnum);
voidsetinterrupt(intcomnum);
voidclearinterrupt(intcomnum);
voidcominit(intcomnum,intpara,intinterruptmark);
voidsendcomdata(intcomnum,char*command);
intgetcomdata(intcomnum,char*buf);
voidinterruptcom1(void)
{fax2(0);}
voidinterruptcom2(void)
{fax2(1);}
//setcominterrupt,comnum0=com1,1=com2
voidsetinterrupt(intcomnum)
{
old_com[comnum]=getvect(com[comnum]。intbit);
if(!oomnum)
setvect(com[comnum]。intbit,coml);//com1
else
setvect(com[comnum]。intbit,com2);//com2
//sethardint
Hardinterrupt=inportb(0x21);
if(comnum)
outportb(0x21,Hardinterrupt&0xf7);//com2,0
else
outportb(0x21,Hardinterrupt&0xef);//com10,
}
voidclearinterrupt(intcomnum)
{
if(comnum)
outportb(0x21,Hardinterrupt|0x08);//COM2
else
outportb(0x21,Hardinterrupt|0x10);//COM1
setvect(com[comnum]。intbit,old_com[comnum]);
for(i=0;imaxsize;i++)com[comnum]。buf[i]=“0;
com[comnum]。sendcount=com[comnum]。recount=com[comnum]。bufh=0;
outportb(com[comnum]。portadd+1,0);
outportb(com[comnum]。portadd+4,0x0);
}
voidfax2(inti)//i=o,com1;i=1,com2
{unsignedcharmark;
mark=inport(com[i]。portadd+2);
do
{
if(mark&0x4)//receivedata
{if(com[i]。bufh==maxsize)
com[i]。bufh=0;com[i]。buf[com[i]。bufh++]=inportb(com[i]。portadd);com[
i]。recount++;}
elseif(mark&0x2)//sendcommand
{if(*com[i]。comm)
outportb(com[i]。p
ortadd,*com[i]。comm++);
com[i],sendcount++;}
else
outportb(com[i]。portadd+1,1);
}
}while((mark=inport([1]。portadd+2))!=1);
outportb(ox20,0x20);//hardintreturn
}
//interruptmark1=reoeive,2=send,3=rec&send
voidcomint(intcom,charpara,intinterruptmark)
{
bioscom(0,par,com);
//opencominterrupt
outportbv(com[comnum]。portadd+4,0x8;
outportb(com[comnum]。portadd+1,interruptmark);
}
voidsendcomdata(intcomnum,char*command)
{unsignedcharinterruptmark;
com[comnum],comm=command;
com[comnum],sendcount=0;
//setsendinterrupt
interruptmark=inportb(com[comnum]。portadd_1);
outportb(com[comnum]。portadd+1。(interruptmark|2));
}
//getcom_receivedateandclearcom_receivebuf,(责任编辑:一枝笔写作)