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

📄 serdpcin.c

📁 一个C语言写的读入位置跟踪器数据的源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	}
	else    /* rxcount > 0 */
	{
	    /*
		Get remainder of Block of data from the serial port, recsize characters
		and store them in rxbuf
	    */
	    if ((rxchar = waitforchar()) >= 0)  /* no errors */
	    {
		/*
		   Check Phase bit
		*/
		if (rxchar & 0x80)              /* check to see that phase bit = '0' */
		{
		    if (outputmode == STREAM)
		    {
			phaseerror_count++;     /* keep track of phase errors */
			resynch = TRUE;         /* loop again flag */
			continue;
		    }
		    else
		    {
			return(RXPHASEERROR);       /* return phase error */
		    }
		}
	    }
	    else
	    {
		if (outputmode == STREAM)
		{
		    phaseerror_count++;     /* keep track of phase errors */
		    resynch = TRUE;         /* loop again flag */
		    continue;
		}
		else
		{              
		    return(RXERRORS);
		}
	    }
	}
	/*
	   Store the received character
	*/
	*rxbufptr++ = rxchar;   /* store and adjust pointer */
	rxcount++;              /* increment */
    }
    while ((resynch) || (rxcount < recsize));

    /*
	Return the number of characters received
    */
    return(rxcount);
}

/*
    send_serial_cmd     -    Send Serial Command to the Bird port

    Prototype in:       serial.h

    Parameters Passed:  cmd         -   string to send to the serial point
			cmdsize     -   size of the cmd string (cmd is NOT
					NULL terminated, since the data can
					be NULL)
    Return Value:       number of characters transmitted

    Remarks:            Routine will send a string of characters to the serial
			port.  The string is pointed to by cmd and all
			characters will be sent upto but NOT including
			the NULL
*/
int send_serial_cmd(cmd,cmdsize)
unsigned char * cmd;
short cmdsize;
{
    short txcount = 0;
    unsigned char rs232tofbbcmd;

    DISABLE();

    /*
	Send the RS232 to FBB Prefice Character if non-zero
    */
    if (rs232tofbbaddr > 0)
    {
	if (rs232tofbbaddr <= 15)
	    /* pass through command 0-15 */
	    rs232tofbbcmd = (unsigned char)(0xF0 | rs232tofbbaddr);
	else
	    /* pass through command 16-31 */
	    rs232tofbbcmd = (unsigned char)(0xE0 | rs232tofbbaddr-16);

	while (send_serial_char(rs232tofbbcmd) == TXNOTEMPTY);
    }

    while (txcount < cmdsize)
    {
	/*
	    Store the character in the TX buffer
	*/
	if (send_serial_char(*cmd++) != TRUE)
	    break;

	txcount++;
    }

    /*
	Verify that the TX interrupt is enabled
	..if not, enable it so that the ISR will execute
    */
    if ((INPORTB (com_base + INTERENABLE) & TXHOLDINTENABLE) == 0)
    {
	OUTPORTB (com_base + INTERENABLE,
	    TXHOLDINTENABLE | RXDATAAVAILINTENABLE | RXLINESTATUSINTENABLE);
	OUTPORTB (com_base + INTERENABLE,
	    TXHOLDINTENABLE | RXDATAAVAILINTENABLE | RXLINESTATUSINTENABLE);
    }
    ENABLE();                   /* reenable interrupts */
    return(txcount);
}

/*
    send_serial_char    -   Send one serial char to the serial port

    Prototype in:       serial.h

    Parameters Passed:  chr     -   character to send to the serial port

    Return Value:       returns TRUE if successful, or TXBUFFERFULL if the
			TXBUF is full

    Remarks:            The routine is used to send a single character
			out to the UART if there is room in the output buffer.
			The routine checks to see if the Transmit interrupts
			are presently enabled...if not they are turned out
			so the ISR will get the character.
*/
int send_serial_char(chr)
unsigned char chr;
{
    /*
	Check for a full TX buffer...
	... 2 ways the txbufinptr can = the txbufoutptr:
		1) if the buffer is empty, which is OK
		2) if the buffer is full, which is not OK
    */
    if (txbufinptr == txbufoutptr)
	if (!txbufempty)
	    return(TXBUFFERFULL);

    /*
	Write the character to the inbufptr
    */
    *txbufinptr++ = chr;
    txbufempty = FALSE;

    /*
	Check for buffer end...wrap around if at end
    */
    if (txbufinptr == &txbuf[TXBUFSIZE])
	txbufinptr = txbuf;

    return(TRUE);
}

/*
    get_serial_char -   Get 1 Character from the serial port if one is available

    Prototype in:       serial.h

    Parameters Passed:  void

    Return Value:       returns the

    Remarks:            returns the receive character if successful,
			RXERRORS if recieve errors
			NODATAAVAIL if no characer available
*/
int get_serial_char()
{
	short rxchar;

    if ((!rxerrors) && (!rxbufoverruns))
    {
	/*
	    get character if available...else return
	*/
	if (rxbufinptr == rxbufoutptr)
	    return(NODATAAVAIL);

	/*
	    get the character
	*/
	rxchar = *rxbufoutptr++;

	/*
	    check for End of Rx buffer..if so, wrap pointer to start
	*/
	if (rxbufoutptr == &rxbuf[RXBUFSIZE])
	    rxbufoutptr = rxbuf;

	/*
	    return the character
	*/
	return(rxchar);
    }
    else
    {
	/*
	    Reset Error flags and Announce the Errors
	*/
	if (rxerrors)
	{
	    printf("** ERROR ** rx line errors have occured\n");
	    rxerrors = FALSE;
	}

	if (rxbufoverruns)
	{
	   printf("** ERROR ** rx buffer overrun errors have occured\n");
	   rxbufoverruns = FALSE;
	}

	return(RXERRORS);
    }

}

/*
    waitforchar         -   Wait for a Character from the Serial Port

    Prototype in:       serial.h

    Parameters Passed:  void

    Return Value:       returns the receive character if successful,
			RXERRORS if recieve errors,
			RXTIMEOUT if a time out occurs before a
			character is ready

    Remarks:            Routine waits for the TIMEOUTINTICKS period
			for a character

*/
int waitforchar()
{
	short rxchar;
    long starttime;

    /*
	Get the time now in ticks
    */
    starttime = GETTICKS;

    /*          
	Wait until a character is available
	....leave loop if errors or character available
    */
    while ((rxchar = get_serial_char()) == NODATAAVAIL)
    {
	/*
	    Check to see if a timeout occured
	*/
	if ((GETTICKS - starttime) > (long)((RXTIMEOUTINSECS * 1000) / TICK_MSECS))
	{
	    printf("\n** ERROR ** receiver timed out\n");
	    return(RXTIMEOUT);
	}
    }


    /*
	return if RX errors
    */
    if (rxchar < 0)
	return(RXERRORS);

    /*
	Everything is OK...return the character
    */
    return(rxchar);
}

/*
    waitforphase        -   Wait for a Character with phase bit set

    Prototype in:       serial.h

    Parameters Passed:  void

    Return Value:       returns the received character if successful,
			or RXERRORS if an error occurs

    Remarks:            waits for a character to be received with the
			most significant bit (bit 7) set to a '1'.  Characters
			received with bit 7 = '0' are thrown away.
			Routine waits for the TIMEOUTINTICKS period.
*/
int waitforphase()
{
	short rxchar;

    /*
	Wait until waitforchar returns a character or error
    */
    while (((rxchar = waitforchar()) & 0x80) == 0)
    {
	/*
	    return if errors
	*/
	if (rxchar < 0)
	    return(RXERRORS);
    }

    /*
	Everything is OK...return the character
    */
    return(rxchar);
}


/*
    serialisr   -   Serial Interrupt Service Routine

    Prototype in:       serial.h

    Parameters Passed:  void

    Return Value:       void

    Remarks:            Routine processes the interrupt request from the
			8250 UART.  There are four possible interrupts from
			the UART...all are processed while in the ISR.
			Note that for the HIGHC users, the routine is
			called from the assembly module, which has
			set the DS to our own Data Segment, which will
			allow DOS to be interruptable since DOS will be
			operating in REAL mode via the DOS Extender
*/
#ifdef HIGHC
void serialisr(void)  /* called from the assembly code */
#else
INTTYPE serialisr()
#endif
{
	short intid;      /* holds the interrupt ID from the UART */
	short txchar;     /* Character to transmit */

#ifndef DPMC
    ENABLE();         /* enable higher priority interrupts to occur */
#endif

    /*
	Verify that the Interrupt is from the UART
	...do all the possible pending interrupts while here...until
	there are NO interrupts pending
    */

    while (!((intid = INPORTB(com_base + INTERIDENT)) & 1)) /* bit 0 = 0 if interrupts pending */
    {
	/*
	    Do the Serial Interrupt in Priority order
	    ..RXLINESTATUS, RXDATAAVAIL,TXEMPTY, MODEMSTATUS
	*/
	switch (intid)
	{
	    /*
		Line Status
		...just increment error counter
	    */
	    case RXLINESTATUS:  /* line status changed ... check RX errors */
		/*
		    Get the error from Linestatus
		*/
		if ((rxerrorvalue = (INPORTB(com_base + LINESTATUS) & RXERRORMSK)) != 0) /* clears interrupt */
		    rxerrors = TRUE;

		break;

	    /*
		RX Data Available
		...get the byte and store it in the RX circular buffer
		.....check for RX buffer overruns when storing character
	    */
	    case RXDATAAVAIL:
		/*
		    Get the RX data and store in the circular buffer
		*/
		*rxbufinptr++ = INPORTB(com_base + RXBUF);

		/*
		    Check for RX circular buffer overrun
		*/
		if (rxbufinptr == rxbufoutptr)          /* ck overrrun? */
		    rxbufoverruns=TRUE;                 /* increment overrun count */

		/*
		    Check for top of buffer...adjust if necessary
		*/
		if (rxbufinptr == &rxbuf[RXBUFSIZE])    /* at top ? */
		    rxbufinptr = rxbuf;                 /* reset */

		break;

	    /*
		TX Holding Register Empty
		...transmit a character from the TX buffer if one is available
		else, shut down the TX interrupt until more characters are
		available
	    */
	    case TXEMPTY:
		/*
		    Get the Character to transmit
		*/
		txchar = *txbufoutptr++;

		/*
		    check for top of buffer
		    ...reset if at top
		*/
		if (txbufoutptr == &txbuf[TXBUFSIZE])
		    txbufoutptr = txbuf;

		if (txbufoutptr == txbufinptr)          /* no data to send */
		{
		    /*
			Disable the Tx Interrupt Enable
			....don't bother until more TX chars in buffer
		    */
		    OUTPORTB(com_base + INTERENABLE,
			RXDATAAVAILINTENABLE | RXLINESTATUSINTENABLE);
		    OUTPORTB(com_base + INTERENABLE,
			RXDATAAVAILINTENABLE | RXLINESTATUSINTENABLE);

		    /*
			Set flag to indicate buffer empty
		    */
		    txbufempty = TRUE;
		}
		/*
		    Send the next TX character and increment the pointer
		*/
		OUTPORTB(com_base + TXBUF, txchar);

		break;

	    /*
		Modem Status Change
		...currently should never get here since it is never enabled,
		but if we do...clear the request by reading the register
	    */
	    case MODEMSTATUSCHG:        /* CTS, DSR, RI, DCD change */
	       INPORTB(com_base + MODEMSTATUS);         /* clear the request */
	}
    }

    /*
	Send End of Interrupt Command to the 8259
    */
    PCPIC_OUTEOI;

    return;         /* go home via IRET */
}

#endif      /* DOS */

⌨️ 快捷键说明

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