📄 gserial.cpp
字号:
/*------------------------------------------------------------------*
GSERIAL.CPP
Edited by Gong jianwei http://www.gjwtech.com
For asynchronous serial port communications
适用于DOS环境下异步串口通信编程 多串口控制程序
ATTENTION: Compile this program with Test Stack Overflow OFF.
在Turbo C++3.0中选项设置 Options/Compiler/Entry中关闭Test Stack Overflow
*------------------------------------------------------------------*/
#include "GSerial.h"
#include <dos.h>
#include <stdio.h>
GSerial gsCOM1;//gsCOM2; //定义两个GSerial对象
unsigned char senddata1[15];
//unsigned char Senddata2[5];
unsigned char frame1[35];
int i=0;
//int j=0;
struct COMPORT_VAR{
unsigned char inbuf[IBUF_LEN]; // in buffer
unsigned char outbuf[OBUF_LEN]; // out buffer
unsigned int startbuf ;
unsigned int endbuf ;
unsigned int inhead ;
unsigned int intail ;
unsigned int outhead ;
unsigned int outtail ;
unsigned int PortBase ;
};
COMPORT_VAR comport1,comport2;
//////////////////////////////////GSerial////////
GSerial::GSerial()
{
}
GSerial::~GSerial()
{
}
//* get status of the port */
int GSerial::ReadStatus(void)
{
return(inp(m_unPortBase+5));
}
/* send one valid char from the port */
void GSerial::SendChar(unsigned char unCh)
{
while ((ReadStatus() & 0x40) == 0);
outportb(m_unPortBase,unCh);
}
void GSerial::SendCommand(void)
{
char c;
unsigned char *unChBuf;
unsigned char cmd1[3]={0xef,0x21,0x11};
unsigned char cmd2[3]={0xef,0x21,0x22};
unsigned char cmd3[3]={0xef,0x21,0x33};
if(kbhit())
{
c=getch();
switch(c)
{
case 'a':
GSerial::SendString(3,cmd1);
//GSerial::SendChar(0x11);
break;
case 'b':
GSerial::SendString(3,cmd2);
break;
case 'c':
//unChBuf=cmd3;
GSerial::SendString(3,cmd3);
//GSerial::SendChar(0x33);
break;
}
}
}
/* send one string from the port */
void GSerial::SendString(int nStrlen, unsigned char *unChBuf)
{
int k=0;
do {
SendChar(*(unChBuf + k));
k++;
} while ((k < nStrlen));
}
/* Install our functions to handle communications */
void GSerial::SetVects(void interrupt(*New_Int)(...))
{
disable();
OldVects = getvect(InterruptNo[m_unPortNo-1]);
setvect(InterruptNo[m_unPortNo-1], New_Int);
enable();
}
/* Uninstall our vectors before exiting the program */
void GSerial::ResetVects(void)
{
setvect(InterruptNo[m_unPortNo-1], OldVects);
}
/* Tell modem that we're ready to go */
void GSerial::CommOn(void)
{
int temp;
disable();
//temp = inportb(m_unPortBase + MCR) | MCR_INT;
//outportb(m_unPortBase + MCR, temp);
outportb(m_unPortBase + MCR, MCR_INT);
//temp = inportb(m_unPortBase + MCR) | MCR_DTR | MCR_RTS;
//outportb(m_unPortBase + MCR, temp);
temp = (inportb(m_unPortBase + IER)) | IER_RX_INT;//|IER_TX_INT;
outportb(m_unPortBase + IER, temp);
temp = inportb(PIC8259_IMR) & ComIRQ[m_unPortNo-1];
outportb(PIC8259_IMR, temp);
enable();
}
/* Go off-line */
void GSerial::CommOff(void)
{
int temp;
disable();
temp = inportb(PIC8259_IMR) | ~ComIRQ[m_unPortNo-1];
outportb(PIC8259_IMR, temp);
outportb(m_unPortBase + IER, 0);
outportb(m_unPortBase + MCR, 0);
enable();
}
/* Set the port number to use */
int GSerial::SetPortBaseAddr(int Port)
{
if((Port<1)||(Port>6))
return(-1);
m_unPortNo = Port;
m_unPortBase = PortBaseAddr[m_unPortNo-1];
return (0);
}
/* This routine sets the speed; will accept funny baud rates. */
/* Setting the speed requires that the DLAB be set on. */
int GSerial::SetSpeed(int Speed)
{
char c;
int divisor;
if (Speed == 0) /* Avoid divide by zero */
return (-1);
else
divisor = (int) (115200L/Speed);
if (m_unPortBase == 0)
return (-1);
disable();
c = inportb(m_unPortBase + LCR);
outportb(m_unPortBase + LCR, (c | 0x80)); /* Set DLAB */
outportb(m_unPortBase + DLL, (divisor & 0x00FF));
outportb(m_unPortBase + DLH, ((divisor >> 8) & 0x00FF));
outportb(m_unPortBase + LCR, c); /* Reset DLAB */
enable();
return (0);
}
/* Set other DATA Format communications parameters */
int GSerial::SetDataFormat(int Parity, int Bits, int StopBit)
{
int setting;
if (m_unPortBase == 0)
return (-1);
if (Bits < 5 || Bits > 8)
return (-1);
if (StopBit != 1 && StopBit != 2)
return (-1);
if (Parity != LCR_NO_PARITY && Parity != LCR_ODD_PARITY && Parity != LCR_EVEN_PARITY)
return (-1);
setting = Bits-5;
setting |= ((StopBit == 1) ? 0x00 : 0x04);
setting |= Parity;
disable();
outportb(m_unPortBase + LCR, setting);
enable();
return (0);
}
void GSerial::CloseSerialPort(void)
{
CommOff();
ResetVects();
}
/* Set up the port */
int GSerial::InitSerialPort(int Port, int Speed, int Parity, int Bits, int StopBit)
{
int flag = 0;
if (SetPortBaseAddr(Port))
flag = -1;
if (SetSpeed(Speed))
flag = -1;
if (SetDataFormat(Parity, Bits, StopBit))
flag = -1;
return(flag);
}
////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////COM1//////////////////////////////////////////////////////////
void interrupt ComIntServ_comport1(...)
{
int temp;
disable();
temp = (inportb(comport1.PortBase+IIR)) & IIR_MASK; // why interrupt was called
switch(temp)
{
case 0x00: // modem status changed
inportb(comport1.PortBase+MSR); // read in useless char
break;
case 0x02: // Request To Send char
if (comport1.outhead != comport1.outtail) // there's a char to send
{
outportb(comport1.PortBase+TXR,comport1.outbuf[comport1.outhead++]); // send the character
if (comport1.outhead == OBUF_LEN)
comport1.outhead=0; // if at end of buffer, reset pointer
}
break;
case 0x04: // character ready to be read in
//inbuf[inhead++] = inportb(m_unPortBase+RXR);// read character into inbuffer
comport1.inbuf[comport1.inhead] = inportb(comport1.PortBase+RXR);// read character into inbuffer
comport1.inhead++;
if (comport1.inhead == IBUF_LEN) // if at end of buffer
comport1.inhead=0; // reset pointer
break;
case 0x06: // line status has changed
inportb(comport1.PortBase+LSR); // read in useless char
break;
default:
break;
}
outportb(PIC8259_ICR, PIC8259_EOI); // Signal end of hardware interrupt
enable(); // reenable interrupts at the end of the handler
}
//COM1 串口1
//char ReadChar_comport1(void)
//{
// char ch;
// if (comport1.inhead != comport1.intail) // there is a character
// {
// disable(); // disable irqs while getting char
// ch = comport1.inbuf[comport1.intail++]; // get character from buffer
// if (comport1.intail ==IBUF_LEN) // if at end of in buffer
// comport1.intail=0; // reset pointer
// enable(); // re-enable interrupt
// return(ch);
// }
// ch = -1;
// return(ch); // return nothing
//}
unsigned char ReadChar_comport1(void)
{
unsigned char ch;
if (comport1.inhead != comport1.intail) // there is a character
{
disable(); // disable irqs while getting char
ch = comport1.inbuf[comport1.intail++]; // get character from buffer
if (comport1.intail ==IBUF_LEN) // if at end of in buffer
comport1.intail=0; // reset pointer
enable(); // re-enable interrupt
return(ch);
}
else
return(0xff); // return nothing
}
/*中断接收数据帧*/
void ReceiveDataFrame()
{
unsigned char ch;
do
{
ch=ReadChar_comport1();
if(ch!=0xff)
{
frame1[i]=ch;
i++;
gsCOM1.SendCommand();
//delay(50);
//c = ReadChar_comport2();
//if (c != -1) //'-1' is the END signal of a string
//{
//fprintf(stdout,"[COM2:RX]: %c\n",c);
//gsCOM2.SendChar( c );
//gsCOM2.SendString(int nStrlen, unsigned char *unCharBuf );
//fprintf(stdout,"[COM2:TX]: %c\n",c);
//}
// } while ((!done) && (!SError));
}
}while (i==36);
}
/*对数据帧进行处理并重新组帧*/
void ProcessDataFrame()
{
int l=19,k;
for(k=0;k<16;k++)
{
senddata1[k]=frame1[l];
l++;
}
}
void SaveData1()
{
FILE *fp1;
fp1=fopen("E:\\bc45\\gtdata.dat","ab+");
for(i=0;i<35;i++)
{
fwrite(frame1,1,35,fp1);
}
fclose(fp1);
}
void SaveData2()
{
FILE *fps;
fps=fopen("E:\\bc45\\sdata.dat","ab+");
for(i=0;i<35;i++)
{
fwrite(senddata1,1,15,fps);
}
fclose(fps);
}
////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////COM2//////////////////////////////////////////////////////////
void interrupt ComIntServ_comport2(...)
{
int temp;
disable();
temp = (inportb(comport2.PortBase+IIR)) & IIR_MASK; // why interrupt was called
switch(temp)
{
case 0x00: // modem status changed
inportb(comport2.PortBase+MSR); // read in useless char
break;
case 0x02: // Request To Send char
if (comport2.outhead != comport2.outtail) // there's a char to send
{
outportb(comport2.PortBase+TXR,comport2.outbuf[comport2.outhead++]); // send the character
if (comport2.outhead == OBUF_LEN)
comport2.outhead=0; // if at end of buffer, reset pointer
}
break;
case 0x04: // character ready to be read in
//inbuf[inhead++] = inportb(m_unPortBase+RXR);// read character into inbuffer
comport2.inbuf[comport2.inhead] = inportb(comport2.PortBase+RXR);// read character into inbuffer
comport2.inhead++;
if (comport2.inhead == IBUF_LEN) // if at end of buffer
comport2.inhead=0; // reset pointer
break;
case 0x06: // line status has changed
inportb(comport2.PortBase+LSR); // read in useless char
break;
default:
break;
}
outportb(PIC8259_ICR, PIC8259_EOI); // Signal end of hardware interrupt
enable(); // reenable interrupts at the end of the handler
}
//COM2 串口2
char ReadChar_comport2(void)
{
char ch;
if (comport2.inhead != comport2.intail) // there is a character
{
disable(); // disable irqs while getting char
ch = comport2.inbuf[comport2.intail++]; // get character from buffer
if (comport2.intail == IBUF_LEN) // if at end of in buffer
comport2.intail=0; // reset pointer
enable(); // re-enable interrupt
return(ch); // return the char
}
ch = -1;
return(ch); // return nothing
}
///////
main()
{
FILE *fp1,*fp2,*fps;
/* Communications parameters */
comport1.startbuf =0;
comport1.endbuf =0;
comport1.inhead =0;
comport1.intail =0;
comport1.outhead =0;
comport1.outtail =0;
comport1.PortBase =0;
comport2.startbuf =0;
comport2.endbuf =0;
comport2.inhead =0;
comport2.intail =0;
comport2.outhead =0;
comport2.outtail =0;
comport2.PortBase =0;
int port = COM1;
int speed = 9600;
int parity = LCR_NO_PARITY;
int bits = 8;
int stopbits = 1;
int done = FALSE;
unsigned char ch;
int temp;
int SError=0;
int m=0;
int n=0;
int frameindex;
// unsigned char Senddata1[15];
//unsigned char Senddata2[5];
// unsigned char frame1[35];
// int i=0;
//int k=100;
// int j=0;
int Strlen;
// GSerial gsCOM1;//gsCOM2; //定义两个GSerial对象
//初始化COM1,串口1
if (!gsCOM1.InitSerialPort(port, speed, parity, bits, stopbits))
{
comport1.PortBase = PortBaseAddr[port-1];
gsCOM1.SetVects(ComIntServ_comport1);
gsCOM1.CommOn();
}
// else
// SError=2;
//初始化COM2,串口2
//port = COM2;
// if (!gsCOM2.InitSerialPort(port, speed, parity, bits, stopbits))
//{
// comport2.PortBase = PortBaseAddr[port-1];
// gsCOM2.SetVects(ComIntServ_comport2);
// gsCOM2.CommOn();
// }
// else
//SError=2;
//void ReadData_comport1();
//打印串口地址及中断向量地址
fprintf(stdout, "\nCOM%d, PortBase=0X%x, IntVect=0X%x\n\n",
gsCOM1.m_unPortNo,gsCOM1.m_unPortBase,ComIRQ[gsCOM1.m_unPortNo-1]);
//fprintf(stdout, "\nCOM%d, PortBase=0X%x, IntVect=0X%x\n\n",
//gsCOM2.m_unPortNo,gsCOM2.m_unPortBase,ComIRQ[gsCOM2.m_unPortNo-1]);
fprintf(stdout, "Now we are ready to go: \n\n");
// do
// {
// ch=ReadChar_comport1();
//if (c!= -1) //'-1' is the END signal of a string
// if(ch!=0xff)
// {
// fp=fopen("E:\\bc45\\Rdata1.dat","ab+");
// fputc(ch,fp);
// }
// gsCOM1.SendCommand();
//delay(50);
//c = ReadChar_comport2();
//if (c != -1) //'-1' is the END signal of a string
//{
//fprintf(stdout,"[COM2:RX]: %c\n",c);
//gsCOM2.SendChar( c );
//gsCOM2.SendString(int nStrlen, unsigned char *unCharBuf );
//fprintf(stdout,"[COM2:TX]: %c\n",c);
//}
// } while ((!done) && (!SError));
ReceiveDataFrame();
ProcessDataFrame();
SaveData1();
SaveData2();
//关闭打开的串口
//gsCOM1.CloseSerialPort();
//gsCOM2.CloseSerialPort();
/* Check for errors */
//switch (SError)
//{
//case NO_ERROR: fprintf(stderr, "\nbye.\n");
// return (0);
//case BUF_OVFL: fprintf(stderr, "\nBuffer Overflow.\n");
// return (99);
//case 2: fprintf(stderr,"\n Cannot init serial port");
// return(2);
//default: fprintf(stderr, "\nUnknown Error, SError = %d\n",
// SError);
// return (99);
//}
//} while ((!done) && (!SError));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -