BUeno os cuento como va el tema. Me ha pasado una cosa rarísima.
Al final me he declinado por hacerlo con la orden ON INTERRUPT de PBP. He modificado un poco el programa como pongo abajo, y me ha funcionado. Cada vez que enviaba una trama de datos ASCII p cadena de caracteres me la devolvía por la consola con la orden hserout[bufchar], era lo que quería, según la trama de datos sin tener que estar pendiente de la longitud de la misma.
BUeno os pongo el código:
***********************************************
INCLUDE "bs2defs.bas"
DEFINE LOADER_USER 1
DEFINE OSC 20
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 24h
DEFINE HSER_BAUD 9600
ADCON1 = 6 " Set PortA to digital operation
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 PORTB.7 " Alias LED to PORTB.7
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
codigo VAR BYTE " Holds error flags
" Initialize variables
index_in = 0
index_out = 0
i = 0
col = 1
Pause 100 " Wait for LCD to start
"LCDOut $fe,1 " Clear LCD
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:
High LED " Turn on LED connected to PORTD.0
For i = 0 To 250 " Delay for .5 seconds (250*2mS)
Pause 2 " Use a short pause within a loop
Next i " instead of one long pause
Low LED " Turn off LED connected to PORTD.0
For i = 0 To 250 " Delay for .5 seconds (250*2mS)
Pause 2 " Use a short pause within a loop
Next i
goto loop " instead of one long pause
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
hserout [bufchar] " Get a character from buffer
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
IF errflag.1 Then error1 " Determine the error
error1:
serout2 portc.6,84,["Buffer Overrun"] " Display buffer error on line-2
"Else
serout2 portc.6,84,["USART Overrun"] " Display usart error on line-2
"End If
"LCDOut $fe,2 " Send the LCD cursor back to line-1 home
"For i = 2 To col " Loop for each column beyond 1
"LCDOut $fe,$14 " Move the cursor right to the right column
"Next i
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
"disable
serialin:
HIGH PORTB.3
" Buffer the character receive
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]]
LOW PORTB.3
IF RCIF then serialin " Read USART and store character to next empty locationIf RCIF Then serialin " Check for another character while we"re here
Resume
enable " Return to program
buffer_error:
errflag = 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 = 1 " Set the error flag for hardware
Resume " Return to program
End
************************************************
Pues lo hecho asi y me ha funcionado. Pero al modifcarlo ya no funciona, es muy curioso. Yo me pregunto a ver si se ha quedado el buffer de tanto programarlo colapsado, ya que he intentado meter el comando write. Esa ha sido la modificación.
También como vereís en serialin he puesto que se encienda un led cuando entre en la interrupcón, y se enciende y se apaga como. Por lo que deduzco que la interrrupción la crea, el problema es que no saca por hserout[bufchar] la cadena de caracteres. Os prometo que me ha funcionado antes.
Qué puede ser?
He intentado con los enable y disable cambiandolos pero ni asi.
He pasado de este estado
a este en 10 minutos.
Que disilusión, pensaba que estaba hecho ya.
Por cierto estoy con un PIC16F876.
Saludos.