#include
#include
#include
#define BUFFLEN 1024 //缓冲区大小
unsigned int COMIR=0x0c; //COM1产生的硬件中断号为IR4,对应的中断向量为0ch,附:COM2产生的硬件中断号为IR3,对应的中断向量为0bh
unsigned int COM=0x3f8; //COM1的端口地址为3f8h
long BPS=9600; //波特率的值,初始波特率为9600bps
unsigned char MSB=0x00; //波特率除数寄存器的值,初始波特率为9600bps
unsigned char LSB=0x0c;
void InitCOM(); //初始化串口
void OpenPort(); //打开串口
void ClosePort(); //关闭串口,释放串口资源
unsigned char ReadData(); //接收数据
void SendData(unsigned char unch); //发送数据
void ReadStr(); //接收字符
void SendStr(); //发送字符
void SendFile(); //发送文件
void ReadFile(); //接收文件
//新的中断函数
void interrupt far asyncint();
//中断向量:用于保存中断现场
void interrupt(*asyncoldvect)();
unsigned char Buffer[BUFFLEN];
int buffin=0;
int buffout=0;
//打开COM
void OpenPort()
{
unsigned char ucTemp;
InitCOM(); //初始化串口
//读入由参数给定的中断向量值,并将它作为中断函数的远地址
asyncoldvect=getvect(COMIR);
disable(); //关中断
outportb(COM+4,0x0b);
outportb(COM+1,0x01);
ucTemp=inportb(0x21)&0xe7; //读出OCW1的操作命令字,8259复位原先的IR3,IR4的状态
outportb(0x21,ucTemp);
setvect(COMIR,asyncint); //置中断向量类型asyncint
enable(); //开中断
}
//中断服务程序,从COM接收数据
void interrupt far asyncint()
{
Buffer[buffin++] = inportb(COM);// 读字符到缓冲区
if (buffin >= BUFFLEN) // 缓冲区满
buffin=0; // 指针复位
outportb(0x20,0x20); //中断结束命令,8259在普通EOI结束方式下结束
}
void ClosePort() //关闭串口
{
disable(); //关中断
outportb(COM+1,0x00); //屏蔽8250所有中断
outportb(COM+4,0x00); //OUT1,OUT2,DTR,RTS信号无效
outportb(0x21,inportb(0x21)&0x18); //8259屏蔽原先的IR3,IR4的状态
enable();
setvect(0x0c,asyncoldvect); //恢复原来的中断向量
}
void InitCOM()// 对COM串口初始化,设置串口参数
{
outportb(COM+3,0x80); //将设置波特率
outportb(COM,LSB);
outportb(COM+1,MSB);
outportb(COM+3,0x03); //8个数据位,1个停止位、无奇偶校验
outportb(COM+4,0x0b); //OUT2,DTR,RTS信号有效
outportb(COM+1,0x0f); //允许8250所有中断
}
unsigned char ReadData() //接收数据
{
unsigned char unch;
if(buffout != buffin)
{
unch = Buffer[buffout];
buffout++;
if(buffout >= BUFFLEN)
buffout=0;
return(unch);
}
else
return(0xff);
}
void SendData(unsigned char unch) //发送数据
{
while ((inportb(0x21)&0x18)==0x18); //读出OCW1的操作命令字,判断IR3,IR4的状态
while (((inportb(COM+5))&0x40)==0); //判断发送移位寄存器是否就绪,就绪才发送数据
outportb(COM,unch);
}
void ReadStr() //接收字符
{
unsigned char unChar;
int bExit_Flag=0;
OpenPort(); //打开串口
fprintf(stdout, "\n\nReady to Read String\n"
"press [ESC] to quit...\n\n");
do {
if (kbhit()) //检测是否有按键按下
if(getch()==0x1b) //ESC的ASCII值为1bh
{
bExit_Flag=1; //退出
break;
}
unChar=ReadData(); //从缓冲区中读数
if (unChar != 0xff)
{
putchar(unChar);
}
} while (!bExit_Flag);
ClosePort(); //关闭串口
}
void SendStr()
{
unsigned char unChar;
int bExit_Flag=0;
OpenPort(); //打开串口
fprintf(stdout, "\n\nReady to Send String\n"
"press [ESC] to quit...\n\n");
do {
if (kbhit()) //检测是否有按键按下
{
unChar=getch();
if(unChar==0x1b) //ESC的ASCII值为1bh
{
bExit_Flag=1; //退出
break;
}
else
{
printf("%c",unChar);
SendData(unChar); //发送键入的字符
}
}
} while (!bExit_Flag);
ClosePort(); //关闭串口
}
void SendFile() //发送文件函数
{
int i;
FILE *fp;
int bExit_Flag=1;
unsigned char unChar;
unsigned char fname[30];
clrscr();
printf("\t *** Send File.... ***\n\nPlease input the filename:");
scanf("%s",fname);
if((fp=fopen(fname,"rb"))==NULL) //出错判断:无法读取文件
{
printf("\nError can't open the file!\n");
getch();
return;
}
OpenPort();
for(i=0;fname[i]!='\0';i++) //发送文件名
{
SendData(fname[i]);
}
SendData('\0'); //文件名发送结束符号
do
{
unChar=ReadData();
}while(unChar==0xff);//判断接收准备字符,等待发送数据
if(unChar!='-')
{
printf("\nError! Can't send the file!\n");
bExit_Flag=0;
getch();
}
else
{ //SendData('*');//发送开始标志
while(1)
{
if(fread(&unChar,1,1,fp)==1)SendData(unChar); //发送1字节文件
else
{
if(feof(fp))
break;
printf("\nfile read error\n");
getch();
bExit_Flag=0;
break;
}
}
}
fclose(fp); //关闭文件
unChar=0xfe;
SendData(unChar); //文件发送完毕符号
unChar=0x9e;
SendData(unChar);
unChar=0xcc;
SendData(unChar);
unChar=0x88;
SendData(unChar);
if(bExit_Flag)printf("\nSend file OK!");
getchar();
ClosePort(); //关闭串口
}
void ReadFile() //接收文件函数
{
int i=0;
FILE *fp;
int bExit_Flag=1;
unsigned char unChar;
unsigned char unChar1;
unsigned char unChar2;
unsigned char unChar3;
unsigned char fname[30];
clrscr();
printf("Receive file...\n");
buffin=0; //初始化缓冲区
buffout=0;
OpenPort();
do //接收文件名
{
if(i>=30)
{
printf("\nfilename is error!");
return;
}
unChar=ReadData();
if(unChar fname[i++]=unChar;
}while(fname[i-1]!='\0');
printf("\nfilename is %s! Are you receive?(Y/N)\n",fname);
scanf("%c",&unChar);
getchar();
if(unChar!='Y'&&unChar!='y')
{
SendData('N');
return;
}
printf("\nfilename is %s! Are you rename file?(Y/N)\n",fname);
scanf("%c",&unChar);
getchar();
if(unChar=='Y'||unChar=='y')
{
scanf("%s",fname);
getchar();
}
if((fp=fopen(fname,"wb"))==NULL) //出错判断:无法打开文件
{
printf("\nError can't open the file!\n");
SendData('N');
getchar();
return;
}
buffin=0; //初始化缓冲区
buffout=0;
SendData('-');
while(1)
{
if(buffout != buffin)
{
unChar = Buffer[buffout%BUFFLEN]; //解密
unChar1 = Buffer[(buffout+1)%BUFFLEN];
unChar2 = Buffer[(buffout+2)%BUFFLEN];
unChar3 = Buffer[(buffout+3)%BUFFLEN];
buffout++;
if(buffout >= BUFFLEN)
buffout=0;
if(unChar==0xfe&&unChar1==0x9e&&unChar2==0xcc&&unChar3==0x88)break; //文件接收完毕
if(fwrite(&unChar,1,1,fp)!=1) //接收1字节文件
{
printf("\nfile read error\n");
bExit_Flag=0;
break;
}
}
}
fclose(fp); /*关闭文件*/
if(bExit_Flag)printf("\nReceive file OK!\n");
getchar();
ClosePort(); //关闭串口
}
void main()
{
int i,j;
char ch;
unsigned int bp;
unsigned long bp1;
do
{
clrscr();
printf("**********************************************************************\n");
printf("* The connection between two PC port:COM%d %6lubps *\n",COM==0x3f8?1:2,BPS);
printf("**********************************************************************\n");
printf("* 1.Read String *\n");
printf("* 2.Read File *\n");
printf("* 3.Send String *\n");
printf("* 4.Send File *\n");
printf("* 5.Set COM *\n");
printf("* 6.Set COM BPS *\n");
printf("* 0.exit *\n");
printf("**********************************************************************\n");
printf("Please choose the method that you want to use(1-6):");
scanf("%d",&i);
printf("\n");
getchar();
switch(i)
{
case 1:
ReadStr();
break; /*发送字符*/
case 2:
ReadFile();
break; /*发送文件*/
case 3:
SendStr();
break; /*接收字符*/
case 4:
SendFile();
break; /*接收文件*/
case 5:
clrscr();
printf("**********************************************************************\n");
printf("* Choose the COM *\n");
printf("**********************************************************************\n");
printf("* 1.COM1 *\n");
printf("* 2.COM2 *\n");
printf("* 3.exit *\n");
printf("**********************************************************************\n");
printf("Please choose the method that you want to use(1-3):");
scanf("%d",&j);
getchar();
printf("\n");
switch(j)
{
case 1:
COMIR=0x0c;
COM=0x3f8;
break; /*选用COM1串口*/
case 2:
COMIR=0x0b;
COM=0x2f8;
break; /*选用COM2串口*/
case 3: break;
default: printf("Error!\n");
}
break;
case 6:
printf(" Enter the Seriec COM BPS(eg:2400):");
scanf("%lu",&BPS);
getchar();
bp1=115200/BPS; //获取波特率寄存器预置数
bp=bp1;
MSB =bp>>8; //将预置数分解为高8位与低8位
LSB =bp&0x00ff;
break;
case 0: exit(0); /*退出操作界面*/
default: printf("Error!\n");
}
printf("\nDo you want to continue ?( y:continue ; otherkey:exit )");
printf("\n");
ch=getchar();
}
while(ch=='y'||ch=='Y');
}