Send out bytes using serout one byte at a time instead of a whole string of bytes and in between sending out bytes, do a quick serin check to see if anything is there.
Send out bytes using serout one byte at a time instead of a whole string of bytes and in between sending out bytes, do a quick serin check to see if anything is there.
I don't have a choice, the data always comes in groups of 8.
The serout is just for debugging, not really needed finally.
I must be able to read in 8 bytes and then check if the 1st one is $A0 and the 7th $AF. When that is true I can use the data. The packets come at 4800bps and in bursts relatively far apart (That is how I got away with serin2 until now, it just lost packets from time to time)
I need to stop what the program is doing when that 1st byte arrives and then channel in the next 7 into an array or sepparate vars.
Regards
Chris
Hi,
I have done an application where a PIC 18F452 is connected in parallel with a dumb terminal. It parses incoming strings on the fly in an asm based INT routine and keeps required data in specified variables.For your app @4800 try this.
1. Set up a ring buffer.
2. Within the interrupt hunt for the trailer, if found set a flag.
3. Jump back to the header location to find if it was a complete command set.
4. Verify Checksum
Then you now where your data of interest are and handle them in the main routine.
Regards
Sougata
Put that input on portB and use the 'interrupt on change' feature...
I.E. - you're transmitting, something starts coming in on the serial line. Stop transmitting immediately and start receiving.
What you're trying to do isn't impossible. It's just getting past the PicBasicPro serial commands and using straight hardware and interrupts to handle it in the 'background'.
I suggest playing around with interrupts first, doesn't matter which one, just play with them. Then work your way up to using the serial port, both RX and TX, use some sort of buffering setup.
I don't understand how to setup a ring buffer, is this in the main program?
How does a ring buffer work?
Is this using asm interrupts or ON INT?
Chris,
You already have a buffer, it doesn't need to be a "ring".
But it does need to work properly.
In your original routine...When testing the value of RCREG, it also removes a byte from the USARTs buffer (if one's available).Code:'******************* interrupt routine ********************* disable myroutine: if PIR1.5=1 then PELCO[BYTECOUNT]=RCREG IF RCREG=$AF THEN GOSUB SENDATA PIR1.5=0 ELSE BYTECOUNT=BYTECOUNT+1 GOTO MYROUTINE ENDIF ENDIF resume enable
And, there's currently no way to reset BYTECOUNT, it just keeps counting, which then overwrites memory areas that you don't want it to.
Try this...HTH,Code:'******************* interrupt routine ********************* disable myroutine: if PIR1.5=1 then temp = RCREG if temp = $A0 then BYTECOUNT = 0 if BYTECOUNT < 8 then PELCO[BYTECOUNT]=temp BYTECOUNT=BYTECOUNT+1 IF (BYTECOUNT = 8) and (temp=$AF) THEN GOSUB SENDATA GOTO MYROUTINE ENDIF ENDIF resume enable
DT
Thanks for the example code, I modified it to my variable names and included the main loop but it just gives me vales of 0 for BUFFER, what have I done wrong. I checked if it was interrupting and it is.
Here is my code:
'************************************************* **
@ device hs_OSC, wdt_on, pwrt_on, protect_off
define osc 20
Include "modedefs.bas"
trisc.6=0
TRISC.7=1
TRISA.0=0
RCSTA = %10010000 ' ENABLE USART AND SET TO CONTINUOUS RECEIVE
SPBRG = 64 'SET TO 4800bps
INTCON = %11000000 'ENABLE GLOBAL & PERIFERAL INTERRUPTS
RCIF VAR PIR1.5 'FLAG IS THE INTERRUPT WHEN A BYTE IS IN THE USART BUFFER
RCIE VAR PIE1.5
OERR VAR RCSTA.1
CREN VAR RCSTA.4
test var porta.0
BAUD CON 16390
BUFFER VAR BYTE[8] 'BUFFER FROM USART TO COLLECT THE 8 BYTES
BYTECOUNTER VAR BYTE 'USED TO COUNTER BYTES INTO THE BUFFER
BFULL VAR BIT 'FLAGS THAT THE BUFFER HAS ALL 8 BYTES
VALUE VAR BYTE 'A TEMP SINGLE BYTE RECEIVED FROM THE USART
COUNTER VAR WORD 'USED FOR LOOP IN MAIN PROGRAM
BUFFER = 0
BYTECOUNTER = 0
BFULL = 0
VALUE = 0
RCIE=1 'ENABLE USART RECEIVE INTERRUPT FLAG
ON INTERRUPT GOTO GETDATA
GOTO MAIN:
disable
GETDATA:
if RCIF=1 then 'IF RECEIVE FLAG IS ON
VALUE=RCREG 'READ THE VALUE IN THE USART BUFFER
IF VALUE = $A0 THEN 'CHECK TO SEE IF THE BYTE IS THE START BYTE
BYTECOUNTER=0 'AND SET THE COUNTER TO FIRST BYTE
ENDIF
IF BYTECOUNTER < 8 THEN
BUFFER[BYTECOUNTER] = VALUE
BYTECOUNTER=BYTECOUNTER+1 'INCREMENT FOR NEXT BYTE
IF (BYTECOUNTER = 8) AND (VALUE=$AF) THEN
TOGGLE PORTD.0
GOTO MAIN
ENDIF
ENDIF
'CHECK IF OVERRUN HAS OCCURRED:
IF OERR=1 THEN
Serout2 test,BAUD,["OERR",10,13] 'FOR DEBUGGING SHOW ERROR
CREN=0 'STOP CONTINUOUS RECEIVE
CREN=1 'RESTART CONTINUOS RECIEVE & CLEAR THE FLAG
BYTECOUNTER=0 'RESET COUNTER
GOTO GETDATA
ENDIF
ENDIF
RESUME
ENABLE
'===============================================
MAIN:
ON INTERRUPT GOTO GETDATA
if counter= 5000 THEN 'SEND PELCO VALUE EVERY FEW LOOPS
serout2 test,BAUD,["BUFFER=",HEX BUFFER.0,HEX BUFFER.1,10,13]
'(JUST CHECK 1ST 2 VALUES)
toggle portd.1 'LED TO INDICATE TO ME THAT THE LOOP IS LOOPING
counter=0
else
counter=counter+1
endif
goto main
end
I modified my code and am getting the 8 bytes but seem to keep running into buffer overflows. Can you see an error in my interrupt routine?
'************************************************* ***************
@ device hs_OSC, wdt_on, pwrt_on, protect_off
define osc 20
Include "modedefs.bas"
trisc.6=0
TRISC.7=1
TRISA.0=0
RCSTA = %10010000 ' ENABLE USART AND SET TO CONTINUOUS RECEIVE
SPBRG = 64 'SET TO 4800bps
INTCON = %11000000 'ENABLE GLOBAL & PERIFERAL INTERRUPTS
RCIF VAR PIR1.5 'FLAG IS THE INTERRUPT WHEN A BYTE IS IN THE USART BUFFER
RCIE VAR PIE1.5
OERR VAR RCSTA.1
CREN VAR RCSTA.4
test var porta.0
BAUD CON 16390
BUFFER VAR BYTE[10] 'BUFFER FROM USART TO COLLECT THE 8 BYTES
BYTECOUNTER VAR BYTE 'USED TO COUNTER BYTES INTO THE BUFFER
BFULL VAR BIT 'FLAGS THAT THE BUFFER HAS ALL 8 BYTES
VALUE VAR BYTE 'A TEMP SINGLE BYTE RECEIVED FROM THE USART
COUNTER VAR WORD 'USED FOR LOOP IN MAIN PROGRAM
BUFFER = 0
BYTECOUNTER = 0
BFULL = 0
VALUE = 0
RCIE=1 'ENABLE USART RECEIVE INTERRUPT FLAG
ON INTERRUPT GOTO GETDATA
GOTO MAIN:
disable
'====================INTERRUPT ROUTINE ==============================
GETDATA:
IF RCIF=1 THEN
VALUE=RCREG
IF VALUE = $A0 THEN 'CHECK TO SEE IF THE BYTE IS THE START BYTE
BYTECOUNTER=0
ENDIF
RCIF=0
IF BYTECOUNTER < 8 THEN
BUFFER[BYTECOUNTER] = VALUE
BYTECOUNTER=BYTECOUNTER+1
ENDIF
'CHECK IF OVERRUN HAS OCCURRED:
IF OERR=1 THEN
Serout2 test,BAUD,["OERR",10,13] 'TO SHOW OVERFLOW
PAUSE 1000
CREN=0 'STOP CONTINUOUS RECEIVE
CREN=1 'RESTART CONTINUOS RECIEVE & CLEAR THE OVERRUN FLAG
BYTECOUNTER=0 'RESET COUNTER AS PART OF PACKET HAS BEEN LOST SO START AGAIN
BUFFER=0
GOTO GETDATA
ENDIF
IF BYTECOUNTER=7 AND BUFFER[0]=$A0 AND BUFFER[6]=$AF THEN
GOTO MAIN
ELSE
GOTO GETDATA
ENDIF
ENDIF
RESUME
ENABLE
'================================================= ====================================
MAIN:
'ON INTERRUPT GOTO GETDATA
if counter= 1000 THEN 'SEND PELCO VALUE EVERY FEW LOOPS
serout2 test,BAUD,["BUFFER=",HEX BUFFER[0],",",HEX BUFFER[1],",",HEX BUFFER[2],",",HEX BUFFER[3],",",HEX BUFFER[4],",",HEX BUFFER[5],",",HEX BUFFER[6],",",HEX BUFFER[7],10,13] 'JUST CHECK 1ST 2 VALUES
toggle portd.1 'LED TO INDICATE TO ME THAT THE LOOP IS LOOPING
counter=0
else
counter=counter+1
endif
goto main
end
'================================================= ====================================
Bookmarks