📄 comintr.cpp
字号:
/************************************************************
Defines a function as an interrupt handler.
interrupt <function-definition>(...) ;
All CPU registers are saved and the function is terminated with an IRET instruction.
When you use the interrupt keyword,
1.the Stack warning checkbox should be unchecked (off),
2.the Register Variables option should be set to None.
**************************************************************/
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <bios.h>
#define com1 0x3F8
#define com2 0x2F8
int COM=com2;
unsigned char bdh=0x00,bdl=0x0c;
unsigned char sbuf[100]; //发送缓冲区
unsigned char rbuf[20][100]; //接收缓冲区
unsigned char rbuf1[100]; //接收缓冲区
int ri=0,si=0,k=0,x=0;
int rif=0,sif=0,sif1=0;
float pra[4][4]={11,12,13,14,21,22,23,24};
//===================================================
void interrupt (*old_int_com1)(...); //老的通信中断程序
void interrupt (*old_int_com2)(...); //老的通信中断程序
void interrupt new_int(...) //自己的通信中断程序
{
unsigned char statue;
unsigned char ch;
do{ //COM2
statue=inp(COM+2); //读取中断标识寄存器
if(statue == 0x02) //是否为发送中断?
{
if(sif) { outp(COM,sbuf[si]);sif1=1;}
else sif1=0;
if(!sbuf[si]) sif=0;
si++;
}
if(statue == 0x04) //是否为接收中断?
{
ch=inp(COM);
if(ch==255) {ri=0;ch=254;}
rbuf[k][ri++]=ch;
if(!ch) {rbuf[k][0]=255;k++;ri=0;if(k>19) k=0;}
}
}while(inp(COM+2)!= 0x01); //是否还有中断?
outp(0x20,0x20); //通知8259中断处理结束
}
//===================================================
void send(unsigned char f1,unsigned char f2,float f3)
{
while(sif1);
sbuf[0]=255;
sbuf[1]=f1;
sbuf[2]=f2;
sprintf(&sbuf[3],"%6.1f",f3);
si=1;
sif=sif1=1;
outp(COM, sbuf[0]); //启动中断发送
}
//===================================================
void sendc(unsigned char f1)
{
while(sif1);
sbuf[0]=255;
sbuf[1]=f1;
sbuf[2]=0;
si=1;
sif=sif1=1;
outp(COM, sbuf[0]); //启动中断发送
}
//===================================================
void set_com()
{
asm cli //disable(); 关中断
setvect(0x0B, old_int_com2); //恢复老的中断向量
setvect(0x0C, old_int_com1); //恢复老的中断向量
if(COM==com2)
setvect(0x0B ,new_int ); //使新的中断向量指向自己的通信中断程序。
if(COM==com1)
setvect(0x0C ,new_int ); //使新的中断向量指向自己的通信中断程序。
outp(COM+3,0x80); //置DLAB=1,允许访问波特率因子寄存器
outp(COM,bdl); //写入波特率因子LSB,设置通信波特率=9600
outp(COM+1,bdh); //写入波特率因子MSB
outp(COM+3,0x03); //设置通信格式(无校验,停止位=1,数据位=8)
if(COM==com1)
outp(0x21, inp(0x21)&0xEF); //xxx0 xxxx,允许IRQ4中断请求COM1
if(COM==com2)
outp(0x21, inp(0x21)&0xF7); //xxxx 0xxx,允许IRQ3中断请求COM2
outp(COM+4,0x08); //设置MODEM控制寄存器,OUT2=1,
//允许8250产生的中断进入8259
outp(COM+1,0x03); //设置中断允许寄存器,允许发送、接收中断
asm sti //enable();开中断
clrscr();
textcolor(14);
cprintf("RS-232 communications (serial I/O) TEST V1.2 by Chen Jiaqi 2000\n");
printf("\n");
if(COM==com2)
printf("Com2 Test[B=9600,S=1,P=None]; Press [F5]->Com1;\n");
if(COM==com1)
printf("Com1 Test[B=9600,S=1,P=None]; Press [F5]->Com2;\n");
printf("Press [F1]->Send Pra. of Group 1; Press [F2]->Send Pra. of Group 2\n");
printf("Press [F3]->Get Pra. of Group 1; Press [F4]->Get Pra. of Group 2\n");
printf("Press [Esc]->Quit;\n");
}
//===================================================
void main()
{
int i,ch,j,comn=0;
union k{ char c[2]; int i; } key;
old_int_com1 =getvect(0x0C); //修改中断向量表(COM1:0CH, COM2:0BH)
old_int_com2 =getvect(0x0B); //修改中断向量表(COM1:0CH, COM2:0BH)
COM=com2; //Com2
set_com();
for(i=0;i<20;i++)
rbuf[i][0]=0;
for( ; ; )
{
for(i=0;i<20;i++)
{
if(rbuf[i][0]==255)
{
for(j=0;j<100;j++)
rbuf1[j]=rbuf[i][j];
rif=1;
rbuf[i][0]=0;
break;
}
}
if(rif)
{
i=0;
do{
printf("%d,",rbuf1[i++]);
}while(rbuf1[i-1]);
switch(rbuf1[1])
{
case 1:
switch(rbuf1[2])
{
case 1:
printf("[No.1.1 %6.1f],",pra[0][0]=atof(&rbuf1[3]));
break;
case 2:
printf("[No.1.2 %6.1f],",pra[0][1]=atof(&rbuf1[3]));
break;
case 3:
printf("[No.1.3 %6.1f],",pra[0][2]=atof(&rbuf1[3]));
break;
case 4:
printf("[No.1.4 %6.1f],",pra[0][3]=atof(&rbuf1[3]));
break;
}
break;
case 2:
switch(rbuf1[2])
{
case 1:
printf("[No.2.1 %6.1f],",pra[1][0]=atof(&rbuf1[3]));
break;
case 2:
printf("[No.2.2 %6.1f],",pra[1][1]=atof(&rbuf1[3]));
break;
case 3:
printf("[No.2.3 %6.1f],",pra[1][2]=atof(&rbuf1[3]));
break;
case 4:
printf("[No.2.4 %6.1f],",pra[1][3]=atof(&rbuf1[3]));
break;
}
break;
case 11:
send(1,1,pra[0][0]);
send(1,2,pra[0][1]);
send(1,3,pra[0][2]);
send(1,4,pra[0][3]);
break;
case 21:
send(2,1,pra[1][0]);
send(2,2,pra[1][1]);
send(2,3,pra[1][2]);
send(2,4,pra[1][3]);
break;
}
printf("\n");
rif=0;
}
if(kbhit())
{
key.i=bioskey(0);
if(key.c[0]==27) break; //按Esc键退出!
if(key.c[0]=='q'||key.c[0]=='Q') break;//按Q键退出!
if(!key.c[0])
switch(key.c[1])
{
case 59: //F1: Send Pra. of Group 1
send(1,1,pra[0][0]);
send(1,2,pra[0][1]);
send(1,3,pra[0][2]);
send(1,4,pra[0][3]);
printf("Send Pra. of Group 1 = Ok!\n");
break;
case 60: //F2: Send Pra. of Group 2
send(2,1,pra[1][0]);
send(2,2,pra[1][1]);
send(2,3,pra[1][2]);
send(2,4,pra[1][3]);
printf("Send Pra. of Group 2 = Ok!\n");
break;
case 61: //F2: Get Pra. of Group 1
sendc(11);
printf("Send command (Get Pra. of Group 1) = Ok!\n");
break;
case 62: //F2: Get Pra. of Group 2
sendc(21);
printf("Send command (Get Pra. of Group 2) = Ok!\n");
break;
case 63: //F5: Com1<->Com2
if(comn=!comn)
{
COM=com1; //Com1
set_com();
}
else
{
COM=com2; //Com2
set_com();
}
break;
}
}
}
asm cli //disable();
outp(COM+1,0x00); //设置中断允许寄存器,关闭发送、接收中断
outp(COM+4,0x00); //关闭8250产生的中断进入8259
if(COM==com2)
outp(0x21, inp(0x21) | 0x08); //xxxx 1xxx,关闭IRQ3中断请求COM2
if(COM==com1)
outp(0x21, inp(0x21) | 0x10); //xxx1 xxxx,关闭IRQ4中断请求COM1
setvect(0x0B, old_int_com2); //恢复老的中断向量
setvect(0x0C, old_int_com1); //恢复老的中断向量
asm sti //enable();
}
//===================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -