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

📄 ser.cpp

📁 串口部分编码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}
		break;
	case 0x04:  // character ready to be read in
		inbuf[inhead++] = inportb(portbase+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(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
}

// Inserts the character to be outputted into the output buffer, checking
// for an open slot in the output buffer array.  If there is, insert
// the character, or if there isn't, wait until a slot opens up.

serial& serial::operator<<(char ch )
{
	if (ch)                             // If this is a valid char
	{
		enable();                       // turn on irqs to ensure data output
		//outportb(portbase + MCR,  MCR_INT | MCR_DTR | MCR_RTS);//modem control,
		outportb(portbase + IER,  IER_RX_INT);

		// check buffer, and if full, wait for an available opening
		//  fprintf(stdout,"\n %c is pressed!\n",ch);   //You can use this to verify which key is hit during your test
		while((outhead-1==outtail) ||(outtail==OBUF_LEN-1 && outhead==0));
		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
		if((inportb(portbase+IER)&IER_TX_INT) == 0)
			outportb(portbase+IER,IER_TX_INT | IER_RX_INT);
		enable();                       // re-enable interrupts
	}
	return(*this);
}

serial &serial::operator<<(char *str)
// Outputs a string to the serial port
{

	while (*str)
	{
		(*this) << (*str);
		str++;
	}
	return(*this);
}

serial &serial::operator>>( char &ch )
// Returns either the character to be received from modem if there is one
// waiting in the buffer, or returns a 0 if there is no character waiting.
{
	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(*this);                   // return the char
	}
	ch = -1;
	return(*this);                       // return nothing
}

/* Install our functions to handle communications */

void setvects(void)
{
	oldvects[0] = getvect(0x0B);
	oldvects[1] = getvect(0x0C);
	setvect(0x0B, com_int);
	setvect(0x0C, com_int);
}

/* Uninstall our vectors before exiting the program */
void resvects(void)
{
	setvect(0x0B, oldvects[0]);
	setvect(0x0C, oldvects[1]);
}

/* Tell modem that we're ready to go */
void serial::comm_on(void)

{

	int temp, pnum;

	disable();
	temp = inportb(portbase + MCR) | 0x0f;//MCR_INT;
	outportb(portbase + MCR, temp);
	temp = (inportb(portbase + IER)) | IER_RX_INT;//|IER_TX_INT;
	outportb(portbase + IER, temp);
	pnum = (portbase == COM1BASE ? COM1 : COM2);
	temp = inportb(PIC8259_IMR) & (pnum == COM1 ? IRQ4 : IRQ3);
	outportb(PIC8259_IMR, temp);
	// temp = inportb(portbase + MCR) | MCR_DTR | MCR_RTS;
	// outportb(portbase + MCR, temp);
	enable();
}

/* Go off-line */

void serial::comm_off(void)
{
	int  temp;

	disable();
	temp = inportb(PIC8259_IMR) | ~IRQ3 | ~IRQ4;
	outportb(PIC8259_IMR, temp);
	outportb(portbase + IER, 0);
	outportb(portbase + MCR, 0);
	enable();
}



void serial::init_serial(void)
{
	endbuf = startbuf = 0;
	setvects();
	comm_on();
}

serial::~serial()
{
	comm_off();
	resvects();
}

/* Set the port number to use */
int serial::SetPort(int Port)
{
	int  Offset, far *RS232_Addr;
	switch (Port)
	{ /* Sort out the base address */
	case COM1 :
		Offset = 0x0000;
		break;
	case COM2 :
		Offset = 0x0002;
		break;
	default   :
		printf("\ncannot find the serial port.\n");
		return (-1);
	}

	RS232_Addr = (int far *)MK_FP(0x0040, Offset);  /* Find out where the port is. */
	if (*RS232_Addr == NULL)
	{
		printf("\ncannot find the serial port.\n");
		return (-1);                     /* If NULL then port not used. */
	}

	portbase = *RS232_Addr;              /* Otherwise set portbase      */
	return (0);
}

/* This routine sets the speed; will accept funny baud rates. */
/* Setting the speed requires that the DLAB be set on.        */

int serial::SetSpeed(int Speed)
{
	char    c;
	int     divisor;


	if (Speed == 0)            /* Avoid divide by zero */
		return (-1);
	else
		divisor = (int) (115200L/Speed);

	if (portbase == 0)
		return (-1);



	disable();
	c = inportb(portbase + LCR);
	outportb(portbase + LCR, (c | 0x80)); /* Set DLAB */
	outportb(portbase + DLL, (divisor & 0x00FF));
	outportb(portbase + DLH, ((divisor >> 8) & 0x00FF));
	outportb(portbase + LCR, c);          /* Reset DLAB */
	enable();

	return (0);
}

/* Set other communications parameters */

int serial::SetOthers(int Parity, int Bits, int StopBit)
{
	int  setting;

	if (portbase == 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(portbase + LCR, setting);
	enable();

	return (0);

}

/* Set up the port */

serial::serial(int Port, int Speed, int Parity, int Bits, int StopBit)
{
	flag = 0;

	if (SetPort(Port))
		flag = -1;

	if (SetSpeed(Speed))
		flag = -1;

	if (SetOthers(Parity, Bits, StopBit))
		flag = -1;

	if (!flag)
		init_serial();
}

/*  Control-Break interrupt handler */

int c_break(void)
{
	int temp;

	disable();

	temp = inportb(PIC8259_IMR) | ~IRQ3 | ~IRQ4;

	outportb(PIC8259_IMR, temp);
	outportb(portbase + IER, 0);
	outportb(portbase + MCR, 0);

	enable();

	fprintf(stderr, "\nStill online.\n");
	return(0);
}

⌨️ 快捷键说明

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