UART - how to properly receive?

Have you got the greatest 48 bit multiplier ever conceived? Prove it - post your code here.

Moderator: phalanx

Post Reply
jvd
Posts: 34
Joined: Sat Aug 01, 2009 6:47 am

UART - how to properly receive?

Post by jvd » Fri Jun 11, 2010 5:00 am

Hi,

I've written a C routine for reading a full string from the UART into a buffer.
2 problems I faced: timeout (implemented using timer0) and when to stop receiving.
In this code I detect a \r\n sequence and see that as the end of the incoming data,
but what if there are multiple \r\n in one received string? How do you know when you
received the full string?

Code: Select all

volatile char uartbuf[256];

void uartreceive(unsigned short timeout)
{
	unsigned short uartbufcount = 0;
	unsigned short limit = timeout + timer0count1s;
	unsigned char thischar, prevchar;
	unsigned char framingerror = 0;
	unsigned char overrun = 0;
	uartbuf[0] = 0;

	// MAKE SURE UART IS ENABLED
	if (! SPEN) { return; }

	// CLEAR WHAT MIGHT BE ALREADY IN BUFFER AND POTENTIAL OVERRUN ERRORS
	CREN = 0;
	CREN = 1;

	// NOTE: -1 BECAUSE WE NEED TO ADD A FINAL 0
	while ((timeout <= timer0count1s) && (uartbufcount < (UARTBUFSIZE-1)))
	{
		// WAIT FOR INTERRUPT FLAG
		if (RCIF)
		{
			// BUFFER OVERRUN?
			if (OERR) { overrun = 1; break; }

			// FRAMING ERROR IN THIS BYTE?
			if (FERR) { framingerror = 1; }

			// READ BYTE
			prevchar = thischar;
			thischar = RCREG;
			uartbuf[uartbufcount] = thischar;
			uartbufcount++;
		}

		// BREAK IF \r\n RECEIVED
		if ((prevchar == '\r') && (thischar == '\n')) { break; }
	}

	if (timeout >= timer0count1s)
	{
		// RETURN CAUSED BY TIMEOUT
		uartbuf[0] = 0;
		return;
	}

	// UART OVERRUN!
	if (overrun)
	{
		uartbuf[0] = 0;
		return;
	}

	// THERE WAS A FRAMING ERROR IN ANY OF THE RECEIVED BYTES
	if (framingerror)
	{
		uartbuf[uartbufcount] = 0;
		return;
	}

	// BUFFER OVERRUN
	if (uartbufcount == (UARTBUFSIZE-1))
	{
		uartbuf[uartbufcount] = 0;
		return;
	}

	// ALL GOOD :-)
	uartbuf[uartbufcount] = 0;
	return 0;
}
(all those different checks at the end are so I can program return codes based
on type of error in the future)

millwood
Posts: 115
Joined: Thu Jul 02, 2009 2:09 pm

Re: UART - how to properly receive?

Post by millwood » Mon Jul 05, 2010 7:00 am

the continued absence of start / stop bits over a period of time?

or you can implement your own escape / control sequence.

Post Reply