Code:
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>>2
Pauseus (pw>>2)
LOW SERVO1
HIGH SERVO2
Pauseus (pw>>2
Pauseus (pw>>2)
LOW SERVO2
Enable
For i = 0 to 1600 ' Delay for 16ms (16*1mS)
Pauseus 10 ' 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
Bookmarks