Autor Tema: Apoyo para rutina en FSR  (Leído 3898 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Pinolillo16

  • PIC18
  • ****
  • Mensajes: 324
Apoyo para rutina en FSR
« en: 03 de Febrero de 2016, 16:02:08 »
Que tal amigos acudo a ustedes para solicitar su ayuda. Veran estoy trabajando en unas pequeñas practicas y quiero manejar tablas con direccionamiento indirecto para optimizar codigo.

Código: ASM
  1. MENSAJE_RELEVADORES
  2.                 MOVLW   LOW (ACTIVANDO_RELEVADORES)
  3.                 MOVWF   FSR0L
  4.                 MOVLW   HIGH(ACTIVANDO_RELEVADORES)
  5.                 MOVWF   FSR0H
  6.                 MOVLW   .17
  7.                 MOVWF   CONTADOR_MENSAJES
  8. SENDING_TEXT
  9.                 MOVF    INDF0,W
  10.                 CALL    ENVIAR_DATO
  11.                 INCF    FSR0L,F
  12.                 CALL    RET_100ms
  13.                 DECFSZ  CONTADOR_MENSAJES,F
  14.                 GOTO    SENDING_TEXT
  15.                 RETURN 
  16. ;***************************************************************************************************
  17. ;*********************** DECLARACION DE MENSAJES PARA OPTIMIZACION DE CÓDIGOS **********************
  18. ;***************************************************************************************************
  19.  
  20.         ACTIVANDO_RELEVADORES: DT "Activando Reles:";

Bueno este es el codigo segun lei en el Manual de MPASM de microchip, y por recomendacion anterior de KillerJC las direcciones de los FSR son correctas, pero el registro INDFx no me carga bien el dato. Quisiera saber que estoy haciendo mal.

Saludos

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Apoyo para rutina en FSR
« Respuesta #1 en: 03 de Febrero de 2016, 16:35:23 »
Lo raro es que a mi me funciona (Probado en un PIC16F1707 en simulacion). Lo que si, si quisiera hacerlo extensible a cualquier mensaje y no preocuparme por el largo del mismo. haria algo asi:

Código: ASM
  1. MENSAJE_RELEVADORES:
  2.                 MOVLW   HIGH(ACTIVANDO_RELEVADORES)
  3.                 MOVWF   FSR0H
  4.                 MOVLW   LOW (ACTIVANDO_RELEVADORES)
  5.                 MOVWF   FSR0L
  6.  
  7. ; Funcion general para cualquier texto:
  8.  
  9. SENDING_TEXT:
  10.                 MOVIW   FSR0++
  11.                 BTFSC   STATUS,Z
  12.                 RETURN
  13.                 CALL    ENVIAR_DATO
  14.                 CALL    RET_100ms
  15.                 GOTO    SENDING_TEXT
  16.  
  17. ;***************************************************************************************************
  18. ;*********************** DECLARACION DE MENSAJES PARA OPTIMIZACION DE CÓDIGOS **********************
  19. ;***************************************************************************************************
  20.  
  21. ACTIVANDO_RELEVADORES: DT "Activando Reles:", 0x00;

De esa forma solo cargo el comienzo, es decir el puntero y le digo que continue.
Ademas la funcion MOVIW hace que el FSR0 se incremente en el espacio de 16bits conformador por los 2 registros.
Mientras que el INCF solo lo haria con el FSR0L y deberias checkear si existe un overflow para incrementar el otro registro, mas que nada por si se pasa de pagina.

Obviamente esto es en el PIC16F1707 que posee esta caracteristica de poder acceder a la FLASH a traves del acceso indirecto. Otro PIC tal ves no posea esta caracteristica, como estuviste usando esta forma de acceso imagino que es lo que utilizas.

PD: En el MPLAB el INDF0 siempre aparece con el valor 0x00, pero si te fijas en W se carga el valor correcto a la letra:

"Activando Reles:" es igual (en hexa) a:
41 63 74 69 76 61 6e 64 6f 20 52 65 6c 65 73 3a

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re:Apoyo para rutina en FSR
« Respuesta #2 en: 03 de Febrero de 2016, 16:51:20 »
Sería importante que dijeras qué microcontrolador estás usando. Como bien mencionó KILLERJC, eso sólo servirá en micros que puedan acceder también a la memoria FLASH mediante direccionamiento indirecto.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Pinolillo16

  • PIC18
  • ****
  • Mensajes: 324
Re:Apoyo para rutina en FSR
« Respuesta #3 en: 03 de Febrero de 2016, 17:49:29 »
Cierto, se me olvido. El codigo en el 16F1707 me funciona bien pero lo quiero implementar para un 18F4620.

Saludos

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re:Apoyo para rutina en FSR
« Respuesta #4 en: 03 de Febrero de 2016, 17:55:04 »
El problema es que el 18F4620 no permite leer la FLASH desde el direccionamiento indirecto. Tenés que leerlo como se explica en la sección 7.3 del datasheet del 18F4620. Y tener cuidado con la config de los fusibles ya que pueden impedir la lectura de tablas algunos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Apoyo para rutina en FSR
« Respuesta #5 en: 03 de Febrero de 2016, 18:22:26 »
Como dice BrunoF. En ese PIC tenes otras instrucciones para leer las tablas, no es muy distinto de lo que tenes, solo cambian un poco de cosas. Cuando posea un tiempito edito esta respuesta con un codigo.

Desconectado Pinolillo16

  • PIC18
  • ****
  • Mensajes: 324
Re:Apoyo para rutina en FSR
« Respuesta #6 en: 03 de Febrero de 2016, 21:02:41 »
Muchas gracias Bruno, KillerJC, lei esa parte del datasheet donde me indica las instrucciones TLBR y TLBW creo que si me sirve. De hecho ya me funciono bien solo que, por ahi tengo un dato extra en cada lectura. Anexo el código implementado para la lectura de la tabla y una imagen de los datos obtenidos.

Código: ASM
  1. MENSAJE
  2.                 MOVLW   UPPER (LEER_MAX)
  3.                 MOVWF   TBLPTRU
  4.                 MOVLW   HIGH(LEER_MAX)
  5.                 MOVWF   TBLPTRH
  6.                 MOVLW   LOW(LEER_MAX)
  7.                 MOVWF   TBLPTRL
  8.                 MOVLW   .21
  9.                 MOVWF   CONTADOR_MENSAJES
  10. SENDING_TEXT
  11.                 TBLRD*+                                         ; read into TABLAT and increment
  12.                 CALL    RET_100ms
  13.                 MOVF    TABLAT,W                        ; get data
  14.                 CALL    ENVIAR_DATO
  15.                 DECFSZ  CONTADOR_MENSAJES,F
  16.                 GOTO    SENDING_TEXT
  17.                 RETURN 
  18. ;***************************************************************************************************
  19. ;*********************** DECLARACION DE MENSAJES PARA OPTIMIZACION DE CÓDIGOS **********************
  20. ;***************************************************************************************************
  21.  
  22.         LEER_MAX: DT "Reading Temperature:";

De acuerdo a lo que necesito programar, leo la tabla posterior a leerla se realiza un incremento en la misma tabla enseguida mando el dato obtenido a la LCD. En efecto lo hace pero como podeis ver el siguiente dato es un caracter extraño.

Que puedo hacer amigos?

Saludos

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Apoyo para rutina en FSR
« Respuesta #7 en: 03 de Febrero de 2016, 22:30:33 »
Eso por que la arquitectura son distintas.

Por su parte el PIC16 tiene una memoria de instruccion de 14 bits, lo cual solo te queda para 1 byte y 6bit mas, mientras que el PIC18 tiene una memoria de instrucciones de 16bits y podrias aprovechar los 2 bytes

Es decir cada instruccion ( que ocupe un solo espacio ) ocuparia eso..

Ahora vos con la directiva DT. lo que creas es un RETLW de cada valor que tenes.. ejemplo

Código: ASM
  1. DT "Read"

en memoria es lo mismo que:

Código: ASM
  1. RETLW 'R'
  2. RETLW 'e'
  3. RETLW 'a'
  4. RETLW 'd'

Esto era util para cuando el micro NO poseia alguna forma de leer desde la FLASH, y se creaban tablas las cual indexaban a estos RETLW, en el caso del PIC16F1707 funciona por que el opcode del RETLW k es

Código: [Seleccionar]
11 0100 kkkk kkkk
Y vos con el acceso indirecto lees unicamente el byte donde esta el valor k.
Pero en tu PIC18 al tener 16 bits, tendrias 2 bytes. Si usas DT estarias creando RETLW, pero el acceso por tablas te permiten leer ambos bytes y no solo el menos significativo. Mirando el OPCODE de la instruccion RETLW del PIC18 encontras que es:

Código: [Seleccionar]
0000 1100 kkkk kkkk
Entonces cuando lees por primera ves lees el valor k, y luego lees 0x0C. Por eso tenes ese caracter de mas que siempre es un 0x0C, asi para todos los valores, recorda que serian todos RETLW. Si observas en tu imagen es siempre el mismo caracter. Es decir el mismo numero ( 0x0C ) se esta enviando siempre. Si buscas 0x0C en la tabla de caracteres del LCD veras que corresponde a un valor de la CGRAM, es decir de los caracteres que vos creas, como no tenes creado nada ahi, lo que aparece es "basura".

Exactamente en la memoria de tu PIC verias esto con dt:

Código: [Seleccionar]
       Line     Address      Opcode           Label                         DisAssy                 
       28    0036         0C52        LEER_MAX             RETLW 0x52                               
       29    0038         0C65                             RETLW 0x65                               
       30    003A         0C61                             RETLW 0x61                               
       31    003C         0C64                             RETLW 0x64                               
       32    003E         0C69                             RETLW 0x69                               
       33    0040         0C6E                             RETLW 0x6E                               
       34    0042         0C67                             RETLW 0x67                               
       35    0044         0C20                             RETLW 0x20                               
       36    0046         0C54                             RETLW 0x54                               
       37    0048         0C65                             RETLW 0x65                               
       38    004A         0C6D                             RETLW 0x6D                               
       39    004C         0C70                             RETLW 0x70                               
       40    004E         0C65                             RETLW 0x65                               
       41    0050         0C72                             RETLW 0x72                               
       42    0052         0C61                             RETLW 0x61                               
       43    0054         0C74                             RETLW 0x74                               
       44    0056         0C75                             RETLW 0x75                               
       45    0058         0C72                             RETLW 0x72                               
       46    005A         0C65                             RETLW 0x65                               
       47    005C         0C3A                             RETLW 0x3A                               
       48    005E         0C00                             RETLW 0x0   

Para esto quedan 2 opciones,

- leer cada 2 bytes, es decir leer e incrementar 2 veces.
- usar otra forma de almacenar datos.

Leer cada 2 bytes es una perdida de memoria/tiempo . Estariamos desperdiciando 1 byte por cada palabra de memoria ( 16 bits ), entonces tendriamos que buscar algo que no haga el RETLW sino que ponga el valor nomas en FLASH. Si Usas la directiva data, en ves de dt:

Código: ASM
  1. LEER_MAX: data "Reading Temperature:",0x00;

Tu mensaje en hexa es (asi comparas abajo):

52 65 61 64 69 6e 67 20 54 65 6d 70 65 72 61 74 75 72 65 3a 00

Con esa directiva tu flash queda asi, observa la 3er columna que es el contenido y si lo comparas con el hexa de tu mensaje vas a ver la relacion:

Código: [Seleccionar]
       Line     Address      Opcode           Label                         DisAssy                 
       28    0036         6552        LEER_MAX             CPFSGT 0x52, BANKED                     
       29    0038         6461                             CPFSGT 0xF61, ACCESS                     
       30    003A         6E69                             MOVWF UIE, ACCESS                       
       31    003C         2067                             ADDWFC UFRMH, W, ACCESS                 
       32    003E         6554                             CPFSGT 0x54, BANKED                     
       33    0040         706D                             BTG UCON, 0, ACCESS                     
       34    0042         7265                             BTG 0xF65, 1, ACCESS                     
       35    0044         7461                             BTG 0xF61, 2, ACCESS                     
       36    0046         7275                             BTG UEP5, 1, ACCESS                     
       37    0048         3A65                             SWAPF 0xF65, F, ACCESS                   
       38    004A         0000                             NOP


Con lo cual tu codigo para que funcione ahora si, seria asi (o como lo tenias vos):

Código: ASM
  1. MENSAJE:
  2.                 MOVLW   UPPER (LEER_MAX)
  3.                 MOVWF   TBLPTRU
  4.                 MOVLW   HIGH(LEER_MAX)
  5.                 MOVWF   TBLPTRH
  6.                 MOVLW   LOW(LEER_MAX)
  7.                 MOVWF   TBLPTRL
  8.  
  9. SENDING_TEXT:
  10.                 TBLRD*+
  11.                 MOVF    TABLAT,W
  12.                 BTFSC   STATUS,Z
  13.                 RETURN
  14.                 CALL    ENVIAR_DATO
  15.                 GOTO    SENDING_TEXT
  16.  
  17.  
  18. ;***************************************************************************************************
  19. ;*********************** DECLARACION DE MENSAJES PARA OPTIMIZACION DE CÓDIGOS **********************
  20. ;***************************************************************************************************
  21.  
  22. LEER_MAX: data "Reading Temperature:",0x00;

Ahi vi que tenes un retardo, no se por que lo tenes puesto, imagino que es para debug, pero no deberia estar.

En fin.. todo esto para explicarte que debes usar data en ves de dt, podrias haber usado de igual forma data para el PIC16, lo unico que no iban a funcionar como un RETLW.

Bibliografia:
MPASM™ Assembler,. MPLINK™ Object Linker,. MPLIB™ Object Librarian. User's Guide
http://ww1.microchip.com/downloads/en/DeviceDoc/33014L.pdf
« Última modificación: 03 de Febrero de 2016, 23:46:23 por KILLERJC »

Desconectado Pinolillo16

  • PIC18
  • ****
  • Mensajes: 324
Re:Apoyo para rutina en FSR
« Respuesta #8 en: 04 de Febrero de 2016, 15:31:57 »
Gracias KillerJC como siempre buenas respuestas, de hecho habia notado eso de leer dos veces y me funciono pero se me hacia algo absurdo hacerlo de esa manera. Cambie la tabla de DT a DATA y listo funciona perfectamente  :-/ ahora nada mas me queda la duda de como usar FSR en este micro. Digo es correcto lo que pienso para hacerlo:

- Mandar direccion a FSRXL y FSRXH moviendo o leyendo el dato requerido al INDFX?

Si es correcto, solo para tablas no me funciona?

Si no es correcto como lo puedo hacer?

Gracias por todas sus recomendaciones
 :)

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Apoyo para rutina en FSR
« Respuesta #9 en: 04 de Febrero de 2016, 16:14:10 »
El acceso indirecto en ese PIC es solo para la memoria de datos. Lo que te puede servir como para un buffer o leer posiciones seguidas en la memoria de datos ( RAM ).

Para el acceso a la FLASH, usas las tablas como el ejemplo anterior. En el cual el equivalente para el FSRxH:FSRxL serian las TBLPTRU:TBLPTRH:TBLPTRL  (TBL=table PTR=pointer), en esta tenes instrucciones que suman, restan a este puntero o leen directamente como TBLRD*+, TBLRD*, TBLRD*-, TBLRD+* , y que tambien sirven para escribir la flash que es algo un poco mas complejo todavia y no vamos a tocar. En el acceso indirecto ( FSRx ) sucede otra cosa totalmente distinta.

Volviendo al tema de acceso a la memoria de datos, tenes 2 opciones:

- Usar un acceso directo
El acceso directo esta separado... Esto lo explique en otro post y algunas mas preguntas que me hicieron..
http://www.todopic.com.ar/foros/index.php?topic=45254.0

El resumen es asi. Las instrucciones pueden ir a la porcion de memoria llamada ACCESS o BANKED. El ACCESS corresponde una parte de 0x00 a 0x5F al banco 0, y otra parte de 0x60 a 0xFF a los SFR (Special function register), Banked por su parte funciona como los pic16, es decir seleccionas el banco y accedes. es medio largo asi que voy a resumir las posibilidades en un solo codigo:

Código: ASM
  1. Var1    EQU     0x20
  2.         Var2    EQU     0x80
  3.         Var3    EQU     0x120
  4.  
  5.         MOVLB   0x00                    ;Banco 0
  6.  
  7.         INCF    Var1, F, ACCESS         ; Var1 ( 0x20 ) = 1
  8.         INCF    Var2, F, ACCESS         ; PORTA ( 0xF80 ) = 1
  9.         INCF    Var3, F, ACCESS         ; [0x20] = 1
  10.  
  11.         INCF    Var1, F, BANKED         ; Var1 ( 0x20 ) = 2
  12.         INCF    Var2, F, BANKED         ; Var2 ( 0x80 ) = 1
  13.         INCF    Var3, F, BANKED         ; [0x20] = 2
  14.  
  15.         MOVLB   0x01                    ; Banco 1
  16.  
  17.         INCF    Var1, F, ACCESS         ; Var1 ( 0x20 ) = 3
  18.         INCF    Var2, F, ACCESS         ; PORTA ( 0xF80 ) = 2
  19.         INCF    Var3, F, ACCESS         ; [0x20] = 3
  20.  
  21.         INCF    Var1, F, BANKED         ; Var3 ( 0x120 ) = 1
  22.         INCF    Var2, F, BANKED         ; [0x180] = 1
  23.         INCF    Var3, F, BANKED         ; Var3 ( 0x120 ) = 2


- Usar acceso indirecto
Lo bueno del acceso indirecto es que no esta separado en "bancos". Supongamos que tenes un buffer en 0x100, tiene 256 posiciones y queres ir llenandolo con valores de 0 a 255.

Código: ASM
  1. SetupCarga:
  2.  
  3.         LFSR    0, 0x100        ;Seteo el FSR0 a 0x100
  4.         CLRF    Contador        ;Pongo a 0 Contador
  5.  
  6. CargoDatos:
  7.  
  8.         MOVF    Contador,W      ; W = Contador
  9.         MOVWF   POSTINC0        ; [FSR0] = Contador , FSR0++
  10.         INCF    Contador,F      ; Contador++
  11.         TSTFSZ  FSR0L           ; FSR0L = 0 ? es decir pasaron los 256 valores aprovecho que esta en 0
  12.         GOTO    CargoDatos      ; Si no pasaron que cargue de nuevo el otro valor
  13.         RETURN                  ; Si paso entonces que vuelva

Podes hacer el buffer en 0x150 sin problemas.
Ahora para pre/post aumentar/decrementar el indice de los accesos indirectos, el PIC posee registros como PREINCx, POSTINCx, POSTDECx, INDFx
Pensalo como un INDFx que ademas resta/suma 1 al FSRx antes o despues.

Y todo esto sin si quiera utilizar el set extendido de instrucciones del PIC. Cambia lo expuesto arriba un poco mas.
« Última modificación: 04 de Febrero de 2016, 16:18:58 por KILLERJC »


 

anything