PDA

View Full Version : Serial interrupt on PicBasic Pro



mregisd
- 6th February 2012, 13:11
I need some help with this serial interrupt... It's working but not so well because when the interrupt happens I receive the serial data and treat the information. The problem is when the program return from the 1st interrupt to the Loop, I can't do another interrupt. I send serial data but the interrupt not happens.

So, please, can anyone help me?

Thanks...

Here's my code..

define LOADER_USED 1 INCLUDE "modedefs.bas"


DEFINE OSC 4



RX VAR PORTC.7 'SERIAL'S RECEIVE BIT.

TX VAR PORTC.6 'SERIAL'S TRASMITTER BIT.

CMD VAR PORTD.2

CONT VAR BYTE

CMD = 0
CONT = 0

TRISC = 000000
TRISD = 000100
TRISE = 0




INTCON = 000000 ; GENERAL AND PERIPHERALS INTERRUPT
PIE1.5 = 1 ; " " " DE RECEPÇÃO DA USART


RCSTA.1 = 0 ; MANY BYTES RECEIVED WITHOUT READ
RCSTA.2 = 0 ; Stop Bit
RCSTA.4 = 1 ; CONTINOUS REVEICE
RCSTA.6 = 0 ; 8 BITS' RECEIVE
RCSTA.7 = 1 ; USART ACTIVATION


RCIF var PIR1.5 ; RECEIVE INTERRUPT
STATUSLED var PORTD.0 ; LED'S NOTIFICATION OF "PROCESS RUNNING"
USERLED var PORTD.1 ; LED CONTROLLED BY USER

DELAY var word
DISCARD var byte ; Clean the RCREG

FRAME VAR BYTE[10]
FRAME = 0

PORTD = 0
PORTC = 0
PORTE = 0





ON INTERRUPT GOTO USART_INTERRUPT

LOOP:




toggle statusled
for delay = 1 to 5000 ; use a loop delay to ensure
pauseUS 5 ; getting interrupt as fast as
next ; possible

goto LOOP




DISABLE




USART_INTERRUPT:


WHILE RCIF = 1

RCREG = DISCARD

WEND


SERIN2 RX,84,[WAIT("E"),STR FRAME\10]


IF FRAME[0] = "E" THEN


IF FRAME[1] = "B" THEN

IF FRAME[2] = "9" THEN


IF FRAME[3] = "0" THEN



SELECT CASE FRAME[4]



CASE "S"

IF FRAME[7] = "0" THEN


IF FRAME[5] = "E" THEN


IF FRAME[8] = "0" THEN


IF FRAME[6] = "P" THEN

WHILE FRAME[9] = "0" AND CMD = 0 AND CONT < 36

PORTC.0 = 1
PAUSE 2500
CONT = CONT + 1

WEND

ENDIF

ENDIF

ENDIF

ENDIF


CASE "L"

IF FRAME[5] = "V" THEN

IF FRAME[8] = "0" THEN


IF FRAME[6] = "A" THEN


IF FRAME[9] = "0" THEN

while FRAME[7] = "L" AND CMD = 0 AND CONT < 36


PORTC.1 = 1
PORTC.3 = 1
PAUSE 2500
CONT = CONT + 1

WEND

ENDIF

ENDIF

ENDIF

ENDIF
CASE "D"

IF FRAME[5] = "V" THEN


IF FRAME[8] = "0" THEN

IF FRAME[6] = "A" THEN


IF FRAME[9] = "0" THEN

WHILE FRAME[7] = "L" AND CMD = 0 AND CONT < 36

PORTC.2 = 1
PORTC.3 = 1
PAUSE 2500
CONT = CONT + 1

WEND

ENDIF

ENDIF

ENDIF

ENDIF


END SELECT


ENDIF

ENDIF

ENDIF

ENDIF


REVERSE CMD
CMD = 0
REVERSE CMD


FRAME = 0

PORTC.0 = 0
PORTC.1 = 0
PORTC.2 = 0
PORTC.3 = 0
CONT = 0



WHILE RCIF = 1

RCREG = DISCARD


WEND

RESUME
ENABLE

END

mackrackit
- 8th February 2012, 08:22
A good rule with interrupts is to get in and out as fast as possible.
Try not doing all of the processing inside the interrupt routine and see if that helps.

mregisd
- 9th February 2012, 17:41
Thanks mackrackit! I modified the program and just put a flag that i created inside of the interrupt routine. So the interrupt set that flag = 1 and go back to Loop and then if this flag = 1, the program goto to another routine and do all the processing. But don't solve the problem.
I did a test that I remove the SERIN2 and leave all the IF's, CASE and WHILE inside the interrupt routine, then the problem was solved, I can interrupt normally. But i need to receive the data with 10 bytes when interrupt happens.
So, I'm stuck on that problem. =/