⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gserial.cpp

📁 使用C++编写的一个串口通信程序类
💻 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 + -