Thanks for all the replies very useful.
Can my ring buffer RX routine below coexist with your TX routine I wonder?
Can you have two interrupt driven things going on?
Code:'------------------------------------- ' PBP BCM CODE 8mhz 1963 Words '------------------------------------- 'MPASM Config @ __config _CONFIG1, _INTRC_IO & _WDT_OFF & _LVP_OFF & _MCLR_OFF & _CP_OFF @ __config _CONFIG2, _IESO_OFF & _FCMEN_OFF DEFINE OSC 8 'Set oscilator speed to 8mHz OSCCON = %01111000 '8 Mhz CMCON = %00000111 'COMPARATORS OFF CCP1CON = 0 'COMPARATORS OFF CVRCON = 0 'COMPARATORS OFF INTCON = 0 'Disable interrupts TRISB = %00000100 'SET PORTB RB2(RX) as input, others to OUTPUT TRISA = %11110111 'SET PORTA AS INPUTS except PORTA.3 ANSEL = %00000001 'AN0 Analog Input ADCON0 = %01000001 'Turns A/D on, AN0 Fosc/16 ADCON1 = %11000000 'Right justified and Fosc/16 '----------------------------------------------------------------------------- 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_BAUD 9600 'Set Baud rate to 9600bps DEFINE HSER_BITS 9 'Set to 9 bit mode DEFINE HSER_EVEN 1 'Set Even Parity DEFINE HSER_CLROERR 1 'Clear overflow error automatically 'Debug is used as it is the fastest and smallest serial routine to drive the Lcd display DEFINE DEBUG_REG PORTB 'Set Debug pin port B DEFINE DEBUG_BIT 4 'Set Debug pin bit for Lcd Display PORTB.4 'DEFINE DEBUG_BAUD 38400 'Set Debug baud rate 38400 approx 3840 cps or 0.26ms per character DEFINE DEBUG_BAUD 9600 'Set Debug baud rate 9600 approx 960 cps or 1ms per character DEFINE DEBUG_MODE 0 'Set Debug mode: 0 = true, 1 = inverted (T=True Idle High)(N=Inverted Idle Low) DEFINE DEBUG_PACING 1000 'Set Debug Character Pacing mode to 1ms between bytes include "modedefs.bas" 'Allows the use of the standard serin/serout command 'Variables Constants and I/O definitions '------------------------ Variables 16bit -------------------------------------- Amps var WORD 'Amps Word Variable Soc var WORD 'Soc Word Variable TempH var WORD 'High Temperature Word Variable TempL var WORD 'Low Temperature Word Variable Gen1 var WORD 'Gen1 General variable & Key input up/down/left/right/centre Watts var WORD 'IMA Power in Watts (Battery Volts x Battery Amps) MaxWatts var WORD 'Maximum IMA Power in Watts during trip Errors var WORD 'Number of RS485 Data Checksum Errors Packets var WORD 'Number of RS485 Data Packets '------------------- Variables 8bit -------------------------------------------- Volts var BYTE 'Volts Byte Variable (0-255) BCM87 var BYTE[11] 'Define BCM87 as a Byte array (12 Bytes 0-11) (BCM87 = BCM Data) BCMAA var BYTE[11] 'Define BCMAA as a Byte array (12 Bytes 0-11) (BCMAA = BCM Data) Cnt var BYTE 'General Byte Counter Variable (0-255) Text var BYTE 'General Byte Text Variable (0-255) Gen0 var BYTE 'Gen0 is a Byte variable (0-255) Config var BYTE 'Gauge Config Byte (8 bits) AmpSign var BYTE 'Amps Sign Byte Variable (43 = +) (45 = -) TempHSign var BYTE 'TempH Sign Byte Variable (43 = +) (45 = -) TempLSign var BYTE 'TempL Sign Byte Variable (43 = +) (45 = -) CheckSum var BYTE 'BCM Data Checksum calculation Byte MaxVolts var BYTE 'Maximum Voltage during trip MinVolts var BYTE 'Minimum voltage during trip MaxAsst var BYTE 'Maximum Assist Amps during trip MaxRegen var BYTE 'Maximum Regen Amps during trip MaxTemp var BYTE 'Maximim Temp during trip MinTemp var BYTE 'Minimum Temp during trip MaxSoc var BYTE 'Maximum OEM Soc during trip MinSoc var BYTE 'Minimum OEM Soc during trip Adr1 VAR BYTE 'Number for start of menu data Adr2 VAR BYTE 'Number for end of menu data Display VAR BYTE 'Display Mode 0 = Normal, 1 = Binary, 2 = Max/Min, 3 = Splash Screen 'PortA Input Variables OverV VAR PORTA.0 'Define PortA.0 Pin as OverV (Over Voltage Input) (Low = Over V) UnderV VAR PORTA.7 'Define PortA.7 Pin as UnderV (Under Voltage Input) (Low = Under V) 'PortA Output Variables Spare VAR PORTA.3 'Define PortA.3 Pin as Data Out 'PORTB Input Variables BcmIn Var PORTB.2 'Define PortB.2 Pins as RS485 In 'PORTB Ouput Variables Led1 VAR PORTB.0 'Define PortB.0 Pin as Led1 Led2 VAR PORTB.1 'Define PortB.1 Pin as Led2 Piezo VAR PORTB.3 'Define PortB.3 Pin as Piezo BcmOut Var PORTB.5 'Define PortB.5 Pins as RS485 Out ;-- Place a copy of these variables in your Main program ------------------- ;-- The compiler will tell you which lines to un-comment -- ;-- Do Not un-comment these lines -- ;--------------------------------------------------------------------------- ;wsave VAR BYTE $20 SYSTEM ' location for W if in bank0 ;wsave VAR BYTE $70 SYSTEM ' alternate save location for W ' if using $70, comment wsave1-3 ' --- IF any of these three lines cause an error ?? ------------------------ ' Comment them out to fix the problem ---- ' -- Which variables are needed, depends on the Chip you are using -- ;wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1 ;wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2 ;wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3 '*********************************************************************** '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 48 'Sets the size of the ring buffer 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 debug 254,1 'Clear Screen goto MainLoop '*********************************************************************** '------------------------------------- ' 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, so 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 '------------------------------------- ' Error Handler '------------------------------------- ErrorHandler: 'Display error message if buffer has overrun IF errflag.1 Then 'Determine the error DEBUG 254,128,"Buffer Overflow" 'Display buffer error Else DEBUG 254,128,"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. '------------------------------------- ' RS485 Passthru Test '------------------------------------- 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) HSEROUT [BufChar] 'Send the character goto MainLoop 'Loop forever END




Bookmarks