📄 serial.c
字号:
#include "includes.h"
/****************************************************************************
* Communications routines for the PC's serial port. These routines are
* adapted from methods and examples presented in "Extending Turbo C
* Professional" by Al Stevens, MIS Press, 1989.
****************************************************************************/
/* Drop down to 16-bit instruction mode to avoid disturbing the
interrupted 32-bit machine state, which is not saved by Borland
C++ 3.1 interrupt routines. */
#pragma option -2
volatile char serial_buffer[SERIALBUFFERSIZE];
volatile char *nextserialin = serial_buffer;
volatile char *nextserialout = serial_buffer;
volatile int buffer_count;
/* Standard RS-232 line settings for external beacon receivers. */
volatile int SERIALPORT = 1; /* COM1 or COM2.*/
volatile int PARITY = 0; /* 0 = none, 1 = odd, 2 = even. */
volatile int STOPBITS = 1; /* 1 or 2. */
volatile int WORDLEN = 8; /* 7 or 8. */
volatile int BAUD = 9600; /* 110,150,300,600,1200,2400,4800,9600. */
/* Serial port initialization parameter byte. */
static union
{
struct
{
unsigned wordlen : 2;
unsigned stopbits : 1;
unsigned parity : 3;
unsigned brk : 1;
unsigned divlatch : 1;
} serial_initial_bits;
char serial_initial_char;
} initserial;
static void interrupt (far *oldserialint)(__CPPARGS);
static void interrupt far NewSerialInt(__CPPARGS);
/****************************************************************************
* Function: void InitSerialPort(int portnum)
*
* Initialise the serial port input buffer, then initialize either COM1 or
* COM2 for RS232 parameters specified in the control variables BAUD, PARITY,
* etc. Attach our own serial input ISR to the default COM port interrupt,
* saving the old interrupt vector so that it can be restored later.
*
* Input: portnum - the COM port number.
*
* Output: None.
*
* Return Value: None.
****************************************************************************/
void InitSerialPort(int portnum)
{
SERIALPORT = portnum;
buffer_count = 0;
nextserialin = nextserialout = serial_buffer;
initserial.serial_initial_bits.parity = PARITY == 2 ? 3 : PARITY;
initserial.serial_initial_bits.stopbits = STOPBITS-1;
initserial.serial_initial_bits.wordlen = WORDLEN-5;
initserial.serial_initial_bits.brk = 0;
initserial.serial_initial_bits.divlatch = 1;
outp(LINECTL, initserial.serial_initial_char);
outp(DIVLSB, (char) ((115200L/BAUD) & 255));
outp(DIVMSB, (char) ((115200L/BAUD) >> 8));
initserial.serial_initial_bits.divlatch = 0;
outp(LINECTL, initserial.serial_initial_char);
/* Attach to the serial interrupt vector. */
oldserialint = getvect(SERIALINT);
setvect(SERIALINT, NewSerialInt);
outp(MODEMCTL, (inp(MODEMCTL) | DTR | RTS | OUT2));
outp(PIC01, (inp(PIC01) & SERIALIRQ));
outp(INTENABLE, DATAREADY);
outp(PIC00, EOI);
/* Flush existing serial interrupts. */
inp(RXDATA);
inp(INTIDENT);
inp(LINESTATUS);
inp(MODEMSTATUS);
}
/****************************************************************************
* Function: void RestoreSerialInt(void)
*
* Restore the previously saved serial interrupt routine, thus inactivating
* our own serial input ISR. This needs to be done before program termination,
* or before switching serial input to another COM port.
*
* Input: None.
*
* Output: None.
*
* Return Value: None.
****************************************************************************/
void RestoreSerialInt(void)
{
if (oldserialint)
setvect(SERIALINT, oldserialint);
}
/****************************************************************************
* Function: void far interrupt NewSerialInt(__CPPARGS)
*
* Read the new serial input character and store it in the circular serial
* input buffer.
*
* Input: None.
*
* Output: None.
*
* Return Value: None.
****************************************************************************/
void far interrupt NewSerialInt(__CPPARGS)
{
int c;
outp(PIC00,EOI);
if(nextserialin == (serial_buffer+SERIALBUFFERSIZE))
nextserialin = serial_buffer;
c = inp(RXDATA);
*nextserialin++ = (char) c;
buffer_count++;
}
/****************************************************************************
* Function: int InputCharsReady(void)
*
* Determines if there are any charcters to process in the input buffer.
*
* Input: None.
*
* Output: None.
*
* Return Value: TRUE if at least one character to process.
****************************************************************************/
int InputCharsReady(void)
{
return (nextserialin!=nextserialout);
}
/****************************************************************************
* Function: int ReadSerial(void)
*
* Gets the next character from the serial input buffer.
*
* Input: None.
*
* Output: None.
*
* Return Value: The next character waiting in the serial input buffer.
****************************************************************************/
int ReadSerial(void)
{
if(nextserialout == (serial_buffer+SERIALBUFFERSIZE))
nextserialout = serial_buffer;
buffer_count--;
return(*nextserialout++);
}
/****************************************************************************
* Function: int WriteSerial(int c)
*
* Wait for the serial port to become ready to accept the next output
* character. Then write it to the UART.
*
* Input: c - the character to be sent.
*
* Output: None.
*
* Return Value: TRUE - when written.
****************************************************************************/
int WriteSerial(int c)
{
while(TRUE)
{
PROTECT++;
if((inp(LINESTATUS) & XMIT_DATA_READY))
break;
PROTECT--;
}
outp(TXDATA,c);
PROTECT--;
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -