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

📄 sercomm.cpp

📁 dos 下的串口通讯程序
💻 CPP
字号:
#include <dos.h>

#include "SerComm.h"

void interrupt(*oldvects[2])(...);
void interrupt com1_int(...);
void interrupt com2_int(...);

class ComClass
{
public:	
	ComClass(const int comPortVal);

	void comInt(void);	
	void sendChar(const char ch);
	int  receiveChar(char *ch);
	void comOff(void);
	int  setCom(const int baud, const int para);
	void comMainRun(void);
	
private:
	int comPort;
	int comBase;
	int comIRQ;
	int comVect;
	int comOldVect;
	int onFlag;
	int inHead;
	int inTail;
	int outHead;
	int outTail;
	char *inBuf;
	char *outBuf;	
};

ComClass::ComClass(const int comPortVal)
{
	comPort = comPortVal;
	onFlag  = 0;
	inHead  = 0;
	inTail  = 0;
	outHead = 0;
	outTail = 0;
	switch(comPortVal)
	{
		case COM1:
			comBase = COM1_BASE;
			comIRQ  = COM1_IRQ;
			comVect = COM1_VECT;
			comOldVect = COM1_OLD_VECT;
			break;
		case COM2:
			comBase = COM2_BASE;
			comIRQ  = COM2_IRQ;
			comVect = COM2_VECT;
			comOldVect = COM2_OLD_VECT;
			break;
		default:
			break;
	}
}

void ComClass::comInt(void)
{
	if (!onFlag)
		return;
		
	disable();
	
	int temp = (inportb(comBase+IIR)) & IIR_MASK;
	switch(temp)
	{
		case 0x00:  // modem status changed
			inportb(comBase+MSR);   // read in useless char
			break;
		case 0x02:  // Request To Send char
			if (outHead != outTail)	// there's a char to send
			{
				outportb(comBase+TXR, outBuf[outHead++]);	// send the character
				if (outHead == OBUF_LEN)
					outHead = 0;								// if at end of buffer, reset pointer
			}
			break;
		case 0x04:  // character ready to be read in
			inBuf[inHead++] = inportb(comBase+RXR);// read character into inbuffer
			if (inHead == IBUF_LEN) // if at end of buffer
				inHead = 0;           // reset pointer
			break;
		case 0x06:  // line status has changed
			inportb(comBase+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
}

void ComClass::sendChar(const char ch)
{
	if (onFlag)
	{
		disable();						      // make sure nothing happens while changing buffer
		outBuf[outTail++] = ch;			// insert character into buffer;
		if (outTail == OBUF_LEN)		// if at end of out buffer
		{
			outTail = 0;				      // reset pointer
		}
		enable();                   // re-enable interrupts
	}
}

int ComClass::receiveChar(char *ch)
{
	if(onFlag)
	{
		if (inHead != inTail)     // there is a character
		{
			disable();              // disable irqs while getting char
			*ch = inBuf[inTail++];  // get character from buffer
			if (inTail == IBUF_LEN)	//if at end of in buffer
				inTail = 0;				    // reset pointer
			enable();               // re-enable interrupt
			return TRUE;
		}
	}
	return FALSE;
}

void ComClass::comOff(void)
{
	if(onFlag)
	{
    disable();
		int temp = inportb(PIC8259_IMR) | ~comIRQ;
		outportb(PIC8259_IMR, temp);
		outportb(comBase + IER, 0);
		outportb(comBase + MCR, 0);
		enable();
    setvect(comVect, oldvects[comOldVect]);
		onFlag = FALSE;
		delete [] inBuf;
		delete [] outBuf;
	}
}
		
int ComClass::setCom(const int baud, const int para)
{
	if (baud == 0)
		return FALSE;
	int divisor = (int)(115200L/baud);
	
	//申请空间
	inBuf = new char[IBUF_LEN];
	outBuf = new char[OBUF_LEN];
	
	disable();	
	char c = inportb(comBase + LCR);
  outportb(comBase + LCR, (c | 0x80)); 
  outportb(comBase + DLL, (divisor & 0x00FF));
  outportb(comBase + DLH, ((divisor >> 8) & 0x00FF));
  outportb(comBase + LCR, c);          
	outportb(comBase + LCR, para);	
	enable();
	
	oldvects[comOldVect] = getvect(comVect);
	switch(comPort)
	{
		case COM1:
		  setvect(comVect, com1_int);
		  break;
		case COM2:
			setvect(comVect, com2_int);
			break;
		default:
			break;
	}	
	disable();
	int temp = inportb(comBase + MCR) | 0x0f;
	outportb(comBase + MCR, temp);
	temp = (inportb(comBase + IER)) | IER_RX_INT;
	outportb(comBase + IER, temp);
	temp = inportb(PIC8259_IMR) & comIRQ;
	outportb(PIC8259_IMR, temp);
	enable();
	
	onFlag = TRUE;
	
	return TRUE;
}

void ComClass::comMainRun(void)
{	
	if (onFlag)
	{
		disable();
		if (outHead != outTail)
		{
			outportb(comBase+IER,IER_TX_INT);
		}
		else
		{
			outportb(comBase+IER,IER_RX_INT);
		}
		enable();
	}	
}


ComClass com1(COM1);
ComClass com2(COM2);

void interrupt com1_int(...)
{
	com1.comInt();
}

void interrupt com2_int(...)
{
	com2.comInt();
}

int SerComOn(int comport)
{
 if ((comport == COM1) || (comport == COM2))
 	 return TRUE;
 else 
 	 return FALSE;
}

int SetSerCom(const int comport, int baud, int para)
{
	switch(comport)
	{
		case COM1:			
			return com1.setCom(baud, para);
		case COM2:
			return com2.setCom(baud, para);
		default:
			return FALSE;
	}
}

//关闭串口
void SerComOff(const int comport)
{
	switch(comport)
	{
		case COM1:
			com1.comOff();
			break;
		case COM2:
			com2.comOff();
			break;
		default:
			break;
	}
}

//关闭全部串口
void OffAllSerial(void)
{
	com1.comOff();
	com2.comOff();
}

void SendChar(const int comport, const char ch)
{
	switch(comport)
	{
		case COM1:
			com1.sendChar(ch);
			break;
		case COM2:
			com2.sendChar(ch);
			break;
		default:
			break;
	}
}

void SendChars(const int comport, unsigned int strlen, char *buf, unsigned int *sendlen)
{
	for(int i=0; i<strlen; i++)
	{
		SendChar( comport, *(buf+i) );
	}
	*sendlen = strlen;
}

int ReceiveChar(const int comport, char *ch)
{
	switch(comport)
	{
		case COM1:
			return com1.receiveChar(ch);
		case COM2:
			return com2.receiveChar(ch);
		default:
			return FALSE;
	}
}

//例行扫描
void comMainRun(void)
{
	com1.comMainRun();
	com2.comMainRun();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -