TODOPIC

Microcontroladores PIC => Lenguaje Basic para microcontroladores PIC => Mensaje iniciado por: egds en 27 de Septiembre de 2004, 05:43:00

Título: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: egds en 27 de Septiembre de 2004, 05:43:00
Sigo como siempre más que liado, cuando creo resolver algo me sale otro problema por otro lado.
El problema que me surge es que quiero recibir una serie de caracteres números incluidos, que no sé su tamaño exacto, aveces pueden llegar  10 caracteres, 15, etc...Lo único que sé es como empieza esta trama, empieza por:AgAAAAAAABA y luego continua.

Tiene alguien alguna solución?                                
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: MarquesSalsero en 27 de Septiembre de 2004, 09:22:00
A veces llegan 10 y otras 15, pero sabes cuantos han llegado? hay algun marcador de fin de trama?

Si es asi simplemente empieza a leer hasta que encuentres el fin de tramay ve poniendo los datos en una matriz sobredimensionada. Yo tengo un cacharrito en el que puedo recibir bloques de comandos que pueden ser desde 4 a 12 bytes y he creado un array de 12 bytes y luego simplemente busco hasta fin de trama.

A veces el problema es que el basic no es demasiado versatil en esos casos y necesitas leer caracter a caracter e ir poniendolos en el buffer de forma manual. Es una buena oprtunidad para implementar una rutina de recepcion por hardware ( si tu pic tiene USART ) con un buffer circular. Hay una cadena de mensajes iniciada por Abago en la que se trató el tema a fondo.

http://miarroba.com/foros/ver.php?foroid=8826&temaid=1673107

Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: egds en 30 de Septiembre de 2004, 14:31:00
Hola Marques,

Al final si que puedo saber mi final de trama, puesto que lo he planteado de otra manera. Cuando me llega la trama de datos, almaceno ésta en la memoria de la tarjeta SIM luego mediante el comando AT+CMGL="REC UNREAD" el móde me devuelve toda la información es decir:
+CMGL:1,"REC UNREAD","675434334",,"02/03/04,18:....ETC...la
trama recibida de datos y termina por Ok, es decir interrogando al módem el mensaje lo termina mediante Ok, por lo que sé por donde empieza la trama que le puedo llamar X, y llamando a la  longitud de la trama completa "y" la simple ecuación sería:
y=X+n-2(caracteres).
Ponme algún ejemplo tonto -si quieres claro- sobre como almacenar una matriz y poder leerla hasta llegar hasta el final de la trama.
Te lo agredecería mucho.
Un saludo.
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: MarquesSalsero en 01 de Octubre de 2004, 04:01:00
Mi gramatica no es muy buena asi que espero que lo de tonto es sobre el ejemplo

Yo el sistema que llevo usando desde hace mucho es el que se decribe en le cadena de mensajes que te indicaba un poco antes.

Primero crou un sistema de recepcion de datos por hardware byte a byte por interrupción, cavez que me llaga un caracter lo meto en un buffer FIFO circular de unos 10 a 64 bytes dependiendo de la aplicación y luego voy leyendo de ese buffer y evaluando los datos recibidos.

Si no te aclaras bien leyendo directamente del buffer lo que puedes hacer es crearte otra matriz independiente y copiar los datos del buffer circular a la matriz de trabajo.

p.ej
start:
leo dato buffre circular
dato=comienzo_de_cadena
si comienzo de cadena then bucle
sino comienzo de cadena apunto a siguiente caracter y start


bucle:
si caracter="O" and carater+1="k" entonces fin
copio caracter a matriz de trabajo
apunto a siguiente caracter
goto bucle

Por supuesto may que incrementar contadores de la posicion en la que estas leyendo del buffer circular, verificar si has llegado al final y en ese caso volver al principio, el contador de donde escribes en la matriz de trabajo, etc... pero esa es la parte mas sencilla de todo.

Yo uso esas rutinas que se indican en la mencionada cadena de mensajes y me funcionan perfectamente ( son de melabs asi que no tengo eningun merito, solo el de saber buscar ).
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: Abago en 03 de Octubre de 2004, 23:54:00
Como bien dice Marques, la mejor solución es al crear el buffer fifo...
en el tema que planteé hace unos meses, le dimos muchas vueltas al tema, y es la mejor solución...
creamos la rutina de recepción por interrupción de la usart que  almacene los datos en el buffer FIFO temporal y gestionamos la posición de los punteros de inicio y fin de buffer.

luego solo tenemos que hecer una pequeña rutina, que rastree el buffer en busca de comandos válidos...

Espero no haber liado el tema...
Ahora las cosas las veo muy claras, pero cuando empecé, la cosa no era tan sencilla....

De todos modos, en el tema, que plantea marques, hay cantidad de código que te pede ser de utilidad.  

Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: egds en 04 de Octubre de 2004, 11:36:00
Hola Abago,

He seguido todos tu post, en el dilema.
He intentado compilar algunos de tus programas y me han dado errores. La verdad es que estoy un poco despistado en cuanto a las interrupcciones. No sé si utilizar la orden INTERRUPT por asm o PBP. Estoy intentando hacerlo por PBP pero no veo ejemplos claros, incluso los de melania me dan error al compilarlos.
Mi problema es que cuando recibo un mensaje no sé cuantos bytes o caracteres me van a llegar por serie, a través de un módem GSM. Entonces tengo que crear una rutina que cuando compruebe que no hay ningun caracter más, almacene la trama en una variable para luego descodificarla.
Marques me ha ayudado mucho en el tema, pero me falta un pequeño empujón -más tiempo,jejejeje- para empezar ha entenderlo mejor.

Tienes alguna solución?.¿Cómo lo harías tú?,porque de otra forma que no sea por interrupción serie no la hay verdad?

Un saludo a todos los que lean este mensaje.
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: MarquesSalsero en 04 de Octubre de 2004, 14:47:00
Yo tengo el sistema de entrada por interrupción funcionando en mi casa desde hace mas de un año y no ma da ningun problema, de hecho decodifico directamente desde el buffer de entrada.

Porque no nos muestras tu programa a ver si vemos por donde anda el error?

ya sabes que cuatro ojos ven mas que dos y si son varias docenas las que miran pues imaginate.

Lo que no te ayuda a ti lo mas minimo, porque nosotros no podemos decirte nada, es si solamente nos dices que "te da error al compilar".

Eso es tan abstracto que o eres pediatra ( eso si que es jodido ) o no hay manera de saber cual puede ser el error.
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: Abago en 04 de Octubre de 2004, 14:57:00
La solución que te ha dado marques, es la mejor que se te pueda ocurrir...
el tema, está en que tienes que pensar que tu programa va a ir siempre mas rápido que el puerto serie, y si te creas un buffer RX lo suficientemente grande, no tendrás problemas en ir decodificando la trama en tiempo real...
puedo decir, que incluso tendrás que hacer retención al programa principal, porque el buffer lo limpia hechando leches...

en el siguiente link, aparece el código que marques en su día me pasó, y en el que puedes basar tu programa...

http://www.melabs.com/resources/samples/x1/pbp/serbufAx.bas

solo tienes que modificarlo a tu gusto y eliminar la parte en la que se trabaja con el transpaso de datos al display...

y como último, creo que tienes que hecharle un ojo a
buffer_size     CON     32  
el valor depende de los datos que tengas que almacenar en el buffer....

de todos modos ves estudiandote el código del link, y te iremos ayudando en lo que esté en nuestras manos....

Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: egds en 05 de Octubre de 2004, 13:00:00
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.
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: egds en 05 de Octubre de 2004, 13:36:00
Perdonad 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:

Bueno ahora, -es que no me lo creo-, no sé si es de coña o que, pero cuando envio cualquier cadena de menos de 32 caracteres me la saca por puerto serie. eso esta bien?. Voy por el buen camino.?

Griacias y no haced caso al mensaje anterior, no quiero liar a la gente que lea los mensajes.
BUeno ya me contaís.


Saludos.
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: MarquesSalsero en 05 de Octubre de 2004, 13:54:00
A ver por partes

El -INCLUDE "bs2defs.bas"- si no te es absolutamente necesario no lo pongas, es mejor que tu definas tus aliases

Si defines -DEFINE HSER_RCSTA 90h- y -DEFINE HSER_TXSTA 24h- es mejor definir -SPBRG=$129- que -DEFINE HSER_BAUD 9600- no se porque pero a mi a veces me ha dado problemas.

por cierto puedes poner:

RCSTA=$90
TXSTA=$24
SPBRG=$129

y funciona correctamente

La parte donde procesas los errores:

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

me parece confusa y no se que tel funcionara, pero es axactamente lo mismo que:

error: " Display error message if buffer has overrun
IF errflag.1 Then" Determine the error  
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

en cuanto a la logica y el descomentado del ELSE y ENDIF, pero ademas... ¿No estas usando HSEROUT?

Luego la parte:

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

me parece aun mas confusa ya que no consigo entenderla, tienes un

errflag=1

al principio y al final ¿?

Pero, y eso es lo mas importante a mi parecer , tienes un bucle cerrado -loop- del que no sales nunca para evaluar si tienes algun carcter para imprimir.

No tienes ninguna manera de llegar a la rutina display.

el bucle loop deberia ser mas o menos asi:

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
If index_in <> index_out then display "**** LO VES
goto loop " instead of one long pause

display: " dump the buffer to the LCD
IF errflag Then error " Handle error if needed
GoSub getbuf
hserout [bufchar] " Get a character from buffer
If index_in = index_out Then Loop " loop if nothing in buffer
GoTo display " Check for more characters in buffer


asi por encima eso es lo que he visto si me doy cuenta de algo mas te pongo otro mensaje.
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: MarquesSalsero en 05 de Octubre de 2004, 14:00:00
Escrito originalmente por egds
Perdonad 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.


En lo que yo he tardado en escribir la contestacion te has dado cuenta, pero mira otros comentarios que te hago que te pueden despejar alguna otra cosilla.

Ademas aunque vas por el buen camino no des nada por bueno sin forzarle todos los errores posibles.
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: egds en 05 de Octubre de 2004, 14:31:00
Gracias Marques,

La verdad es que este foro es de los más activos que yo he visto hasta ahora, asi da gusto. Y más cuando encima te ayudan y te apollan.
La verdad es que poco a poco voy dando pasitos, aunque aun me queda bastante por recorrer. He depurado un poquito el código que he puesto antes. Ahora me saca bien los errores por Overflow.

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.

BUeno voy a ver si ceno y luego me conectaré un ratillo, a ver que dice Abago que estará poniendo copillas, a ver si un día nos dice donde esta su bar y cuando vaya a Madrid me paso.
Que aún estoy en la oficina y la mujer me ha llamado dos veces al móvil, pero cuando te enganchas quieres mas y mas....

Voy a cerrar ya el portatil y dejarlo descansar un poquito.

salu2.

Saludos y gracias
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: Abago en 06 de Octubre de 2004, 11:13:00
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.



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...
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: egds en 06 de Octubre de 2004, 13:06:00
Escrito originalmente por Abago
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.



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...


He intentado insertar algo parecido a lo que tú hacias en tu código
para guardar o almacenar datos en la epromm con el getbuf,cont, write,cont=cont+1,bufchar, etc... Pero no logro guadar datos en el bufchar, qué puede ser?
Es decir, cuando intento leer la variable bufchar no me lee nada, en cambio si leo datos del bufer y lo sco con hserout me muestra todo.
Saludois
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: Abago en 06 de Octubre de 2004, 20:31:00
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





Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: egds en 07 de Octubre de 2004, 04:27:00
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








Estimado Abago,

El código que me has mostrado anteriormente, hace lo mismo que éste que te pongo acontinuación, Es decir cuando llega algo por el Rx sale la interrupción, y el tx hace eco de lo que le he mandado con la interrupción. Eso me lo hace, lo que quiero es ver como puedo gestionar el bufchar para ir a etiquetas y que hagan algo: como poner un puerto a nivel alto, poder guardar en la epromm datos para luego gestionar estos, etc...
***********************************************
"Mi código: parpadea el led, y genera interrución por puerto serie mostrando en pantalla el texto que escribes.
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
cont            var byte          
errflag         VAR     BYTE       " Holds error flags

" Initialize variables

index_in = 0
index_out = 0
i = 0

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    
             

hserout[BUFCHAR]
goto Loop
display:        
                       
                IF errflag Then error
                   
                If index_in = index_out    Then Loop       " loop if nothing in buffer
"gosub getbuf ":
 "leemos buffer hasta encontrar las primeras "
gosub getbuf ""
write cont , bufchar



               
               
               
               
               
               
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:
                hserout["Buffer Overrun"] " Display buffer error on line-2
        "Else
                hserout["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
**********************************************

Este el código.
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: Abago en 07 de Octubre de 2004, 22:27:00
Tal y como lo planteas, es muy facil...
solo tienes que hacerte un pequeño interprete de comandos y en vez de usar getbuf para leer el dato del buffer, y posteriormente enviarlo al display, o al terminal... (lcdout / hserout).
solo tienes que usar getbuf
luego comparar bufchar con las posibilidades que tengas en mente, y posteriormente, saltar a la subrrutina que necesites...

sería algo así...

gosub getbuf
select case bufchar
case 1
 gosub opc1
case 2
 gosub opc2
case 3
 gosub opc3
case 4
 gosub opc4
case else
 gosub opce
end select

bueno, digo que sería algo así, pero me refiero a la filosofía...
ahora solo queda adaptar la idea a tus necesidades....
pero he de decirte, que has de centrar mas tu idea, y debes hacerte una lista de las acciones y los comandos internos que vas a necesitar....

Entiendo lo que estás intentando hacer,  y vas por muy buen camino, pero es un proyecto que no es nada sencillo....
así que no te desanimes.... y sobre todo dale muchas vueltas al coco...
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: MarquesSalsero en 08 de Octubre de 2004, 03:36:00
Estimado egds, como bien dice abago, para estar comenzando con esto te has metido en un proyecto demasiado avanzado y te está costando mucho por eso.

Yo siempre digo que cuando uno esta aprendiendo ha de ir pasito a pasito y dejando que lo aprendido repose, se asiente bien y pase a ser parte intuitiva de nuestro sistema mental.

No puedes ponerte de cabeza y para empezar a poner en marcha un proyecto en el que necesitas hacer tantas cosas de forma casi simultanea.

Deberias ir paso a paso y comprendiendo bien lo que haces. Una vez que hayas conseguido recibir los caracteres por el puerto serie con interrupción en Basic intentalo en ensamplador, es muchisimo mas rapido y seguro ( yo lo tengo funcionando en casa 24 horas al dia y no ha perdido un caracter en mas de un año )

despues deberias intentar el realizar el eco pero haciendo algo con los caracteres, por ejemplo transformando las mayusculas en minusculas y viceversa.

una vez conseguido eso intenta que en funcion del caracter recibido el pic haga algo simple y luego algo mas complejo, por ejemplo que para ON1 encienda el led uno, para ON2 encienda el dos etc..

asi poco a poco iras aprendiendo y llegaras con la ayuda de los demas a dominar el tema. pero si te metes de cabeza a morder mas de lo que te cabe en la boca puedes atragantarte y tomarle mania a los PICs, a mi me paso eso cuando intente programas en Pascal para Macintosh y luego nunca mas lo volví a intentar. De hecho si alguien me habla de pascal le muerdo

Asi que ve paso a paso y no te obsesiones con conseguir algo tan complejo en tus primeros pasos y si te cuesta un año conseguirlo pero lo has hecho aprendiendo y comprendiendo bien lo que has hecho, habras puesto unas bases buenisimas para avanzar luego a pasos agigantados. Por contra , si lo consigues a la primera robando trozos de codigo de aqui y de alla y con ayudas que no llegas a entender pero te funcionan, no solo no habras aprendido sino que para modificar luego cualquie cosa te costara muchisimo... si lo consigues.
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: MarquesSalsero en 08 de Octubre de 2004, 12:52:00
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.
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: egds en 10 de Octubre de 2004, 11:49:00
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.

Gracias Marques,

NO te preocupes, ya me has ayudado bastante. El problema que tengo y creo que ya me podría valer por mí mismo, es que según el código que tengo, intruzco un caracter y me va a la interrupción y lo hace todo bien.
Lo que pasa es que no sé como almacenar en la variable bufchar los caracteres que lleguen por la USART, y luego posteriormente almacenarlos en la epromm de mi PIC, para luego según lo guardado pueda manipularlos libremente.
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, lo que quiero es que en vez de sacarlos por serie, alamacenarlo en la epromm y guardarla como dato1 -por ejemplo-, esperar a recibir otra trama y guardarla como dato2, y luego poder manipular estos datos de la epromm a mi libre elección. Después tendría que descodificar mediante un algoritmo que ya he creado y funciona bien, cada dato de la epromm y hacer lo que proceda. 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
**********************************************
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
errflag         VAR     BYTE  

    " Holds error flags

" Initialize variables

index_in = 0
index_out = 0


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
               
display:        
                       
                IF errflag Then error
                   
                If index_in = index_out    Then Loop       " loop if nothing in buffer
"gosub getbuf ":
 "leemos buffer hasta encontrar las primeras "
gosub getbuf ""
HSEROUT[BUFCHAR]
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:
                hserout["Buffer Overrun"] " Display buffer error on line-2
        "Else
                hserout["USART Overrun"]  " Display usart error on line-2
        "End If
       
               
       
        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
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: MarquesSalsero en 10 de Octubre de 2004, 13:25:00
en bufchar lo que vas atener cada vez es unicamente un caracter que es el que en ese momento estas leyendo de la fifo de entrada.

Puedes crearte otras matrices de datos

mens1[6]
mens2[6]
mens3[6]

etc y luego a medida que vas leyendo del fifo ir metiendolo en estas variables

eso lo puedes hacer con bucles simples.
Título: RE: Cómo almacenar en una variable una trama con longitud descon.
Publicado por: Abago en 10 de Octubre de 2004, 18:20:00
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



en primer lugar, con la función getbuf, lees una posición del buffer fifo, y lo almacenas en bufchar...
pero bufchar, es una variable byte....
si como dices el buffer, contiene el valor AgaaaMN=
al hacer
gosub getbuf
hserout[bufchar]

en el terminal, te aparecería la letra A

--

el segundo problema, es el sistema de almacenamiento de datos en la eeprom...
gosub getbuf
write 10,bufchar

en la posición 10 de la eeprom, tendrás el valor ascii de la A...

espero que por hay estén los tiros... porque yo también tube que darle muchas vueltas al coco, para entender ciertas cosas...