I haven't tried the crystal yet, but after really simplifying the serout strings, everything works fine. No errors. Then when I added back the code that I took out to simplify things I start having problems again. It's the pauseus commands that give me problems since the pauses are between 1ms and 2ms to control two servos. I can't see any other way of receiving UART data and controlling two servos. I'm trying like crazy to avoid real interrupts and I'd prefer not to have to have another microcontroller. Any suggestions? The deletions are included here. It's the code in the main loop that I added back.

' PicBasic Pro program to demonstrate an interrupt-driven
' input buffer for Hserin using On Interrupt.
' Pin definitions compatible with LAB-X1 and PIC16F877

DEFINE HSER_RCSTA 90h 'SPEN=0, CREN=0
DEFINE HSER_TXSTA 20h 'BRGH=0, SYNC=0, TXEN=1
DEFINE HSER_BAUD 2400
SPBRG = 25 ' Set baud rate to 2400 for USART

Include "modedefs.bas"

RCIF VAR PIR1.5 ' Alias RCIF (USART Receive Interrupt Flag)
OERR VAR RCSTA.1 ' Alias OERR (USART Overrun Error Flag)
CREN VAR RCSTA.4 ' Alias CREN (USART Continuous Receive Enable)
LED VAR PORTC.2 ' Alias LED
LCD VAR PORTC.1 ' Alias for LCD
SERVO1 VAR PORTC.3 ' Alias Servo Port
SERVO2 VAR PORTC.0 ' Alias Servo Port

buffer_size CON 32 ' Sets the size of the ring buffer
buffer VAR BYTE[buffer_size] ' Array variable for holding received characters
index_in VAR BYTE ' Pointer - next empty location in buffer
index_out VAR BYTE ' Pointer - location of oldest character in buffer
bufchar VAR BYTE ' Stores the character retrieved from the buffer
i VAR BYTE ' loop counter
col VAR BYTE ' Stores location on LCD for text wrapping
errflag VAR BYTE ' Holds error flags
pw VAR WORD ' Pulse Width Variable
direction Var Byte ' Direction Variable
carnumber Var Byte ' Car # 1 through 8
carsteering Var byte ' Car Steering
carthrottle Var byte ' Car Throttle

index_in = 0
index_out = 0
i = 0
col = 1
pw = 1200 ' start servo at extreme left
direction = 1
LOW SERVO1
LOW SERVO2

SEROUT LCD,N9600,[$1b,$2a,$40] 'Set Backlight Brightness
SEROUT LCD,N9600,[$fe,1] ' Clear Screen

INTCON = %11000000 ' Enable interrupts
ON INTERRUPT GoTo serialin ' Declare interrupt handler routine
PIE1.5 = 1 ' Enable interrupt on USART

' Main program starts here - blink an LED at 1Hz

loop: Disable
HIGH SERVO1
Pauseus pw
LOW SERVO1

HIGH SERVO2
Pauseus pw
LOW SERVO2
Enable
For i = 0 to 16 ' Delay for 16ms (16*1mS)
Pause 1 ' Use a short pause within a loop
Next i ' instead of one long pause
pause 16 ' set frequency to about 50 Hz
If direction=0 THEN
pw = pw - 5
ELSE
pw = pw + 5
ENDIF
if pw > 1800 then direction=0 ' at extreme right, turn CCW. 0 is for left
if pw < 1200 then direction=1 ' at extreme left, turn CW. 1 is for right


display: ' dump the buffer to the LCD
IF errflag Then error ' Handle error if needed
IF index_in = index_out Then loop ' loop if nothing in buffer

GoSub getbuf ' Get a character from buffer
'SEROUT LCD,N9600,[#bufchar] ' Clear Screen
If (buffer[index_out-4] = 0) then
if (buffer[index_out-3] = 0) then
if (buffer[index_out-2] = 1) then
carsteering = buffer[index_out-1]
carthrottle = buffer[index_out]
SEROUT LCD,N9600,[$fe,1] ' Clear Screen
'SEROUT LCD,N9600,[#carnumber]
'SEROUT LCD,N9600,[$fe,$c0] ' Move to beginning of 2nd line
'SEROUT LCD,N9600,[#carsteering]
'SEROUT LCD,N9600,[$fe,$94] ' Move to beginning of 3rd line
'SEROUT LCD,N9600,[#carthrottle]
'SEROUT LCD,N9600,[$fe,$d4] ' Move to beginning of 4th line
'SEROUT LCD,N9600,["End of Data Stream"]
Endif
Endif
endif

GoTo display ' Check for more characters in buffer



' Subroutines

Disable ' Don't check for interrupts in this section

getbuf: ' move the next character in buffer to bufchar
index_out = (index_out + 1) ' Increment index_out pointer (0 to 63)
IF index_out > (buffer_size-1) Then index_out = 0 ' Reset pointer if outside of buffer
bufchar = buffer[index_out] ' Read buffer location
Return


error: ' Display error message if buffer has overrun
SEROUT LCD,N9600,[$fe,$d4] ' Move to beginning of 4th line
IF errflag.1 Then ' Determine the error
SEROUT LCD,N9600,["B"]
Else
SEROUT LCD,N9600,["U"]
EndIF

errflag = 0 ' Reset the error flag
CREN = 0 ' Disable continuous receive to clear overrun flag
CREN = 1 ' Enable continuous receive

GoTo display ' Carry on


' Interrupt handler

serialin: ' Buffer the character received
IF OERR Then usart_error ' Check for USART errors
index_in = (index_in + 1) ' Increment index_in pointer (0 to 63)
IF index_in > (buffer_size-1) Then index_in = 0 'Reset pointer if outside of buffer
IF index_in = index_out Then buffer_error ' Check for buffer overrun
HSerin [buffer[index_in]] ' Read USART and store character to next empty location
IF RCIF Then serialin ' Check for another character while we're here

Resume ' Return to program

buffer_error:
errflag.1 = 1 ' Set the error flag for software
' Move pointer back to avoid corrupting the buffer. MIN insures that it ends up within the buffer.
index_in = (index_in - 1) MIN (buffer_size - 1)
HSerin [buffer[index_in]] ' Overwrite the last character stored (resets the interrupt flag)
usart_error:
errflag.0 = 1 ' Set the error flag for hardware

Resume ' Return to program


End