Autor Tema: Generalizar un proceso con tablas  (Leído 6000 veces)

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

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Generalizar un proceso con tablas
« en: 05 de Julio de 2008, 01:59:40 »
A ver si me podeis hechar una mano con esto que no me sale.

Tengo en ensamblador el siguiente proceso:

orden1: movf orden1H,0
            movwf ordentH
            movf orden1L,0
            movwf ordentL

            call incL

            mov sal_orden1,0
            andwf PORTB,1

orden2: movf orden2H,0
            movwf ordentH
            movf orden2L,0
            movwf ordentL

            call incL

            mov sal_orden2,0
            andwf PORTB,1

... y así sucesivamente hasta 16

Como podría abreviar esto?

Desconectado Javicho

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 570
Re: Generalizar un proceso con tablas
« Respuesta #1 en: 05 de Julio de 2008, 03:19:31 »
Hola pocher:

Una forma seria usar el direccionamiento indirecto, por ejemplo guarda en la RAM tus registros de esta forma:

50 -> orden1H
51 -> orden1L
52 -> sal_orden1
-------------------
53 -> orden2H
54 -> orden2L
55 -> sal_orden2
-------------------

  ...

-------------------
7D -> orden16H
7E -> orden16L
7F -> sal_orden16
-------------------
Ahora haces:

    movlw  .16
    movwf  Contador
    movlw  H'50'
    movwf  FSR
Bucle
    movf    INDF,w
    movwf  ordentH
    incf      FSR,f
    movf    INDF,w
    movwf  ordentL
    call       incL
    incf       FSR,f
    movf    INDF,w
    andwf   PORTB,1
    incf       FSR,f
    decfsz   Contador,f
    goto     Bucle
fin goto     fin
;------------------------------

Otra forma seria usar tablas.

Javicho.

Desconectado todopic

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3495
    • http://www.todopicelectronica.com.ar
Re: Generalizar un proceso con tablas
« Respuesta #2 en: 05 de Julio de 2008, 19:04:43 »
 :-/ Muy bien Javicho, esta es la forma mas eficiente ,empleando el fsr y el loop  :mrgreen:

Vamos amigo Pocher, a colocar varios de estos  :-/ en la respuesta  :D

Un abrazo

Norberto
Firmat - Santa Fe - Argentina

www.TodoPic.net

Solo se tiran piedras, al arbol que tiene frutos...

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Generalizar un proceso con tablas
« Respuesta #3 en: 06 de Julio de 2008, 06:24:17 »
Muy bueno, he aprendido a usar FSR+INDF para PICs16.  :-/ :-/ nunca antes lo había utilizado.

Ahora, perdonadme por el olvido  :D . Se me pasó deciros que la implementación es para un PIC18 y tal cual está no quiere caminar.

Un saludo
« Última modificación: 06 de Julio de 2008, 06:49:33 por pocher »

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Generalizar un proceso con tablas
« Respuesta #4 en: 06 de Julio de 2008, 15:06:01 »
Creo haber encontrado la razón por la cual no funciona.

El programa principal está escrito en C y dentro de él tengo esta serie de sentencias en ensamblador.

El error que me dá al compilar es "Expression must evaluate to a constant INDF0"

Lo que he hecho es transportar el bloque en ensamblador pasado para PICs18 y ensamblar con MPASMWIN y no ha dado ningún tipo de error.

Por lo tanto creo que el tratamiento del direccionamiento indirecto el compilador CCS no lo contempla.

Desconectado Javicho

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 570
Re: Generalizar un proceso con tablas
« Respuesta #5 en: 07 de Julio de 2008, 11:45:04 »
Tal vez te convenga usar Tablas, por ejemplo, puedes crear una tabla con los valores de tus registros en la misma secuencia que el ejemplo anterior y luego haces:
-------------------
   movlw   .16
   movwf   Contador
   bsf   EECON1,EEPGD
   bcf   EECON1,CFGS
   clrf   TBLPTRU      ;TABLA en ORG H'000700'
   movlw   H'07'
   movwf   TBLPTRH
   clrf   TBLPTRL
Bucle
   TBLRD*+      ;lee byte y luego " TBLPTR + 1 "
   movf   TABLAT,w
   movwf   ordentH
   TBLRD*+
   TBLRD*+
   movf   TABLAT,w
   movwf   ordentL
   call   incL
   TBLRD*+
   TBLRD*+
   movf   TABLAT,w
   andwf   PORTB,1
   decfsz   Contador,f
   goto   Bucle
fin   goto   fin

   ORG   H'000700'
   DB 0xn1, 0xn2, 0xn3, 0xn4, 0xn5, .... , 0xn48
-------------------
Donde:

0xn1 -> orden1H
0xn2 -> orden1L
0xn3 -> sal_orden1
-------------------
0xn4 -> orden2H
0xn5 -> orden2L
0xn6 -> sal_orden2
-------------------

  ...

-------------------
0xn46 -> orden16H
0xn47 -> orden16L
0xn48 -> sal_orden16
-------------------

Saludos

Javicho

PD: Te recomiendo que mejor uses los PIC16, domina bien sus módulos e instrucciones, asi como algunas técnicas importantes de manejo de datos luego recien pasa a los PIC18.

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Generalizar un proceso con tablas
« Respuesta #6 en: 08 de Julio de 2008, 13:00:36 »
Con mucho gusto recogo tus recomendaciones Javicho. Es un placer ir de estudiante.

Voy a estudiarme lo de las tablas para PICs18 que me has dejado. Si alguna vez puedo ayudarte, no dudes que lo haré.

Un saludo.


Desconectado flacoclau

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1692
    • El Micro Reactor
Re: Generalizar un proceso con tablas
« Respuesta #7 en: 08 de Julio de 2008, 13:45:11 »
Bueno acá va mi aporte creo que es parecido

Código: [Seleccionar]
  SETF fin,0                         ;carga el valor 0xFF en el registro fin

   NOP                                ;programa

   MOVLW .1                           ;se carga en Wreg el número de tabla a buscar
   call mensaje                       ;se llama al gestor de tablas

   NOP                                ;continúa el programa
   GOTO $-1                           ;en este ejemplo es un bucle infinito




mensaje
   CLRF contador,0                    ;se pone a cero el contador del offset
   MULLW .6                           ;se multiplica por 6 el valor que trae Wreg
                                      ;esto es porque cada CALL ocupa 4 espacios y cada RETURN
                                      ;ocupa 2 espacios de memoria  en un 18f452
                                      ;por lo tanto cada puntero debe saltar de 6 en 6

loop
   CALL sel_tabla                     ;va al selector de tablas
   CPFSGT fin,0                       ;compara si w = oxff no salta
   RETURN                             ;y retorna al programa principal
   CALL caracter                      ;muestra el caracter en el display en este ejemplo
   INCF contador,f,0                  ;incrementa el contador de OFFSET
   GOTO loop                          ;vuelve a repetir el proceso
   
sel_tabla

   MOVF PCL,w,0                        ;se actualizan los pclat
   MOVF PRODL,w,0                    ;se carga el offset en wreg
   ADDWF PCL,f,0                      ;w llega con el número de tabla multiplicado por 6
                                              ;y se suma al PCL para dar el salto
   CALL Tabla_0                        ;va a la tabla seleccionada
   RETURN                             ;regresa de la tabla con el valor a transferir en w
                                      ;y retorna al gestor de tablas
   CALL Tabla_1
   RETURN
   CALL Tabla_2
   RETURN
   CALL Tabla_3
   RETURN
   CALL Tabla_4
   RETURN
   CALL Tabla_5
   RETURN
   CALL Tabla_6
   RETURN
   CALL Tabla_7
   RETURN

Tabla_0     
     MOVF PCL,w,0
     RLNCF cont,w,0           ;se multiplica el valor del offset por dos y se lo almacena en w
                                      ;esto se hace ya que cada RETLW ocupa 2 espacios de memoria
                                      ;en un 18F452
     ADDWF PCL,f,0           ;se suma el contenido de Wreg que vale contador x 2 al PCL
     RETLW 'A'
     RETLW 'B'
     RETLW 'C'
     RETLW 'D'
     RETLW 'E'
     RETLW 'F'
     RETLW 'G'
     RETLW 'H'
     RETLW 'I'
     RETLW 'J'
     RETLW 0xFF                       ;retorna con el valor de 0xFF que es el corte del bucle

Tabla_1
     MOVF PCL,w,0
     RLNCF cont,w,0           ;se multiplica el valor del offset por dos y se lo almacena en w
                                      ;esto se hace ya que cada RETLW ocupa 2 espacios de memoria
                                      ;en un 18F452
     ADDWF PCL,f,0           ;se suma el contenido de Wreg que vale contador x 2 al PCL
     RETLW 'A'
     RETLW 'B'
     RETLW 'C'
     RETLW 'D'
     RETLW 'E'
     RETLW 'F'
     RETLW 'G'
     RETLW 'H'
     RETLW 'I'
     RETLW 'J'
     RETLW 0xFF                       ;retorna con el valor de 0xFF que es el corte del bucle

Tabla_2
     MOVF PCL,w,0
     RLNCF cont,w,0           ;se multiplica el valor del offset por dos y se lo almacena en w
                                      ;esto se hace ya que cada RETLW ocupa 2 espacios de memoria
                                      ;en un 18F452
     ADDWF PCL,f,0           ;se suma el contenido de Wreg que vale contador x 2 al PCL
     RETLW 'A'
     RETLW 'B'
     RETLW 'C'
     RETLW 'D'
     RETLW 'E'
     RETLW 'F'
     RETLW 'G'
     RETLW 'H'
     RETLW 'I'
     RETLW 'J'
     RETLW 0xFF                       ;retorna con el valor de 0xFF que es el corte del bucle

Tabla_3
     MOVF PCL,w,0
     RLNCF cont,w,0           ;se multiplica el valor del offset por dos y se lo almacena en w
                                      ;esto se hace ya que cada RETLW ocupa 2 espacios de memoria
                                      ;en un 18F452
     ADDWF PCL,f,0           ;se suma el contenido de Wreg que vale contador x 2 al PCL
     RETLW 'A'
     RETLW 'B'
     RETLW 'C'
     RETLW 'D'
     RETLW 'E'
     RETLW 'F'
     RETLW 'G'
     RETLW 'H'
     RETLW 'I'
     RETLW 'J'
     RETLW 0xFF

Tabla_4
     MOVF PCL,w,0
     RLNCF cont,w,0           ;se multiplica el valor del offset por dos y se lo almacena en w
                                      ;esto se hace ya que cada RETLW ocupa 2 espacios de memoria
                                      ;en un 18F452
     ADDWF PCL,f,0           ;se suma el contenido de Wreg que vale contador x 2 al PCL
     RETLW 'A'
     RETLW 'B'
     RETLW 'C'
     RETLW 'D'
     RETLW 'E'
     RETLW 'F'
     RETLW 'G'
     RETLW 'H'
     RETLW 'I'
     RETLW 'J'
     RETLW 0xFF

Tabla_5
     MOVF PCL,w,0
     RLNCF cont,w,0           ;se multiplica el valor del offset por dos y se lo almacena en w
                                      ;esto se hace ya que cada RETLW ocupa 2 espacios de memoria
                                      ;en un 18F452
     ADDWF PCL,f,0           ;se suma el contenido de Wreg que vale contador x 2 al PCL
     RETLW 'A'
     RETLW 'B'
     RETLW 'C'
     RETLW 'D'
     RETLW 'E'
     RETLW 'F'
     RETLW 'G'
     RETLW 'H'
     RETLW 'I'
     RETLW 'J'
     RETLW 0xFF

Tabla_6
     MOVF PCL,w,0
     RLNCF cont,w,0           ;se multiplica el valor del offset por dos y se lo almacena en w
                                      ;esto se hace ya que cada RETLW ocupa 2 espacios de memoria
                                      ;en un 18F452
     ADDWF PCL,f,0           ;se suma el contenido de Wreg que vale contador x 2 al PCL
     RETLW 'A'
     RETLW 'B'
     RETLW 'C'
     RETLW 'D'
     RETLW 'E'
     RETLW 'F'
     RETLW 'G'
     RETLW 'H'
     RETLW 'I'
     RETLW 'J'
     RETLW 0xFF

Tabla_7
     MOVF PCL,w,0
     RLNCF cont,w,0           ;se multiplica el valor del offset por dos y se lo almacena en w
                                      ;esto se hace ya que cada RETLW ocupa 2 espacios de memoria
                                      ;en un 18F452
     ADDWF PCL,f,0           ;se suma el contenido de Wreg que vale contador x 2 al PCL
     RETLW 'A'
     RETLW 'B'
     RETLW 'C'
     RETLW 'D'
     RETLW 'E'
     RETLW 'F'
     RETLW 'G'
     RETLW 'H'
     RETLW 'I'
     RETLW 'J'
     RETLW 0xFF



En este me ayudaron Brunof y Maunix, si le encuentran mejoras avisen.

Lo modifico ya que contenía un error, corregido!!
« Última modificación: 11 de Julio de 2008, 14:32:57 por flacoclau »
Las personas con buena ortografía me atraen textualmente.

El Micro Reactor

Córdoba capital - Argentina.

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Generalizar un proceso con tablas
« Respuesta #8 en: 09 de Julio de 2008, 11:43:05 »
Gracias por la colaboración flacoclau, esa forma ya la conocía, la aprendí hace poco ( http://www.todopic.com.ar/foros/index.php?topic=22322.0 ).

Javicho ¿no crees que sobraría un TBLRD*+ de los dos que hay juntos? ya que solo tiene que avanzar una posición.

En el programa que tengo (de momento en PAUSE) me interesaría que en la tabla apareciesen variables en lugar de constantes. Es decir si ponemos:

DB 0x01, 0x02, 0x03 ... toma esos números constantes.

Si ponemos:

Salida1 equ 0x20
Salida2 equ 0x21
Salida3 equ 0x22

DB Salida1, Salida2, Salida3 ... toma como valor de Salida1 el número 0x20, etc.

A mí lo que me interesaría es que tomara el valor del contenido de la posición de memoria 0x20, etc.

¿Se podrá hacer sin usar direccionamiento indirecto?




Desconectado Javicho

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 570
Re: Generalizar un proceso con tablas
« Respuesta #9 en: 09 de Julio de 2008, 13:10:18 »
Hola:

Javicho ¿no crees que sobraría un TBLRD*+ de los dos que hay juntos? ya que solo tiene que avanzar una posición.

No sobra porque el PC avanza de 2 en 2, mas bien falta un TBLRD*+, recuerda que esta instrucción primero lee y luego avanza de posición, el cambio es:

   ...

   movf   TABLAT,w
   andwf   PORTB,1
   TBLRD*+                    ;<- faltó este.
   decfsz   Contador,f
   goto   Bucle
fin   goto   fin

Si lo quieres tener como variables no queda otra que usar el Direccionamiento Indirecto, pero debes tener cuidado porque el tratamiento del mismo en un PIC18 es un tanto diferente en cuanto a sus registros aunque la filosofía es la misma.

Insisto, mejor domina bien los PIC16 luego sigue con los PIC18, asi se te va a hacer mas facil comprender estas cosas, seguro que la aplicación que estas haciendo se puede hacer bien en un PIC16.

Javicho.

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Generalizar un proceso con tablas
« Respuesta #10 en: 09 de Julio de 2008, 13:57:10 »
No, Javicho eso no es así.

Aunque el PC vaya de 2 en 2 con cada instrucción, cuando se encuentra con TBLRD*+ lee el primer elemento de la tabla y luego hace TBLPTR+1 para apuntar al siguiente elemento de la tabla que será el que leerá con el siguiente TBLRD*+, por lo tanto solo hace falta un TBLRD*+ para leer cada elemento de la tabla.

Imposible usar un PIC16, debo de usar un 18F4550 corriendo a 32MHz usando el PLL interno. Si no pasa nada podré controlar un número grande de Servos (muy, muy grande), me faltan estos detalles en ensamblador.

Un saludo

Desconectado Javicho

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 570
Re: Generalizar un proceso con tablas
« Respuesta #11 en: 09 de Julio de 2008, 14:56:50 »
Hola amigo Pocher:

Te explico con un ejemplo, digamos que tienes una tabla con 3 datos:

   ORG   H'000700'
   retlw   H'05'   ;<- posición en memoria de programa H'000700'
   retlw   H'08'   ;<- posición en memoria de programa H'000702'
   retlw   H'BD'   ;<- posición en memoria de programa H'000704'

Cuando se ejecuta TBLRD*+  en la siguiente linea en el registro TABLAT está disponible el valor apuntado previamente en la tabla y el puntero se incrementa en 1. El siguiente código te mostrará como trabaja el TBLRD*+:
   bsf      EECON1,EEPGD
   bcf      EECON1,CFGS
   clrf      TBLPTRU      ;apunta a la posición H'000700'
   movlw   H'07'
   movwf   TBLPTRH
   clrf      TBLPTRL

   TBLRD*+                   ;lee dato 05h y el puntero ahora es H'000701'
   movf   TABLAT,w   ;en TABLAT está el dato 05h
   movwf   DATO_REG_1
   TBLRD*+                   ;lee valor xxh y el puntero ahora es H'000702'
   movf   TABLAT,w
   movwf   DATO_REG_NO_VALIDO
   TBLRD*+                    ;lee dato 08h y el puntero ahora es H'000703'
   movf   TABLAT,w    ;en TABLAT está el dato 08h
   movwf   DATO_REG_2
   TBLRD*+                     ;lee valor xxh y el puntero ahora es H'000704'
   movf   TABLAT,w
   movwf   DATO_REG_NO_VALIDO
   TBLRD*+                     ;lee dato BDh y el puntero ahora es H'000705'
   movf   TABLAT,w   ;en TABLAT está el dato BDh
   movwf   DATO_REG_3
fin   goto   fin

Eso fue paso a paso, pero para leer solo los 3 datos que te interesan ahora debes hacer esto:
   bsf      EECON1,EEPGD
   bcf      EECON1,CFGS
   clrf      TBLPTRU      ;TABLA en ORG H'000700'
   movlw   H'07'
   movwf   TBLPTRH
   clrf      TBLPTRL

   TBLRD*+                   ;lee valor 05h y el puntero ahora es H'000701'
   movf   TABLAT,w   ;en TABLAT está el dato 05h
   movwf   DATO_REG_1
   TBLRD*+                   ;lee valor xxh y el puntero ahora es H'000702'
   TBLRD*+                   ;lee valor 08h y el puntero ahora es H'000703'
   movf   TABLAT,w   ;en TABLAT está el dato 08h
   movwf   DATO_REG_2
   TBLRD*+                   ;lee valor xxh y el puntero ahora es H'000704'
   TBLRD*+                   ;lee valor BDh y el puntero ahora es H'000705'
   movf   TABLAT,w   ;en TABLAT está el dato BDh
   movwf   DATO_REG_3
fin   goto   fin

Si necesariamente tienes que usar este PIC18 entonces primero lee bien el datasheet porque hay muchas cosas que difieren respecto a los PIC16.
Nos podrias comentar un poco mas sobre el proyecto que estás haciendo tal vez por ahi puedas recibir algunas nuevas ideas.

Saludos.

Javicho.

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Generalizar un proceso con tablas
« Respuesta #12 en: 10 de Julio de 2008, 01:44:15 »
En el caso de que sea:

   ORG   H'000700'
   retlw   H'05'   ;<- posición en memoria de programa H'000700'
   retlw   H'08'   ;<- posición en memoria de programa H'000702'
   retlw   H'BD'   ;<- posición en memoria de programa H'000704'

... sí que hay que poner dos TBLRD*+, ya que cada retlw   H'05' ocupa dos posiciones de memoria.

Pero en el caso del primer ejemplo que tú pusiste empleabas:

   ORG   H'000700'
   DB 0xn1, 0xn2, 0xn3, 0xn4, 0xn5, .... , 0xn48 ... y aquí solo se necesita un TBLRD*+

¡¡¡ Comprobado con MPLAB !!!

Desconectado Javicho

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 570
Re: Generalizar un proceso con tablas
« Respuesta #13 en: 11 de Julio de 2008, 09:40:33 »
Para ilustrar el hecho de que hay que tener cuidado con el manejo de tablas en los PIC18 puse una tabla en la que cada valor ocupa 2 posiciones, pero en vez de poner "DT" puse "DB", porque los "DT" tienen el mismo comportamiento que los "retlw", es decir ocupan 2 posiciones.

Javicho.

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Generalizar un proceso con tablas
« Respuesta #14 en: 11 de Julio de 2008, 14:28:47 »
Gracias por todo Javicho.

Voy ahora a poner un anuncio en el subforo de C, a ver si alguién me dice porqué no funciona el direccionamiento indirecto en CCS.

Y si es error del compilador que la gente lo sepa para evitar pérdidas de tiempo.

Un saludo


 

anything