TODOPIC

Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: maunix en 12 de Julio de 2006, 15:21:31

Título: Ejemplos en Assembler - PIC16F876
Publicado por: maunix en 12 de Julio de 2006, 15:21:31
Ejemplos en Assembler para el 16F876

INDICE

1) Lectura de mensajes (tabla) ubicado en cualquier lugar.

Título: Lectura de Tablas
Publicado por: maunix en 12 de Julio de 2006, 15:23:19
Rutina de Lectura de una Tabla en Memoria de Programa, sin importar donde esté ubicada

Versión 0.1.  Manejo simple de la rutina.  Para comprender cómo funciona.

En donde están los "nop" uno puede hacer lo que desee con el dato recibido en WREG que será el dato leído de la tabla.


Código: ASM
  1. ;------------------------------------------------------------------------------------
  2. ;
  3. ;  Rutina para Leer valores de tabla ubicados en cualquier lugar para PIC16Fxxx
  4. ;
  5. ;
  6. ;  Versión  : 0.1
  7. ;  Última Revisión: 12-7-2006
  8. ;  Autor    : Maunix
  9. ;
  10. ;------------------------------------------------------------------------------------
  11.  
  12.         list    P=16F876
  13.         include <p16F876.inc>
  14.  
  15.  
  16. MENSAJEADDRESS equ 0x20 ;Dejar 2 bytes para la variable MENSAJEADDRESS
  17. OFFSET  equ 0x22
  18.  
  19. ;
  20. ;  Modo de USO
  21. ;
  22. ;  En MENSAJEADRESS<1> guardamos el valor high de la dirección donde está el código a leer
  23. ;  En MENSAJEADRESS<0> guardamos el valor low de la dirección donde está el código a leer
  24. ;  OFFSET es un índice dentro del mensaje, que irá de 0 a Largo de Mensaje - 1.
  25. ;  0 para el primer valor, N-1 para el último
  26. ;  Funciona con mensajes donde cada mensaje sea menor a 255 bytes.  Para mayores tablas se deberá incorporar un OFFSET de 16 bits.
  27. ;
  28. ;  La rutina está armada para que sea utilizada no solo con mensajes de texto, sino cualquier tipo de datos que uno quiera leer
  29. ;
  30.  
  31.  
  32.         movlw   LOW MENSAJE1
  33.         movwf   MENSAJEADDRESS+0
  34.         movlw   HIGH MENSAJE1
  35.         movwf   MENSAJEADDRESS+1
  36.         movlw   .0
  37.         movwf   OFFSET          ;Leera el primer caracter
  38.  
  39.         pagesel MENSAJES
  40.         call    MENSAJES
  41.  
  42.         nop
  43.  
  44.         movlw   LOW MENSAJE2
  45.         movwf   MENSAJEADDRESS+0
  46.         movlw   HIGH MENSAJE2
  47.         movwf   MENSAJEADDRESS+1
  48.         movlw   .3
  49.         movwf   OFFSET          ;Leera el 4to caracter
  50.  
  51.         pagesel MENSAJES
  52.         call    MENSAJES
  53.        
  54.         nop                     ;Tengo el 3er caracter del mensaje2
  55.  
  56.         movlw   LOW MENSAJE4
  57.         movwf   MENSAJEADDRESS+0
  58.         movlw   HIGH MENSAJE4
  59.         movwf   MENSAJEADDRESS+1
  60.         movlw   .2
  61.         movwf   OFFSET          ;Leera el 4to caracter
  62.  
  63.         pagesel MENSAJES
  64.         call    MENSAJES
  65.        
  66.         nop
  67.        
  68.  
  69. MENSAJES:
  70.         movf    OFFSET,w
  71.         addwf   MENSAJEADDRESS+0,f
  72.         btfsc   STATUS,C
  73.         incf    MENSAJEADDRESS+1,f
  74.  
  75.         movf    MENSAJEADDRESS+1,w
  76.         movwf   PCLATH                          ;Guardo byte 0 del
  77.         movf    MENSAJEADDRESS+0,w
  78.         movwf   PCL
  79.  
  80. MENSAJE1:       dt      "HOLA"
  81. MENSAJE2:       dt      "MAUNIX TEST DE TABLAS"
  82. MENSAJE3:       dt      "PRIMERA PRUEBA"
  83.  
  84.  
  85. MENSAJE4:       dt      0xA0,0xA1,0xA2,0xA3,0xA4
  86.  
  87.         end



Versión 0.2.  Procesa una cantidad de bytes en forma consecutiva.  Muy útil cuando se quiere sacar una serie de datos por un puerto , un módulo como el USART o bien datos hacia un display LCD.

Se observa que no solo se pueden cargar 'TEXTO' sino también datos.

Código: ASM
  1. ;------------------------------------------------------------------------------------
  2. ;
  3. ;  Rutina para Leer valores de tabla ubicados en cualquier lugar para PIC16Fxxx
  4. ;
  5. ;
  6. ;  Versión  : 0.2
  7. ;           : Optimiza la forma de llamar a la rutina mediante el uso de un bucle
  8. ;
  9. ;  Última Revisión: 12-7-2006
  10. ;  Autor    : Maunix
  11. ;
  12. ;
  13. ;  Version  : 0.1
  14. ;             Primera versión.
  15. ;
  16. ;------------------------------------------------------------------------------------
  17.  
  18.         list    P=16F876
  19.         include <p16F876.inc>
  20.  
  21.  
  22. MENSAJEADDRESS equ 0x20 ;Dejar 2 bytes para la variable MENSAJEADDRESS
  23. OFFSET    equ 0x22
  24. OFFSETEND equ 0x23
  25.  
  26. ;
  27. ;  Modo de USO
  28. ;
  29. ;  En MENSAJEADRESS<1> guardamos el valor high de la dirección donde está el código a leer
  30. ;  En MENSAJEADRESS<0> guardamos el valor low de la dirección donde está el código a leer
  31. ;  OFFSET es un índice dentro del mensaje, que irá de 0 a Largo de Mensaje - 1.
  32. ;  0 para el primer valor, N-1 para el último
  33. ;  Funciona con mensajes donde cada mensaje sea menor a 255 bytes.  Para mayores tablas se deberá incorporar un OFFSET de 16 bits.
  34. ;
  35. ;  La rutina está armada para que sea utilizada no solo con mensajes de texto, sino cualquier tipo de datos que uno quiera leer
  36. ;
  37. ;  Se asume que las variables MENSAJEADDRESS, OFFSET Y OFFSETEND están todas en el banco 0 de memoria ram.  De no ser así deberán modificarse las rutinas
  38. ;  Se incorpora el macro pagesel para facilitar la codificación si es que el código estará ubicado en muchas bancos de memoria de programa
  39. ;  Se asume conocimiento del uso del PCLATH
  40. ;  El ejemplo es muy simple y no tiene en cuenta interrupciones ni otro tipo de cosas, su única finalidad es mostrar una forma
  41. ;  eficiente y fácil de ubicar una tabla en cualquier posición de la memoria de programa e irlo procesando en forma consecutiva
  42. ;
  43. ;
  44. ;
  45.  
  46.  
  47. _RUTINAS:
  48.         movlw   LOW MENSAJE1
  49.         movwf   MENSAJEADDRESS+0
  50.         movlw   HIGH MENSAJE1
  51.         movwf   MENSAJEADDRESS+1
  52.         movlw   .4
  53.         movwf   OFFSETEND               ;Leera 4 bytes (del 0 al 3)
  54.  
  55.         pagesel _MENSAJESTART
  56.         call    _MENSAJESTART
  57.  
  58.         ;pagesel        _RUTINAS                ;En caso de que se quiera hacer algun salto dentro de esta sección
  59.  
  60.         movlw   LOW MENSAJE2
  61.         movwf   MENSAJEADDRESS+0
  62.         movlw   HIGH MENSAJE2
  63.         movwf   MENSAJEADDRESS+1
  64.         movlw   .21
  65.         movwf   OFFSETEND               ;Leerá 21 bytes (del 0 al 20)
  66.  
  67.         pagesel _MENSAJESTART
  68.         call    _MENSAJESTART
  69.        
  70.         ;pagesel        _RUTINAS                ;En caso de que se quiera hacer algun salto dentro de esta sección
  71.  
  72.         movlw   LOW MENSAJE3
  73.         movwf   MENSAJEADDRESS+0
  74.         movlw   HIGH MENSAJE3
  75.         movwf   MENSAJEADDRESS+1
  76.         movlw   .2
  77.         movwf   OFFSETEND               ;Leerá 2 bytes (del 0 al 1)
  78.  
  79.         pagesel _MENSAJESTART
  80.         call    _MENSAJESTART
  81.        
  82.         ;pagesel        _RUTINAS                ;En caso de que se quiera hacer algun salto dentro de esta sección
  83.  
  84.         movlw   LOW MENSAJE4
  85.         movwf   MENSAJEADDRESS+0
  86.         movlw   HIGH MENSAJE4
  87.         movwf   MENSAJEADDRESS+1
  88.         movlw   .6
  89.         movwf   OFFSETEND               ;Leera el 6 bytes (del 0 al 5)
  90.  
  91.         pagesel _MENSAJESTART
  92.         call    _MENSAJESTART
  93.  
  94.         ;pagesel        _RUTINAS                ;En caso de que se quiera hacer algun salto dentro de esta sección
  95.  
  96.         ;A partir de aquí hacer lo que el usuario uno desee
  97.  
  98.         nop
  99.         goto    $-1
  100.  
  101.  
  102.  
  103. _MENSAJESTART:
  104.         clrf    OFFSET
  105.         movf    OFFSET,w
  106.         addwf   MENSAJEADDRESS+0,f
  107.         btfsc   STATUS,C
  108.         incf    MENSAJEADDRESS+1,f
  109.                
  110. _MENSAJEBUCLE
  111.         pagesel MENSAJES
  112.         call    MENSAJES
  113.  
  114.         ; El dato leído está en WREG
  115.         ; Sacarlo por la USART, enviarlo a una rutina de display 7 seg, rutina de display LCD,  etc.
  116.         ; Ej. (usar una de estas lineas, no todas)
  117.         ; movwf TXREG
  118.         ; call  CARACTERLCD
  119.         ; movwf PORTB
  120.  
  121.         bcf     STATUS,Z
  122.         incf    MENSAJEADDRESS+0,f
  123.         btfsc   STATUS,Z
  124.         incf    MENSAJEADDRESS+1,f
  125.        
  126.         pagesel _MENSAJEBUCLE
  127.         incf    OFFSET,f
  128.         movf    OFFSET,w
  129.         subwf   OFFSETEND,w
  130.         btfss   STATUS,Z
  131.         goto    _MENSAJEBUCLE
  132.         return
  133.        
  134.  
  135.  
  136.         org     0x03F0          ;Ubicado aquí a propósito para comprobar como funciona en los límites
  137. MENSAJES:
  138.         movf    MENSAJEADDRESS+1,w
  139.         movwf   PCLATH                          ;Guardo byte 0 del
  140.         movf    MENSAJEADDRESS+0,w
  141.         movwf   PCL
  142.  
  143. MENSAJE1:       dt      "HOLA"
  144. MENSAJE2:       dt      "MAUNIX TEST DE TABLAS"
  145. MENSAJE3:       dt      "VERSION 0.2"
  146.  
  147.  
  148. MENSAJE4:       dt      0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8
  149.  
  150.         end



Versión 0.3.  Procesa una cantidad de bytes en forma consecutiva.  Muy útil cuando se quiere sacar una serie de datos por un puerto , un módulo como el USART o bien datos hacia un display LCD.

Idem a versión 0.2 pero incoropora un macro para hacer el código más legible.

Se observa que no solo se pueden cargar 'TEXTO' sino también datos.

Código: ASM
  1. ;------------------------------------------------------------------------------------
  2. ;
  3. ;  Rutina para Leer valores de tabla ubicados en cualquier lugar para PIC16Fxxx
  4. ;
  5. ;  Versión  : 0.3
  6. ;             Utilización de un macro para comprimir el código
  7. ;             Código idéntico al de la version 0.2 pero con uso de macro
  8. ;
  9. ;  Última Revisión: 12-7-2006
  10. ;  Autor    : Maunix
  11. ;
  12. ;
  13. ;  Versión  : 0.2
  14. ;           : Optimiza la forma de llamar a la rutina mediante el uso de un bucle
  15. ;  Version  : 0.1
  16. ;             Primera versión.
  17. ;
  18. ;------------------------------------------------------------------------------------
  19.  
  20.         list    P=16F876
  21.         include <p16F876.inc>
  22.  
  23.  
  24. MENSAJEADDRESS equ 0x20 ;Dejar 2 bytes para la variable MENSAJEADDRESS
  25. OFFSET    equ 0x22
  26. OFFSETEND equ 0x23
  27.  
  28. ;
  29. ;  Modo de USO
  30. ;
  31. ;  En MENSAJEADRESS<1> guardamos el valor high de la dirección donde está el código a leer
  32. ;  En MENSAJEADRESS<0> guardamos el valor low de la dirección donde está el código a leer
  33. ;  OFFSET es un índice dentro del mensaje, que irá de 0 a Largo de Mensaje - 1.
  34. ;  0 para el primer valor, N-1 para el último
  35. ;  Funciona con mensajes donde cada mensaje sea menor a 255 bytes.  Para mayores tablas se deberá incorporar un OFFSET de 16 bits.
  36. ;
  37. ;  La rutina está armada para que sea utilizada no solo con mensajes de texto, sino cualquier tipo de datos que uno quiera leer
  38. ;
  39. ;  Se asume que las variables MENSAJEADDRESS, OFFSET Y OFFSETEND están todas en el banco 0 de memoria ram.  De no ser así deberán modificarse las rutinas
  40. ;  Se incorpora el macro pagesel para facilitar la codificación si es que el código estará ubicado en muchas bancos de memoria de programa
  41. ;  Se asume conocimiento del uso del PCLATH
  42. ;  El ejemplo es muy simple y no tiene en cuenta interrupciones ni otro tipo de cosas, su única finalidad es mostrar una forma
  43. ;  eficiente y fácil de ubicar una tabla en cualquier posición de la memoria de programa e irlo procesando en forma consecutiva
  44. ;
  45. ;
  46. ;
  47. _mensaje        macro   NombreMensaje,LargoMensaje
  48.         movlw   LOW NombreMensaje
  49.         movwf   MENSAJEADDRESS+0
  50.         movlw   HIGH NombreMensaje
  51.         movwf   MENSAJEADDRESS+1
  52.         movlw   LargoMensaje
  53.         movwf   OFFSETEND               ;Leera 3 bytes (del 0 al 2)
  54.  
  55.         pagesel _MENSAJESTART
  56.         call    _MENSAJESTART
  57.  
  58.         endm
  59.  
  60.  
  61. _RUTINAS:
  62.         _mensaje        MENSAJE1,.4             ;Leera 4 bytes (del 0 al 3)
  63.  
  64.         ;pagesel        _RUTINAS                ;En caso de que se quiera hacer algun salto dentro de esta sección
  65.  
  66.         _mensaje        MENSAJE2,.21            ;Leera el 21 bytes (del 0 al 20)
  67.  
  68.         ;pagesel        _RUTINAS                ;En caso de que se quiera hacer algun salto dentro de esta sección
  69.  
  70.         _mensaje        MENSAJE3,.2             ;Leera el 2 bytes (del 0 al 1)
  71.  
  72.         ;pagesel        _RUTINAS                ;En caso de que se quiera hacer algun salto dentro de esta sección
  73.  
  74.         _mensaje        MENSAJE4,.6             ;Leera el 6 bytes (del 0 al 5)
  75.  
  76.         ;pagesel        _RUTINAS                ;En caso de que se quiera hacer algun salto dentro de esta sección
  77.        
  78.         ;A partir de aquí hacer lo que el usuario uno desee
  79.  
  80.         nop
  81.         goto    $-1
  82.  
  83.  
  84.  
  85. _MENSAJESTART:
  86.         clrf    OFFSET
  87.         movf    OFFSET,w
  88.         addwf   MENSAJEADDRESS+0,f
  89.         btfsc   STATUS,C
  90.         incf    MENSAJEADDRESS+1,f
  91.                
  92. _MENSAJEBUCLE
  93.         pagesel MENSAJES
  94.         call    MENSAJES
  95.  
  96.         ; El dato leído está en WREG
  97.         ; Sacarlo por la USART, enviarlo a una rutina de display 7 seg, rutina de display LCD,  etc.
  98.         ; Ej. (usar una de estas lineas, no todas)
  99.         ; movwf TXREG
  100.         ; call  CARACTERLCD
  101.         ; movwf PORTB
  102.  
  103.         bcf     STATUS,Z
  104.         incf    MENSAJEADDRESS+0,f
  105.         btfsc   STATUS,Z
  106.         incf    MENSAJEADDRESS+1,f
  107.        
  108.         pagesel _MENSAJEBUCLE
  109.         incf    OFFSET,f
  110.         movf    OFFSET,w
  111.         subwf   OFFSETEND,w
  112.         btfss   STATUS,Z
  113.         goto    _MENSAJEBUCLE
  114.         return
  115.        
  116.  
  117.  
  118.         org     0x03F0          ;Ubicado aquí a propósito para comprobar como funciona en los límites
  119. MENSAJES:
  120.         movf    MENSAJEADDRESS+1,w
  121.         movwf   PCLATH                          ;Guardo byte 0 del
  122.         movf    MENSAJEADDRESS+0,w
  123.         movwf   PCL
  124.  
  125. MENSAJE1:       dt      "HOLA"
  126. MENSAJE2:       dt      "MAUNIX TEST DE TABLAS"
  127. MENSAJE3:       dt      "VERSION 0.2"
  128.  
  129.  
  130. MENSAJE4:       dt      0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8
  131.  
  132.         end


Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: Y@el en 27 de Enero de 2007, 02:16:55
Hola Mauricio,

Justo me disponia ha manejar unas Tablas para mensajes en un LCD.

En PBP, y esto me viene de maravilla.... Ya que me ahorras el trabajo... xD

Saludos

Yoel
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: maunix en 27 de Enero de 2007, 14:40:14
Hola Mauricio,

Justo me disponia ha manejar unas Tablas para mensajes en un LCD.

En PBP, y esto me viene de maravilla.... Ya que me ahorras el trabajo... xD

Saludos

Yoel


Bueno yoel, me alegro mucho.  Esa es la idea, que les simplifique la vida y no rehacer lo que otro ya hizo y compartió .

Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: manuelroin24 en 28 de Enero de 2007, 01:14:10
Eso Maunix que bien vienen estos ejemplitos, y tendre q esperar nomas hasta que lleguen los del 18Fxxx jejejejejeje saludos
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: Enrique_86 en 27 de Noviembre de 2008, 17:18:43
Excelente maunix esto me servira mucho gracias por el aporte!.. Saludos  :mrgreen:
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: BrunoF en 04 de Mayo de 2009, 12:39:47
Bueno, extiendo los ejemplos de maunix realizando ahora algoritmos para poder leer tablas de tablas:
En tiempo de ejecución, el usuario puede seleccionar de qué tabla leer un subelemento. Esto es útil cuando tenemos muchas tablas y debemos poder acceder dinámicamente a sus elementos. Todas las tablas pueden ubicarse en cualquier lugar, sin ninguna restricción excepto que no pueden tener un tamaño mayor a los 256 WORDs.
El usuario debe ir completando las tablas individuales así como también sus direcciones altas y bajas en las tablas DirBaja y DirAlta. El ejemplo del siguiente código leerá el primer caracter de la tabla1, por lo que W debería retornar con el valor ASCII de la 'B'

Código: ASM
  1. list    P=16F876
  2.         include <p16F876.inc>
  3.  
  4. elemento        equ             0x20
  5. subelemento     equ             0x21
  6.  
  7. tmpL            equ             0x22
  8. tmpH            equ             0x23
  9. tmpsub          equ             0x24
  10.  
  11. dirL            equ             0x25
  12. dirH            equ             0x26
  13.  
  14.         movlw   0x00                    ;subelemento del elemento a leer
  15.         movwf   subelemento
  16.         movlw   0x01                    ;elemento a leer
  17.         pagesel leer_elemento
  18.         call    leer_elemento
  19.         nop
  20.  
  21.  
  22. leer_elemento
  23.         movwf   elemento
  24.  
  25.         movlw   LOW DirBaja
  26.         movwf   tmpL
  27.         movlw   HIGH DirBaja
  28.         movwf   tmpH
  29.         movf    elemento,w
  30.         movwf   tmpsub
  31.  
  32.         movf    elemento,W
  33.         pagesel SaltaYLee
  34.         call    SaltaYLee
  35.         movwf   dirL
  36.  
  37.  
  38.         movlw   LOW DirAlta
  39.         movwf   tmpL
  40.         movlw   HIGH DirAlta
  41.         movwf   tmpH
  42.         movf    elemento,w
  43.         movwf   tmpsub
  44.         movf    elemento,W
  45.         pagesel SaltaYLee
  46.         call    SaltaYLee
  47.         movwf   dirH
  48.  
  49.         movf    dirL,W
  50.         movwf   tmpL
  51.         movf    dirH,W
  52.         movwf   tmpH
  53.         movf    subelemento,w
  54.         movwf   tmpsub
  55.         pagesel SaltaYLee
  56.         goto    SaltaYLee
  57.  
  58. SaltaYLee
  59.         movf    tmpH,W
  60.         movwf   PCLATH
  61.  
  62.         movf    tmpL,W
  63.         addwf   tmpsub,W
  64.         btfsc   STATUS,C
  65.         incf    PCLATH,F
  66.        
  67.         movwf   PCL
  68.  
  69. DirBaja
  70.         retlw   LOW     tabla0
  71.         retlw   LOW     tabla1
  72.         ;...
  73.  
  74. DirAlta
  75.         retlw   HIGH    tabla0
  76.         retlw   HIGH    tabla1
  77.         ;...
  78.  
  79. tabla0: dt      "HOLA", 0
  80. tabla1: dt      "BRUNOF ESTUVO AQUI", 0
  81. ;...
  82.        
  83.         END

Saludos.
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: marvicdigital en 04 de Mayo de 2009, 16:07:56
Impresionando de nuevo...eres todo un máquina para esto..mil gracias por compartir tus conocimientos.. he aprendido mucho  :-/

Saludos
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: marvicdigital en 05 de Mayo de 2009, 22:48:42
BrunoF, quisiera, si está dentro de tus posibilidades, me pudieras explicar linea por linea de las que no entiendo bien, me refiero por ejemplo que significa [movlw   LOW DirBaja], LOW exactamente que hace o que selecciona de DirBaja, es más DirBaja es el nombre que le pones a la Tabla de Tablas?, es que es ahi donde me pierdo y no logro comprender muy bien, y no soy de los que sigo por mi camino  y dejo esto para otra oportunidad  8)..de verdad me apeno mucho de no poder entender o asimilar muy bien tu ejemplo, debe ser por que desconozco esas funciones que en los libros de microcontroladores nunca mencionan, como el caso de HIGH o LOW y no quiero ponerme con suposiciones ..
Bueno, al lado de cada linea pondré lo que entiendo y lo que no con signo de "?" ..ojala me perdones tanta molestia que te he causado por estos días, pero quiero aprender un poco más  :-).

Código: ASM
  1. list    P=16F876
  2.         include <p16F876.inc>
  3.  
  4. elemento        equ             0x20  ;acá guardamos la dirección de la tabla principal? o el de cada una de las tablas?
  5. subelemento     equ             0x21   ; me imagino que acá se graba el Byte o bytes que hay en cada RETLW o DT?
  6.  
  7. tmpL            equ             0x22
  8. tmpH            equ             0x23
  9. tmpsub          equ             0x24
  10.  
  11. dirL            equ             0x25
  12. dirH            equ             0x26
  13.  
  14.         movlw   0x00                    ;subelemento del elemento a leer
  15.         movwf   subelemento
  16.         movlw   0x01                    ;elemento a leer
  17.         pagesel leer_elemento
  18.         call    leer_elemento
  19.         nop                                   ;aca el programa sigue, pero no leo ningun RETURN, salvo los RETLW de las tablas, osea que
  20.                                                 ;esto quiere decir que se hace una especie de CALL >> CALLL >> y aca se hace el RETURN?
  21.                                                 ;entonces esta rutina elimina la obligación de tener que hacer dos RETURN?
  22. leer_elemento
  23.         movwf   elemento
  24.  
  25.         movlw   LOW DirBaja   ;Carga a W con los 8 bits del PCL en donde está la tabla?
  26.         movwf   tmpL              ; Lo graba en tmpl
  27.         movlw   HIGH DirBaja  ;Carga a W con los bits de el PCLATH en donde está la tabla?
  28.         movwf   tmpH
  29.         movf    elemento,w
  30.         movwf   tmpsub
  31.                                              ;aca se escribe algo parte del programa? si es asi entonces la de arriba es un preset?
  32.         movf    elemento,W            ;hay necesidad de volver a cargar a W con elemento, sabiendo que ya tiene ese valor?
  33.         pagesel SaltaYLee
  34.         call    SaltaYLee
  35.         movwf   dirL
  36.  
  37.  
  38.         movlw   LOW DirAlta  ;?
  39.         movwf   tmpL
  40.         movlw   HIGH DirAlta  ;?
  41.         movwf   tmpH
  42.         movf    elemento,w
  43.         movwf   tmpsub
  44.         movf    elemento,W
  45.         pagesel SaltaYLee
  46.         call    SaltaYLee
  47.         movwf   dirH
  48.  
  49.         movf    dirL,W
  50.         movwf   tmpL
  51.         movf    dirH,W
  52.         movwf   tmpH
  53.         movf    subelemento,w
  54.         movwf   tmpsub
  55.         pagesel SaltaYLee
  56.         goto    SaltaYLee
  57.  
  58. SaltaYLee
  59.         movf    tmpH,W
  60.         movwf   PCLATH
  61.  
  62.         movf    tmpL,W
  63.         addwf   tmpsub,W
  64.         btfsc   STATUS,C
  65.         incf    PCLATH,F
  66.        
  67.         movwf   PCL
  68.  
  69. DirBaja                            ;DirBaja podría ser por ejemplo Texto_bienvenida ?
  70.         retlw   LOW     tabla0
  71.         retlw   LOW     tabla1       ;Dejo las preguntas, pero luego de leer y leer, esto quiere decir que retorna con W cargado con
  72.         ;...                            ;el valor del PCL de cada tabla llamada?
  73.  
  74. DirAlta                             ;y acá retorna con W cargado con el valor del PCLATH?
  75.         retlw   HIGH    tabla0
  76.         retlw   HIGH    tabla1      
  77.         ;...                            
  78. tabla0: dt      "HOLA", 0          ; las tablas pueden ser ilimitadas? el único limite son los 256 words o bytes que contenga cada tabla?
  79. tabla1: dt      "BRUNOF ESTUVO AQUI", 0  ; por ejemplo para el trabajo que estoy haciendo del pasamensajes, cada letra tiene
  80. ;...                                                     ;6 bytes, eso significa que solo puedo tener 256/6 de bytes en esa tabla de caracteres?
  81.        
  82.         END



De verdad que por más que he tratado de entender me pierdo con lo de HIGH y LOW, debe ser por eso que el resto del ejemplo no logro asimilarlo.


De nuevo mil gracias por la ayuda y más por tu comprensión y paciencia ..

Saludos

Editado: Encontré este PDF (http://www.pic16f84a.org/index.php?option=com_docman&task=doc_download&gid=3&Itemid=59)donde explica de que se trata, apenas lo estoy ojeando, ojala me quede bien claro. :P

Parece que algo estoy entendiendo, pero más sim embargo me gustaría mucho una aclaración más...una cosita más que hace el "0" en esta instrucción?

tabla0: dt   "HOLA", 0

Gracias y saludos

Edit2: Parece que aún no me a quedado bien claro lo del PCL, por lo menos de saberlo usar o como  aprovecharlo mejor, cosa uqe no he hecho, por eso me dificulta entender bien estas cosas, el problema de seguir pensando en modo PIC12F/16F84A..o de seguir leyendo libros de hace ya más de 10 años..que atrasado estoy  :(
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: BrunoF en 06 de Mayo de 2009, 17:42:29
Hola.

LOW y HIGH(y UPPER que no utilicé aquí) son tres directivas utilizadas para indicarle cuál byte utilizaremos cuando nos enfrentamos a un valor que supera el byte de tamaño.
Por ejemplo:

Si tengo como valor 0x8FA5, cuyo tamaño es de 2 bytes, si escribo:

movlw LOW 0x8FA5
el ensamblador tomará como valor el byte bajo, quedando: movlw 0xA5

Si ahora escribo:
movlw HIGH 0x8FA5
el ensamblador tomará como valor el byte alto, quedando: movlw 0x8F

El uso de estas directivas es necesario cuando usas valores que superan el byte de tamaño porque la instrucción movlw sólo puede mover un literal de 8 bits a W.
Si pones:
movlw 0x8FA5
el ensamblador va a descartar por defecto todos aquellos bits que no pueda copiar porque excede el tamaño esperado. Entonces, sólo se quedará con los 8 bits de menor peso del valor declarado. Entonces, se reducirá a: movlw 0xA5. En este caso el comportamiento es identico al del movlw LOW 0x8FA5, aunque lo adecuado es utilizar el LOW para no confundirse. Si no usas el LOW, el MPASM emitirá una advertencia indicandote que va a omitir todos los bits superiores y se va a quedar solo con los ultimos 8.



Mi algoritmo está basado en el de Maunix. Lo que se hace, es saltar a cualquier parte de la memoria FLASH, usando el PC. No importa ni siquiera en qué banco está. Si cargas el PCLATH con los valores adecuados y luego modificas el valor del PCL, el programa saltará a la posición de memoria indicada por el PC(para saber cómo está conformado el PC, lee el tutorial de león que ahí lo explico).

Cada tabla está conformada por una serie de valores, que van leyendose utilizando la instrucción RETLW valorX. Como lo que se desea era acceder en tiempo de ejecución a alguna de ellas, indicandolo mediante una variable(elemento en mi algoritmo), y dentro de ellas ir recorriendo cada valor utilizando otra variable(llamada subelemento en mi algoritmo) lo que hice fue implementar otra tabla. Esta tabla es un MAPA. Un MAPA que indica dónde se encuentra cada una de las tablas a las que se desea acceder. Esta tabla contiene las posiciones en las que se encuentra cada tabla ubicada dentro de la memoria FLASH del PIC.
El problema, es que como el PIC posee más de 256 posiciones FLASH, no me alcanza con una tabla para obtener el valor de la posición a la cual debo saltar. Por eso, he partido la tabla del MAPA en dos partes.Una tabla(DirBaja) con la parte baja de la direccion a la que debe ir y otra tabla(DirAlta) con la parte alta de la direccion a la que debe ir.

Entonces el programa va a hacer lo siguiente:

Primero:

El usuario elige el numero de tabla del cual desea leerse un subelemento. Lo hace mediante la variable elemento. Para optimizar un poco, el numero de tabla a leer se pasa como argumento en W, luego la subrutina(leer_elemento) lo almacena inmediatamente en la variable "elemento". Y también el usuario especifica el subelemento a leer de la tabla, mediante la variable "subelemento". Este es el que(comenzando desde 0 por lo general) y luego incrementandolo cada vez que se llama a la subrutina "leer_elemento" va devolviendo uno a uno cada valor de la tabla seleccionada.


Segundo:

Dentro de la subrutina "leer_elemento" lo que se procede a hacer es a obtener la dirección de la tabla a leer. Para obtener la dirección, se utiliza otra tabla, que a su vez se divide en 2 tablas(DirBaja y DirAlta) mencionadas anteriormente.

Entonces, primero se va a saltar a la posición de la FLASH indicada por: DirBaja+elemento.
LLamamos a la subrutina que hará el salto: SaltaYLee.
Como DirBaja puede estar ubicada en cualquier lugar de la FLASH, es necesario "partir" su direccion en 2 partes: baja y alta. La alta se cargará en el PCLATH, y la baja sumada al numero de tabla a leer("elemento") se moverá al registro PCL. al afectar el registro PCL, el programa automaticamente salta a la posicion pedida. Si hemos saltado correctamente, entonces habremos saltado a una instrucción RETLW x, por lo que retornaremos a la subrutina "leer_memoria" con W cargado con la posición FLASH baja de la tabla a la que deseamos acceder.Almacenamos el valor obtenido en "dirL";

Luego, se va a saltar a la posición de la FLASH indicada por: DirAlta+elemento.
LLamamos a la subrutina que hará el salto: SaltaYLee.
Como DirAlta puede estar ubicada en cualquier lugar de la FLASH, es necesario "partir" su direccion en 2 partes: baja y alta. La alta se cargará en el PCLATH, y la baja sumada al numero de tabla a leer("elemento") se moverá al registro PCL. al afectar el registro PCL, el programa automaticamente salta a la posicion pedida. Si hemos saltado correctamente, entonces habremos saltado a una instrucción RETLW x, por lo que retornaremos a la subrutina "leer_memoria" con W cargado con la posición FLASH alta de la tabla a la que deseamos acceder.Almacenamos el valor obtenido en "dirH";

Entonces, tenemos finalmente la posición de la tabla a la que deseamos acceder. Las variables "dirH" y "dirL" contienen la posición FLASH de la tabla(que es la del primer elemento de la tabla, es decir el primer RETLW X) a la que se desea acceder.

Tercero:
Ahora que sabemos en qué posición de la FLASH está ubicada la tabla, agregaremos el valor de "subelemento" a la posición encontrada, para poder acceder a un RETLW X específico dentro de la tabla elegida.

Acá viene una diferencia: Para saltar a la tabla, no voy a utilizarla como subrutina a la etiqueta "SaltaYLee" sino que voy a saltar a ella usando un "goto" en lugar de un "call".

Cuarto:
Cargo el valor de "dirH" en el PCLATH, y sumo a "dirL" el valor de "subelemento". Muevo esta suma al PCL. El PC saltará a la posición deseada. Si hicimos todo bien saltará al subelemento elegido dentro de la tabla elegido. Este debería ser un RETLW X, por lo cargará a W con el valor X y volverá. Como había usado un "goto" en lugar de un "call", el programa sale de la subrutina "leer_elemento", "aterrizando" finalmente ante la instrucción "nop" con W conteniendo el valor deseado.



Te hago un ejemplo, pero indicando también la posición de dónde se guarda cada instrucción en la FLASH del PIC para que lo puedas entender mejor:




Código: ASM
  1. list    P=16F876
  2.         include <p16F876.inc>
  3.  
  4. elemento        equ             0x20
  5. subelemento     equ             0x21
  6.  
  7. tmpL            equ             0x22
  8. tmpH            equ             0x23
  9. tmpsub          equ             0x24
  10.  
  11. dirL            equ             0x25
  12. dirH            equ             0x26
  13.  
  14.         movlw   0x00                    ;subelemento del elemento a leer(guardado en 0x000)
  15.         movwf   subelemento      ;(guardado en 0x001)
  16.         movlw   0x01                    ;elemento a leer(guardado en 0x002)
  17.         pagesel leer_elemento   ;(guardado en 0x003 y 0x004)
  18.         call    leer_elemento           ;(guardado en 0x005)
  19.         nop                                  ;(guardado en 0x006)
  20.  
  21.  
  22. leer_elemento
  23.         movwf   elemento          ;(guardado en 0x007)
  24.  
  25.         movlw   LOW DirBaja     ;(guardado en 0x008)
  26.         movwf   tmpL                ;(guardado en 0x009)
  27.         movlw   HIGH DirBaja    ;(guardado en 0x00A)
  28.         movwf   tmpH                ;(guardado en 0x00B)
  29.         movf    elemento,w               ;(guardado en 0x00C)
  30.         movwf   tmpsub             ;(guardado en 0x00D)
  31.  
  32.         movf    elemento,W              ;(guardado en 0x00E)
  33.         pagesel SaltaYLee         ;(guardado en 0x00F Y 0X010)
  34.         call    SaltaYLee                 ;(guardado en 0x011)
  35.         movwf   dirL                  ;(guardado en 0x012)
  36.  
  37.  
  38.         movlw   LOW DirAlta      ;(guardado en 0x013)
  39.         movwf   tmpL                ;(guardado en 0x014)
  40.         movlw   HIGH DirAlta     ;(guardado en 0x015)
  41.         movwf   tmpH                ;(guardado en 0x016)
  42.         movf    elemento,w               ;(guardado en 0x017)
  43.         movwf   tmpsub             ;(guardado en 0x018)
  44.         movf    elemento,W              ;(guardado en 0x019)
  45.         pagesel SaltaYLee         ;(guardado en 0x01A Y 0X01B)
  46.         call    SaltaYLee                 ;(guardado en 0x01C)
  47.         movwf   dirH                 ;(guardado en 0x01D)
  48.  
  49.         movf    dirL,W                      ;(guardado en 0x01E)
  50.         movwf   tmpL                ;(guardado en 0x01F)
  51.         movf    dirH,W                     ;(guardado en 0x020)
  52.         movwf   tmpH               ;(guardado en 0x021)
  53.         movf    subelemento,w         ;(guardado en 0x022)
  54.         movwf   tmpsub            ;(guardado en 0x023)
  55.         pagesel SaltaYLee        ;(guardado en 0x024)
  56.         goto    SaltaYLee                ;(guardado en 0x025)
  57.  
  58. SaltaYLee
  59.         movf    tmpH,W                   ;(guardado en 0x026)
  60.         movwf   PCLATH           ;(guardado en 0x027)
  61.  
  62.         movf    tmpL,W                   ;(guardado en 0x028)  
  63.         addwf   tmpsub,W        ;(guardado en 0x029)
  64.         btfsc   STATUS,C               ;(guardado en 0x02A)
  65.         incf    PCLATH,F                ;(guardado en 0x02B)
  66.        
  67.         movwf   PCL                ;(guardado en 0x02C)
  68.  
  69.         org 0X1300                      ;agrego esta linea para hacerlo un poco más real, porque las tablas seguramente irán al final de todo el programa.
  70.  
  71. DirBaja
  72.         retlw   LOW     tabla0             ;(guardado en 0x1300)
  73.         retlw   LOW     tabla1             ;(guardado en 0x1301)
  74.  
  75. DirAlta
  76.         retlw   HIGH    tabla0             ;(guardado en 0x1302)
  77.         retlw   HIGH    tabla1             ;(guardado en 0x1303)
  78.  
  79.  
  80.               org 0X19FE                      ;lo mismo, más real. Puede que el codigo este desordenado.
  81.                                                                        ;'H'        'O'       'L'         'A'      0X00
  82. tabla0: dt      "HOLA", 0                ;(guardado en 0x19FE,0x19FF,0x1A00,0x1A01,0x1A02)
  83.                                                                                  ;'B'           'R'         'U'         'N'     'O'        'F'        ' '        'E'       'S'
  84. tabla1: dt      "BRUNOF ESTUVO AQUI", 0  ;(guardado en 0x1A03,0x1A04,0x1A05,0x1A06,0x1A07,0x1A08,0x1A09,0x1A0A,0x1A0B
  85.                                                                                  ;'T'           'U'         'V'         'O'     ' '        'A'        'Q'        'U'       'I'      0X00
  86.                                                                             ;0x1A0C,0x1A0D,0x1A0E,0x1A0F,0x1A10,0x1A11,0x1A12,0x1A13,0x1A14,0x1A15
  87.         END



Ahora, el mismo ejemplo, pero muestro cómo quedarían las dos tablas mas importantes cuando ensamblás el código:




Código: ASM
  1. list    P=16F876
  2.         include <p16F876.inc>
  3.  
  4. elemento        equ             0x20
  5. subelemento     equ             0x21
  6.  
  7. tmpL            equ             0x22
  8. tmpH            equ             0x23
  9. tmpsub          equ             0x24
  10.  
  11. dirL            equ             0x25
  12. dirH            equ             0x26
  13.  
  14.         movlw   0x00                    ;subelemento del elemento a leer(guardado en 0x000)
  15.         movwf   subelemento      ;(guardado en 0x001)
  16.         movlw   0x01                    ;elemento a leer(guardado en 0x002)
  17.         pagesel leer_elemento   ;(guardado en 0x003 y 0x004)
  18.         call    leer_elemento           ;(guardado en 0x005)
  19.         nop                                  ;(guardado en 0x006)
  20.  
  21.  
  22. leer_elemento
  23.         movwf   elemento          ;(guardado en 0x007)
  24.  
  25.         [color=red]movlw       0x00[/color]                ;movlw       LOW DirBaja     ;(guardado en 0x008)
  26.         movwf   tmpL                ;(guardado en 0x009)
  27.         [color=red]movlw       0x13[/color]                ;movlw       HIGH DirBaja    ;(guardado en 0x00A)
  28.         movwf   tmpH                ;(guardado en 0x00B)
  29.         movf    elemento,w               ;(guardado en 0x00C)
  30.         movwf   tmpsub             ;(guardado en 0x00D)
  31.  
  32.         movf    elemento,W              ;(guardado en 0x00E)
  33.         pagesel SaltaYLee         ;(guardado en 0x00F Y 0X010)
  34.         call    SaltaYLee                 ;(guardado en 0x011)
  35.         movwf   dirL                  ;(guardado en 0x012)
  36.  
  37.  
  38.         [color=red]movlw       0x02[/color]                ;movlw       LOW DirAlta      ;(guardado en 0x013)
  39.         movwf   tmpL                ;(guardado en 0x014)
  40.         [color=red]movlw       0x13[/color]                ;movlw       HIGH DirAlta     ;(guardado en 0x015)
  41.         movwf   tmpH                ;(guardado en 0x016)
  42.         movf    elemento,w               ;(guardado en 0x017)
  43.         movwf   tmpsub             ;(guardado en 0x018)
  44.         movf    elemento,W              ;(guardado en 0x019)
  45.         pagesel SaltaYLee         ;(guardado en 0x01A Y 0X01B)
  46.         call    SaltaYLee                 ;(guardado en 0x01C)
  47.         movwf   dirH                 ;(guardado en 0x01D)
  48.  
  49.         movf    dirL,W                      ;(guardado en 0x01E)
  50.         movwf   tmpL                ;(guardado en 0x01F)
  51.         movf    dirH,W                     ;(guardado en 0x020)
  52.         movwf   tmpH               ;(guardado en 0x021)
  53.         movf    subelemento,w         ;(guardado en 0x022)
  54.         movwf   tmpsub            ;(guardado en 0x023)
  55.         pagesel SaltaYLee        ;(guardado en 0x024)
  56.         goto    SaltaYLee                ;(guardado en 0x025)
  57.  
  58. SaltaYLee
  59.         movf    tmpH,W                   ;(guardado en 0x026)
  60.         movwf   PCLATH           ;(guardado en 0x027)
  61.  
  62.         movf    tmpL,W                   ;(guardado en 0x028)  
  63.         addwf   tmpsub,W        ;(guardado en 0x029)
  64.         btfsc   STATUS,C               ;(guardado en 0x02A)
  65.         incf    PCLATH,F                ;(guardado en 0x02B)
  66.        
  67.         movwf   PCL                ;(guardado en 0x02C)
  68.  
  69.         org 0X1300                      ;agrego esta linea para hacerlo un poco más real, porque las tablas seguramente irán al final de todo el programa.
  70.  
  71. DirBaja
  72.         [color=red]retlw       0xFE[/color]                ;retlw       LOW     tabla0             ;(guardado en 0x1300)
  73.         [color=redretlw       0x03[/color]                ;retlw        LOW     tabla1             ;(guardado en 0x1301)
  74.  
  75. DirAlta
  76.         [color=red]retlw       0x19[/color]                ;retlw       HIGH    tabla0             ;(guardado en 0x1302)
  77.         [color=red]movlw       0x1A[/color]                ;retlw       HIGH    tabla1             ;(guardado en 0x1303)
  78.  
  79.  
  80.               org 0X19FE                      ;lo mismo, más real. Puede que el codigo este desordenado.
  81.                                                                        ;'H'        'O'       'L'         'A'      0X00
  82. tabla0: dt      "HOLA", 0                ;(guardado en 0x19FE,0x19FF,0x1A00,0x1A01,0x1A02)
  83.                                                                                  ;'B'           'R'         'U'         'N'     'O'        'F'        ' '        'E'       'S'
  84. tabla1: dt      "BRUNOF ESTUVO AQUI", 0  ;(guardado en 0x1A03,0x1A04,0x1A05,0x1A06,0x1A07,0x1A08,0x1A09,0x1A0A,0x1A0B
  85.                                                                                  ;'T'           'U'         'V'         'O'     ' '        'A'        'Q'        'U'       'I'      0X00
  86.                                                                             ;0x1A0C,0x1A0D,0x1A0E,0x1A0F,0x1A10,0x1A11,0x1A12,0x1A13,0x1A14,0x1A15
  87.         END


Fijate que las tablas DirBaja y DirAlta almacenan las posiciones de las tablas, parte baja y alta respectivamente.

En cuanto al STACK: Te marco los niveles(del STACK) con el codigo resumido para que lo veas:


Inicialmente NIVEL =0
        ;...
   call   leer_elemento           ;NIVEL=1
        ;...
   call   SaltaYLee                 ;NIVEL=2
   retlw X                             ;NIVEL=1         
        ;...     
   call   SaltaYLee                 ;NIVEL=2
   retlw X                             ;NIVEL=1         
        ;...     
   goto   SaltaYLee                 ;NIVEL=1. el goto no carga el STACK
   retlw X                             ;NIVEL=0               
        nop



El <, 0> al final de las tablas significa que estás agregando un retlw 0x00 al final de cada tabla, para indicar el fin de la mísma(lo que estabas usando en tu programa). La ',' concatena valores o cadenas de texto.




La limitación es de 256 WORDS POR TABLA. Esto quiere decir que CADA tabla no debería exceder los 256 WORDS de longitud. Si es necesario una tabla de mayor tamaño, debes utilizar una variable de 16 bits para realizar el offset(es decir, subelemento debe ser de 16 bits).Las tablas en su conjunto pueden usar toda la FLASH disponible si te da la gana.


Saludos.
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: marvicdigital en 06 de Mayo de 2009, 19:55:29
Valla, BrunoF, como agradezco tu brillante explicación, más claro no puede ser, ahora asimilo más el funcionamiento de este llamado de tablas, estoy haciendo unos ejercicios con algo sencillo para que me quede bien claro de verdad que mil gracias..ya ni se como agradecerte tanta explicación y que me estés enseñando  :mrgreen:

Saludos
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: marvicdigital en 07 de Mayo de 2009, 08:24:57
BrunoF, me tomé el atrevimiento de pasar tu valiosa información a un archivo PDF, para que quede como un valioso documento y no se valla a perder por el foro  :mrgreen: espero les sirva a muchos que, como Yo, ingnorabamos esto; en este punto  aclaro que tengo varios libros de PIC y en ninguno encontré una explicación sobre lo que expone BrunoF, es más en uno de ellos trata sobre los PIC16F87x y el PCLTAH pasa sin pena ni gloria, es más  he leído de ese libro por encima todo el indice, el glosario, los ejemplos y explicaciones y en ninguno he encontrado nada que mencione con tanto detalle e interés como la explicación de BrunoF..ignoro si esta técnica es nueva, o si por esta razón el PCLATH a tomado mucha importancia de la que tenía.
Los libros que tengo todos el más reciente es de el 2001

Saludos
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: BrunoF en 07 de Mayo de 2009, 15:09:20
Hola marvic. Muchas gracias por el atrevimieto. No creo que haya libro alguno que pueda enseñarte todos los trucos, usos y posibilidades de un uC. Lo que vos tenés que hacer es estudiar y aprender a fondo qué hace cada instrucción y cada registro del uC. Los libros seguramente sólo te enseñarán lo básico pero no van a llegar a explicarte ciertos algoritmos o usos avanzados como éste.

Un saludo.
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: Miquel_S en 23 de Junio de 2009, 04:42:41
Hola maunix una pregunta tonta, quiero colaborar con los ejemplos pero no se como ponerlos en tu indice  :mrgreen: :mrgreen:

Perdona mi torpeza.
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: zerc79 en 23 de Junio de 2009, 10:08:43
Hola marvic. Muchas gracias por el atrevimieto. No creo que haya libro alguno que pueda enseñarte todos los trucos, usos y posibilidades de un uC. Lo que vos tenés que hacer es estudiar y aprender a fondo qué hace cada instrucción y cada registro del uC. Los libros seguramente sólo te enseñarán lo básico pero no van a llegar a explicarte ciertos algoritmos o usos avanzados como éste.

Un saludo.

Hola y Gracias a maunix por el compartir estos datos valiosos y a BrunoF por tremenda explicacion y dedicacion a compartir con nosotros los "novatos" en el tema..

 :-/ Fenomenal....

Ya vez por estas explicaciones uno no tiene tanto que preguntar...solamente leer y leer para aprender
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: pelacable en 19 de Febrero de 2010, 18:44:10
HOLA BrunoF!
Probé tu rutina de buscar un subelemento dentro del elemento y me pareció muy útil :-/
Ahora, si tomo los valores de un ADC y los quiero direccionar a la tabla, ¿no me faltaría una rutina de conversion de binario a decimal, para aplicarla a la tabla?
O dicho de otro modo ¿como sería la rutina para manejar tablas dt para unidades, decenas y centenas, al ser tres tablas la rutina de los subelemantos parece muy apropiada pero como podría direccionarlas con los valores del ADC?

Agradezco tu paciencia infinita y que compartas tu sabiduría, Quedé impresionado con tu brillante explicación, estoy aprendiendo mucho de tanto leer en éste foro, pero hay lugares que se me pasan, si ya hay un hilo con lo que te pido, te agradecería que me lo indiques.

Quiero hacer un instrumento de medición y contról con LCD y 16f877
Ya compilé las rutinas de mensajes que voy a sacar por el display 2x20 y las de contról,
usando las tablas que uds. publicaron y funciona todo perfecto sin simulación directamente con el pic y el lcd, aprendí mucho pero me falta mucho más.

¡GRACIAS  a todo el foro por haberme ayudado hasta acá sin saberlo!!!!


 :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: todopic en 19 de Febrero de 2010, 18:58:50
Ahora, si tomo los valores de un ADC y los quiero direccionar a la tabla, ¿no me faltaría una rutina de conversion de binario a decimal, para aplicarla a la tabla?

Hola, el micro, trabaja en binario... para que quieres pasarlo a decimal? no tiene sentido.... simplemente direccionas con el valor del AD  a la tabla (pero ojo en no pasarte de la misma....  :mrgreen:)

Norberto
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: pelacable en 19 de Febrero de 2010, 21:22:52
Hola
Está claro que trabaja en binario, pero debido a mi ignorancia, creí entender que para seleccionar una dirección dentro de la tabla, y solo una, por eso sería un subelemento, primero se colocaban los valores bajos y altos para elegir la dirección de la tabla y luego, con .xx se daba la posición del valor a seleccionar dentro de la misma.
si yo cambio el valor de .xx segun el ejemplo también me cambia la posición en la tabla.
Ahora .xx es un valor en decimal, ¿no tendría que convertir el binario a decimal para ubicarlo acá en el lugar ".xx"
Supongo que hablamos de la misma rutina... :(

Hay un dicho que reza: Caballo viejo no agarra trote, y yo ya estoy para el matadero :mrgreen:  pero sigo insistiendo porque antes no sabía ni usar la compu y ahora quiero fabricar la mía, tenganme paciencia  y gracias
Nota: no me gusta copiarme de nadie, solo que tengan la gentileza de tirarme una soga, seguiré buscando por el foro.

Nuevamente gracias!!!  :P
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: pelacable en 19 de Febrero de 2010, 23:17:45
Hola de nuevo
jejejeje confundì las rutinas, mezclè las de maunix, a quien doy las gracias, porque funcionaron muy bien, con las de brunof, que me pareciò que me podrìan venir mejor para sacar lo que necesito, por favor brunof disculpame.  : :oops:
Entonces, de la rutina que hablo es  la de maunix. : :mrgreen:

Aclarado èsto aprovecho a preguntar ¿cual rutina es màs conveniente para lo que quiero hacer?

      Gracias!



Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: pelacable en 21 de Febrero de 2010, 22:31:32
Ahora, si tomo los valores de un ADC y los quiero direccionar a la tabla, ¿no me faltaría una rutina de conversion de binario a decimal, para aplicarla a la tabla?

Hola, el micro, trabaja en binario... para que quieres pasarlo a decimal? no tiene sentido.... simplemente direccionas con el valor del AD  a la tabla (pero ojo en no pasarte de la misma....  :mrgreen:)

Norberto

HOLA A TODOS!!
 
Estimado Norberto: 

Queria decirte que probè como me dijiste, y le mandè el valor del AD directo a OFFSET y funcionò  :-/  El ùnico problema que tuve es que quise sacar nùmeros con la tabla dt y no supe como, los valores que ponìa siempre me mandaban a caracteres ascii. (nunca usè tablas de èste tipo)

Lo solucionè con las tablas tradicioales (yo le llamo verticales)

Como son tres tablas de 255 datos, usè la pàgina 4 del 16f877 y la direccionè segùn una aclaraciòn de uso de la AN556 que encontrè en el foro  :-/ los pocos datos que le puse los tomò muy bien y (sin pasarme, como me aconsejaste) :D :D :D :D
Ahora voy a saguir cargando el resto de las tablas, pero sigo con la duda de como sacar nùmeros de las tablas dt ( horizontales, como yo las llamo) to davìa no encontrè ningùn ejemplo...
Cuando pueda sigo probando, porque considero que estando los nùmeros en la tabla en donde me aparecen los caracteres, algun dìa los encontrarè.
Gracias por haberme contestado antes :-/

          Pelacable

Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: BrunoF en 22 de Febrero de 2010, 20:27:42
Hola maunix una pregunta tonta, quiero colaborar con los ejemplos pero no se como ponerlos en tu indice  :mrgreen: :mrgreen:

Perdona mi torpeza.

Enviamelos a mi y yo los agrego al indice.

Saludos.

Ahora, si tomo los valores de un ADC y los quiero direccionar a la tabla, ¿no me faltaría una rutina de conversion de binario a decimal, para aplicarla a la tabla?

Hola, el micro, trabaja en binario... para que quieres pasarlo a decimal? no tiene sentido.... simplemente direccionas con el valor del AD  a la tabla (pero ojo en no pasarte de la misma....  :mrgreen:)

Norberto

HOLA A TODOS!!
 
Estimado Norberto: 

Queria decirte que probè como me dijiste, y le mandè el valor del AD directo a OFFSET y funcionò  :-/  El ùnico problema que tuve es que quise sacar nùmeros con la tabla dt y no supe como, los valores que ponìa siempre me mandaban a caracteres ascii. (nunca usè tablas de èste tipo)

Lo solucionè con las tablas tradicioales (yo le llamo verticales)

Como son tres tablas de 255 datos, usè la pàgina 4 del 16f877 y la direccionè segùn una aclaraciòn de uso de la AN556 que encontrè en el foro  :-/ los pocos datos que le puse los tomò muy bien y (sin pasarme, como me aconsejaste) :D :D :D :D
Ahora voy a saguir cargando el resto de las tablas, pero sigo con la duda de como sacar nùmeros de las tablas dt ( horizontales, como yo las llamo) to davìa no encontrè ningùn ejemplo...
Cuando pueda sigo probando, porque considero que estando los nùmeros en la tabla en donde me aparecen los caracteres, algun dìa los encontrarè.
Gracias por haberme contestado antes :-/

          Pelacable



dt 0x00,0xFF,.250,b'01001000',"HOL",'A',0

Se puede mezclar casi cualquier cosa...
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: todopic en 22 de Febrero de 2010, 21:19:12
Hola Pelacables.. entiendo que cuando dices "sacar"es por un LCD... entonces tendras que sumarle al valor del numero, el 30h  o .48  para pasarlo al correspondiente ASCII  (30 en hexa o 48 en decimal)  :mrgreen:

Un abrazo

Norberto
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: pelacable en 23 de Febrero de 2010, 10:56:52
Hola a todos!!

   Justamente, quiero poner en un LCD 2X20 , En la línea superior el mensaje: Valor requerido: xx,x

                                                                   En la línea inferior el mensaje: Valor  obtenido : xx,x

Ya logré que al encender la pantalla salga el mensaje de presentacion, y que luego de oprimir un botón cambie de mensaje comenzando una temporización de 5 minutos, pero si dentro de ese tiempo se vuelve a oprimir el mismo boton: RUN/STOP, se detiene la temporización, coloca el mensaje "DESACTIVANDO FUNCIONES" por 4 segundos y vuelve al mensaje de presentación.
Si no se oprime el botón STOP, la temporización de 5 minutos continúa y al finalizar, cambia el mensaje a "COMENZANDO MEDICÓN", lo muestra por 4 segundos y cambia nuevamente los mensajes a Valor requerido y Valor obtenido, mostrando los diferentes valores que llegan desde el AD.
Todo ésto lo tengo resuelto y funciona muy bien, incluso, durante la temporización de 5 minutos manejo los puertos para activar distintos elementos.

Las comparaciones y activación de salidas en función de los valores de setpoint y los obtenidos, también funcionan.

El valor de setpoint lo hago por ahora, variando un multivueltas y leyendolo con otro canal del AD. (cuando practique la lectura y escritura en eeprom , guardaré el valor del setpoint con dos teclas más), eso más adelante.

Como verán solo me queda poner los dichosos números en el lugar del LCD que ya definí.

Puse los valores como decía BrunoF,  0x00, 0x01,etc.etc pero como decía antes salía cualquier cosa  :D  :D

Ahora por lo que tu dices, Norberto, ya entiendo lo que faltaba, voy a probar y después les cuento como resultó.

Nota:
Se preguntarán ¿como visualizo los datos del AD para probar el contról, si no tengo la información el el LCD?
pues saco el valor binario por los puertos y enciendo leds, 8 por cada canal del AD, simple pero a falta de pan........

 Gracias por compartir lo que saben , espero algún día poder hacerlo yo! :mrgreen:

 Un abrazo
 Pelacable
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: Resistencio en 14 de Octubre de 2010, 19:56:13
Otra BIBLIA de BRUNOF !!! Cuarto o Quinto testamento, perdí la cuenta !!!

SALUDOS !!!
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: akira_ve en 06 de Diciembre de 2010, 12:35:36
amigo por casualidad saben resolver el problema de la libreria LCD_4BIT.INC, no funciona con 4Mhz se que hay que agregarle unos temporizadores para que funcione he entrado en la pagina de la editoria RAMA y no aparece, y no recuerdo donde se colocan
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: akira_ve en 06 de Diciembre de 2010, 13:52:32
Diculpen consegui la informacion.............cuando se usa esa libreria con proteus a 4 Mhz no sucede nada por lo tanto hay que modificarla y aqui dicen como hacerlo, y funciona;

http://www.pic16f84a.org/index.php?option=com_content&view=article&id=82:simulacion-del-lcd-en-proteus&catid=38:pic16f84&Itemid=60
Título: Re: Ejemplos en Assembler - PIC16F876
Publicado por: frozen en 01 de Noviembre de 2011, 09:55:56
Bueno soy nuevo en el foro. Aqui les dejo mis macros.

Saludos a todos. :)