Escrito originalmente por egdsPerdonad ya esta solucionado
resulta que no había quitado el Loop de la rutina de al principio, y claro no entraba en la etiqueta display:
Saludos.
Escrito originalmente por egds
Ahora lo que necesito es almacenar los datos en una matriz y luego procesarlos, segun venga la información ya que ahora la longitud de la trama no me preocupa, aunque se pueden meter el comando Skip y wait en la interrupción por USART no?.
Es que necesito que cuando vengan las tramas gurdar solo lo que me interesa.
Escrito originalmente por AbagoEscrito originalmente por egds
Ahora lo que necesito es almacenar los datos en una matriz y luego procesarlos, segun venga la información ya que ahora la longitud de la trama no me preocupa, aunque se pueden meter el comando Skip y wait en la interrupción por USART no?.
Es que necesito que cuando vengan las tramas gurdar solo lo que me interesa.
tienes un pequeño atasco de información...
el skip y el wait, se usan con el serout/hserout....
al usar la interrupción, tendrás que gestionar tus propias paradas y esperas de datos con tu propio código....
esto es una de las cosas que te da un gran juego...
mientras tu código principal va leyendo los datos del buffer, e interpretándolos, el handler de interrupción de la usart va llenando ese mismo buffer...(con el buffer, no me refiero al buffer de la usart, que creo recordar que es de 2 bytes... sino que me refiero a la matriz buffer fifo que tambien creo recordar que está definida a 32 bytes o 32 caracteres ascii)
es muy probable, que a tu programa principal, le de tiempo a ir interpretando los datos que tiene almacenados en el buffer fifo en tiempo real, sin necesidad de tener que crear otra matriz temporal...
ten en cuenta que el buffer fifo, es una matriz, que tiene dos punteros que indican el inicio y el fin de datos a leer...
Espero no haberte liado demasiado con tanta matriz...
a ver si tengo un ratito. y me empapo lo que hace el código que dejaste anteriormente...
Un saludo
PD: intenté responderte a las 6:00 de la madrugada, pero no fuí capaz...
miarroba, o mejor dicho laarroba, se cae cada dos por tres...
Codigo:
" Define interrupt handler
DEFINE INTHAND myint
" Configure internal registers
DEFINE HSER_RCSTA 90H
DEFINE HSER_TXSTA 20H
DEFINE HSER_BAUD 9600
LED VAR PORTB.0 " Alias LED to PORTD.0
CREN VAR RCSTA.4 " Alias CREN (Serial receive enable)
"Variables for saving state in interrupt handler
wsave VAR BYTE $70 system " Saves W
ssave VAR BYTE bank0 system " Saves STATUS
psave VAR BYTE bank0 system " Saves PCLATH
fsave VAR BYTE bank0 system " Saves FSR
buffer_size CON 32 " Sets size of ring buffer
buffer VAR BYTE[buffer_size] " Array variable for holding received characters
index_in VAR BYTE bank0 " Pointer - next empty location in buffer
index_out VAR BYTE bank0 " Pointer - location of oldest character in buffer
errflag VAR BYTE bank0 " Error flag
bufchar VAR BYTE " Stores the character retrieved from the buffer
i VAR BYTE " Loop counter
GoTo start " Skip around interrupt handler
" Assembly language INTERRUPT handler
Asm
myint
; Uncomment the following if the device has less than 2k of code space
;movwf wsave ; Save W
;swapf STATUS, W ; Swap STATUS to W (swap avoids changing STATUS)
;clrf STATUS ; Clear STATUS
;movwf ssave ; Save swapped STATUS
;movf PCLATH, W ; Move PCLATH to W
;movwf psave ; Save PCLATH
; Save the FSR value for later
movf FSR, W ; Move FSR to W
movwf fsave ; Save FSR
; Check for hardware overrun error
btfsc RCSTA,OERR ; Check for usart overrun
GoTo usart_err ; jump to assembly error routine
; Find in which bank the compiler put buffer, and set IRP
IF (_buffer > 0FFh) ; Find the bank where buffer is located
bsf STATUS,IRP ; If bank 2 or 3 set IRP
Else
bcf STATUS,IRP ; If bank 0 or 1 clear IRP
EndIF
; Test for buffer overrun
incf _index_in, W ; Increment index_in to W
subwf _index_out, W ; Subtract indexes to test for buffer overrun
btfsc STATUS,Z ; check for zero (index_in = index_out)
GoTo buffer_err ; jump to error routine if zero
; Increment the index_in pointer and reset it if it"s outside the ring buffer
incf _index_in, F ; Increment index_in to index_in
movf _index_in, W ; Move new index_in to W
sublw _buffer_size-1 ; Subtract index_in from buffer_size-1
btfss STATUS,C ; If index_in => buffer_size
clrf _index_in ; Clear index_in
; Set FSR with the location of the next empty location in buffer
movlw Low _buffer ; Get the location of buffer[0]
addwf _index_in, W ; Add index_in to point to next empty slot
movwf FSR ; Store pointer in FSR
; Read and store the character from the USART
movf RCREG, W ; Read the received character
movwf INDF ; Put the received character in FSR location
; Restore FSR, PCLATH, STATUS and W registers
finished
movf fsave, W ; retrieve FSR value
movwf FSR ; Restore it to FSR
movf psave, W ; Retrieve PCLATH value
movwf PCLATH ; Restore it to PCLATH
swapf ssave, W ; Retrieve the swapped STATUS value (swap to avoid changing STATUS)
movwf STATUS ; Restore it to STATUS
swapf wsave, F ; Swap the stored W value
swapf wsave, W ; Restore it to W (swap to avoid changing STATUS)
retfie ; Return from the interrupt
; Error routines
buffer_err ; Jump here on buffer error
bsf _errflag,1 ; Set the buffer flag
usart_err ; Jump here on USART error
bsf _errflag,0 ; Set the USART flag
movf RCREG, W ; Trash the received character
GoTo finished ; Restore state and return to program
EndAsm
start:
" Initialize variables
index_in = 0
index_out = 0
errflag = 0
INTCON = %11000000 " Enable interrupts
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
Pause 500 " Pause 500mS
Low LED " Turn off LED connected to PORTD.0
Pause 500 " Pause 500mS
display: " dump the buffer to the LCD
IF errflag Then error " Goto error routine if needed
IF index_in = index_out Then loop " loop if nothing in buffer
GoSub getbuf " Get a character from buffer
hserout [bufchar,10,13] " Send the character to LCD
GoTo display " Check for more characters in buffer
" Get a character from the buffer
getbuf: " Move the next character in buffer to bufchar
intcon = 0 " Disable interrupts while reading buffer
index_out = index_out + 1 " Increment index_out pointer (0 to 63)
IF index_out => buffer_size Then index_out = 0 " Reset pointer if outside buffer
bufchar = buffer[index_out] " Read buffer location(index_out)
INTCON = %11000000 " Enable interrupts
Return
" Display an error
error: " Display error message
INTCON = 0 " Disable interrupts while in the error routine
IF errflag.1 Then
hserout ["Buffer Overrun",10,13]
Else
Hserout ["USART Overrun",10,13]
EndIF
errflag = 0 " Reset the error flag
CREN = 0 " Disable continuous receive to clear hardware error
CREN = 1 " Enable continuous receive
INTCON = %11000000 " Enable interrupts
GoTo display " Carry on
End
Escrito originalmente por Abago
He hecho las pertinentes modificaciones al código, para que en teoría... (y digo en teoría, porque no lo he simulado en hard)...
el led se quede parpadeando cada 500 ms
y el buffer se descargue mediante hserout por el pin tx
a groso modo, el rx lo gestiona la interrupción de la usart, y el tx lo gestiona el comando hserout...
será algo así como un echo de lo que escribas en la pantalla del hiperterminal...Codigo:
" Define interrupt handler
DEFINE INTHAND myint
" Configure internal registers
DEFINE HSER_RCSTA 90H
DEFINE HSER_TXSTA 20H
DEFINE HSER_BAUD 9600
LED VAR PORTB.0 " Alias LED to PORTD.0
CREN VAR RCSTA.4 " Alias CREN (Serial receive enable)
"Variables for saving state in interrupt handler
wsave VAR BYTE $70 system " Saves W
ssave VAR BYTE bank0 system " Saves STATUS
psave VAR BYTE bank0 system " Saves PCLATH
fsave VAR BYTE bank0 system " Saves FSR
buffer_size CON 32 " Sets size of ring buffer
buffer VAR BYTE[buffer_size] " Array variable for holding received characters
index_in VAR BYTE bank0 " Pointer - next empty location in buffer
index_out VAR BYTE bank0 " Pointer - location of oldest character in buffer
errflag VAR BYTE bank0 " Error flag
bufchar VAR BYTE " Stores the character retrieved from the buffer
i VAR BYTE " Loop counter
GoTo start " Skip around interrupt handler
" Assembly language INTERRUPT handler
Asm
myint
; Uncomment the following if the device has less than 2k of code space
;movwf wsave ; Save W
;swapf STATUS, W ; Swap STATUS to W (swap avoids changing STATUS)
;clrf STATUS ; Clear STATUS
;movwf ssave ; Save swapped STATUS
;movf PCLATH, W ; Move PCLATH to W
;movwf psave ; Save PCLATH
; Save the FSR value for later
movf FSR, W ; Move FSR to W
movwf fsave ; Save FSR
; Check for hardware overrun error
btfsc RCSTA,OERR ; Check for usart overrun
GoTo usart_err ; jump to assembly error routine
; Find in which bank the compiler put buffer, and set IRP
IF (_buffer > 0FFh) ; Find the bank where buffer is located
bsf STATUS,IRP ; If bank 2 or 3 set IRP
Else
bcf STATUS,IRP ; If bank 0 or 1 clear IRP
EndIF
; Test for buffer overrun
incf _index_in, W ; Increment index_in to W
subwf _index_out, W ; Subtract indexes to test for buffer overrun
btfsc STATUS,Z ; check for zero (index_in = index_out)
GoTo buffer_err ; jump to error routine if zero
; Increment the index_in pointer and reset it if it"s outside the ring buffer
incf _index_in, F ; Increment index_in to index_in
movf _index_in, W ; Move new index_in to W
sublw _buffer_size-1 ; Subtract index_in from buffer_size-1
btfss STATUS,C ; If index_in => buffer_size
clrf _index_in ; Clear index_in
; Set FSR with the location of the next empty location in buffer
movlw Low _buffer ; Get the location of buffer[0]
addwf _index_in, W ; Add index_in to point to next empty slot
movwf FSR ; Store pointer in FSR
; Read and store the character from the USART
movf RCREG, W ; Read the received character
movwf INDF ; Put the received character in FSR location
; Restore FSR, PCLATH, STATUS and W registers
finished
movf fsave, W ; retrieve FSR value
movwf FSR ; Restore it to FSR
movf psave, W ; Retrieve PCLATH value
movwf PCLATH ; Restore it to PCLATH
swapf ssave, W ; Retrieve the swapped STATUS value (swap to avoid changing STATUS)
movwf STATUS ; Restore it to STATUS
swapf wsave, F ; Swap the stored W value
swapf wsave, W ; Restore it to W (swap to avoid changing STATUS)
retfie ; Return from the interrupt
; Error routines
buffer_err ; Jump here on buffer error
bsf _errflag,1 ; Set the buffer flag
usart_err ; Jump here on USART error
bsf _errflag,0 ; Set the USART flag
movf RCREG, W ; Trash the received character
GoTo finished ; Restore state and return to program
EndAsm
start:
" Initialize variables
index_in = 0
index_out = 0
errflag = 0
INTCON = %11000000 " Enable interrupts
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
Pause 500 " Pause 500mS
Low LED " Turn off LED connected to PORTD.0
Pause 500 " Pause 500mS
display: " dump the buffer to the LCD
IF errflag Then error " Goto error routine if needed
IF index_in = index_out Then loop " loop if nothing in buffer
GoSub getbuf " Get a character from buffer
hserout [bufchar,10,13] " Send the character to LCD
GoTo display " Check for more characters in buffer
" Get a character from the buffer
getbuf: " Move the next character in buffer to bufchar
intcon = 0 " Disable interrupts while reading buffer
index_out = index_out + 1 " Increment index_out pointer (0 to 63)
IF index_out => buffer_size Then index_out = 0 " Reset pointer if outside buffer
bufchar = buffer[index_out] " Read buffer location(index_out)
INTCON = %11000000 " Enable interrupts
Return
" Display an error
error: " Display error message
INTCON = 0 " Disable interrupts while in the error routine
IF errflag.1 Then
hserout ["Buffer Overrun",10,13]
Else
Hserout ["USART Overrun",10,13]
EndIF
errflag = 0 " Reset the error flag
CREN = 0 " Disable continuous receive to clear hardware error
CREN = 1 " Enable continuous receive
INTCON = %11000000 " Enable interrupts
GoTo display " Carry on
End
Escrito originalmente por MarquesSalsero
Huy!!!!! pues eso es intrusismo profesional
De todos modos el procedimiento ha de ser el mismo, porque luego tendras que darle a tu cliente todo el software con su codigo fuente comentado y demas para que en un futuro pueda darle soporte o modificarlo segun cambie la tecnologia.
En lo que te voy a poder ayodar poco es en el tema de rutinas avanzadas de parseado, en eso siempre he estado algo perdido.
Escrito originalmente por egds
Imagínate que llega la siguiente trama por el puerto serie "AgaaaMN=", pues bien esto es lo que me sacaría el --hserout[bufchar] sin problemas
En fín te dejo el código que tengo, pero he intentado guardar lo almacenado en el bufchar de mil maneras y nada, solo me muestra cosas raras, osea NADA