Thanks again Joe. That code worked very well and of course thanks to Darrel Taylor for his DT_INTS code.
The final code is posted here should anyone need it:
Code:
'-------------------------------------
' STARTUP CODE
'-------------------------------------
'MPASM generates an warning because of tabs around the macro (this prevents it)
@ errorlevel -207
'Config settings for MPASM
@ __CONFIG _CONFIG1, _HS_OSC & _CP_OFF & _WDT_OFF & _PWRTE_ON & _MCLR_ON & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _DEBUG_OFF & _CCP1_RB0
'Using a 20Mhz XTAL
define OSC 20
'Register setup
ADCON1 = %00000111 ' Disable A/D converter
ANSEL = %00000000 ' all analog pins to digital
CCP1CON = %00000000 ' Disable CCP Module
CMCON = %00000111 ' Turn off comparator
INTCON = %00000000 ' Interrupts disabled
'Setup & Clear the ports
TRISA = %00000000 'All O/P's
TRISB = %00001101 'All O/P's
PORTA = 0 'Zero PortA O/P's
PORTB = 0 'Zero PortB O/P's
'-----------------------------------------------------------------------------
INCLUDE "DT_INTS-14.bas"
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX_INT, _INT_Serin, PBP, no
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE RX_INT ; enable external (INT) interrupts
'-----------------------------------------------------------------------------
'Setup the hardware USART for 9600 baud
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 129 ' 9600 Baud @ 0.16%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
'Define the LCD
Define LCD_DREG PORTA
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 1500
DEFINE LCD_DATAUS 50
'Alias & Vars
RCIF VAR PIR1.5 ' Receive interrupt flag (1=full , 0=empty)
TXIF VAR PIR1.4 ' Transmit interrupt flag (1=empty, 0=full)
OERR VAR RCSTA.1 ' Alias OERR (USART Overrun Error Flag)
CREN VAR RCSTA.4 ' Alias CREN (USART Continuous Receive Enable)
BufMax CON 64 ' Sets the size of the ring buffer, set up from 32
Buffer VAR BYTE[BufMax] ' Array variable for holding received characters
Ptr_in VAR BYTE ' Pointer - next empty location in buffer
Ptr_out VAR BYTE ' Pointer - location of oldest character in buffer
Bufchar VAR BYTE ' Stores the character retrieved from the buffer
ErrFlag VAR BYTE ' Holds error flags
ptr_in = 0 ' Clear buffer pointer (in)
ptr_out = 0 ' Clear buffer pointer (out)
Errflag = 0 ' Clear error flag
'Skip over the interupt handler & subroutines
goto ShowSplash
'-------------------------------------
' INTERUPT HANDLER
'-------------------------------------
INT_Serin: ' Serial Interrupt routine
IF OERR Then usart_error ' Check for USART errors
ptr_in = (ptr_in + 1) ' Increment ptr_in pointer (0 to 63)
IF ptr_in > (BufMax-1) Then ptr_in = 0 'Reset pointer if outside of buffer
IF ptr_in = ptr_out Then Buffer_Error ' Check for buffer overrun
HSerin [buffer[ptr_in]] ' Read USART and store data in next empty location
IF RCIF Then INT_Serin ' Check for another character while we're here
@ INT_RETURN ; Return to program
Buffer_Error: ' Error - Run out of buffer space
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.
ptr_in = (ptr_in - 1) MIN (BufMax - 1)
HSerin [buffer[ptr_in]] ' Overwrite the last data stored (clear the int.)
USART_Error: ' Error - USART has overrun (data too fast?)
errflag.0 = 1 ' Set the error flag for hardware
@ INT_RETURN ; Return to program
'-------------------------------------
' Subroutines
'-------------------------------------
GetBuf: ' move the next character in buffer to bufchar
@ INT_DISABLE RX_INT ; Dont want to interupt this, Disable interupts
ptr_out = (ptr_out + 1) ' Increment ptr_out pointer (0 to 63)
IF ptr_out > (BufMax-1) Then ptr_out = 0 ' Reset pointer if outside of buffer
bufchar = buffer[ptr_out] ' Read buffer location
@ INT_ENABLE RX_INT ; All done, Enable interupts
Return
'-------------------------------------
' SPLASH SCREEN
'-------------------------------------
ShowSplash:
pause 60 'Power up delay
'Display a splash screen for 2 seconds
LCDOUT $FE,1,"RS232 to LCD"
LCDOUT $FE,$C0,"Display Test"
pause 2000
'Now ready for COMMS...
LCDOUT $FE,1,"Waiting for PC"
LCDOUT $FE,$C0,"to send data..."
'-------------------------------------
' RS232 TO LCD
'-------------------------------------
MainLoop:
IF errflag Then ErrorHandler ' Handle error if needed
IF ptr_in = ptr_out Then MainLoop ' loop if nothing in buffer
GoSub getbuf ' Get a character from buffer (stored in bufchar)
LCDOut bufchar ' Send the character to LCD
goto MainLoop 'Loop forever
'-------------------------------------
' Error Handler
'-------------------------------------
ErrorHandler:
' Display error message if buffer has overrun
IF errflag.1 Then ' Determine the error
LCDOut $FE,$1,"Buffer Overflow" ' Display buffer error
Else
LCDOut $FE,$1,"USART Overrun" ' Display usart error
EndIF
errflag = 0 ' Reset the error flag
CREN = 0 ' Disable continuous receive to clear overrun flag
CREN = 1 ' Enable continuous receive
GoTo MainLoop ' Errors cleared, time to work.
Bookmarks