Autor Tema: Guardar valor modulo ADC  (Leído 6930 veces)

0 Usuarios y 3 Visitantes están viendo este tema.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Guardar valor modulo ADC
« Respuesta #15 en: 04 de Mayo de 2015, 05:08:59 »
Parece que la funcion LCD_Mensaje no te va a servir. Por que toma referencia desde la etiqueta Mensajes.

Podrias poner la funcion:

LCD_Caracter

Creo que es esa a la que tenes que llamar y cargar el valor en LCD_ValorCaracter

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Guardar valor modulo ADC
« Respuesta #16 en: 09 de Mayo de 2015, 18:36:01 »
Nada que no lo consigo, solo consigo visualizar cualquier numero excepto el que debería, os dejo el código usado a ver si alguien me alumbra el camino.
Main:
Código: ASM
  1. CBLOCK 0x30
  2.         Num_Binario
  3.         Centena
  4.         Decena
  5.         Unidad
  6.     ENDC
  7.  
  8. ;------------------------------------------------------------------------------
  9. ; RESET VECTOR
  10. ;------------------------------------------------------------------------------
  11.  
  12. RESET     ORG     0x0000            ; processor reset vector
  13.           PAGESEL START
  14.           GOTO    START             ; go to beginning of program
  15.  
  16. ;Tabla para Mensajes.........................
  17. Mensajes                        ;Etiqueta obligatoria
  18.         addwf       PCL,F
  19. Mensaje0                        ;Posicion inicial del mensaje
  20.         DT "   BCD 8-bits",0x00    ;Mensaje terminado en 0x00
  21. Mensaje1
  22.         DT "DECIMAL: ",0x00
  23.  
  24. ;------------------------------------------------------------------------------
  25. ; MAIN PROGRAM
  26. ;------------------------------------------------------------------------------
  27.  
  28. START
  29. ;Configuramos el oscilador interno para 4MHz........
  30.         banksel     OSCCON          ;Banco 1
  31.         bsf         OSCCON,IRCF2
  32.         bsf         OSCCON,IRCF1
  33.         bcf         OSCCON,IRCF0
  34.  
  35. ;Configuramos los puertos del PIC........
  36.         banksel     PORTA           ;Banco 0
  37.         clrf        PORTA
  38.         clrf        PORTB
  39.         banksel     ANSEL           ;Banco 1
  40.         movlw       b'00000000'
  41.         movwf       ANSEL
  42.         clrf        TRISA
  43.         clrf        TRISB
  44.  
  45. ;Configuramos el LCD........
  46.         call        LCD_Inicializa  ;Inicializamos el LCD
  47.  
  48. ;Mensaje de Bienvenida........
  49.         pageselw    Mensaje0
  50.         movlw       Mensaje0
  51.         call        LCD_Mensaje     ;Visualizamos BCD 8-bits en la primera linea
  52.  
  53. ;Conversion a decimal........
  54.         call        LCD_Linea2      ;Visualizamos en la segunda linea del LCD
  55.         pageselw    Mensaje1
  56.         movlw       Mensaje1
  57.         call        LCD_Mensaje
  58.         movlw       0xAF            ;Cargamos W con el valor 175 en decimal
  59.         movwf       Num_Binario
  60.         call        Binario_BCD     ;Llamamos a la rutina de conversion
  61.         movlw       Unidad
  62.         call        LCD_Caracter
  63.         movlw       Decena
  64.         movwf       LCD_Caracter
  65.         movlw       Centena
  66.         movwf       LCD_Caracter
  67.         sleep                       ;Modo reposo
  68.  
  69. ;Rutinas para control del LCD........
  70. #include retardos.INC
  71. #include lcd_4bit.INC
  72. #include LCD_MENS.INC
  73. #include Bin_BCD.INC
  74.  
  75.         END
lcd_4bits.INC:
Código: ASM
  1. ; ZONA DE DATOS *********************************************************************
  2.  
  3.  
  4.  
  5.         CBLOCK  0x20
  6.  
  7.         LCD_Dato
  8.  
  9.         LCD_GuardaDato
  10.  
  11.         LCD_GuardaTRISB
  12.  
  13.         LCD_Auxiliar1
  14.  
  15.         LCD_Auxiliar2
  16.  
  17.         ENDC
  18.  
  19.  
  20.  
  21. LCD_CaracteresPorLinea  EQU     .16     ; Número de caracteres por línea de la pantalla.
  22.  
  23.  
  24.  
  25. #DEFINE  LCD_PinRS      PORTA,2
  26.  
  27. #DEFINE  LCD_PinRW      PORTA,1
  28.  
  29. #DEFINE  LCD_PinEnable  PORTA,3
  30.  
  31. #DEFINE  LCD_BusDatos   PORTB
  32.  
  33.  
  34.  
  35. ; Subrutina "LCD_Inicializa" ------------------------------------------------------------
  36.  
  37. ;
  38.  
  39. ; Inicialización del módulo LCD: Configura funciones del LCD, produce reset por software,
  40.  
  41. ; borra memoria y enciende pantalla. El fabricante especifica que para garantizar la
  42.  
  43. ; configuración inicial hay que hacerla como sigue:
  44.  
  45. ;
  46.  
  47. LCD_Inicializa
  48.  
  49.         ;bsf    STATUS,RP0              ; Configura las líneas conectadas al pines RS,
  50.  
  51.         bcf     LCD_PinRS               ; R/W y E.
  52.  
  53.         bcf     LCD_PinEnable
  54.  
  55.         bcf     LCD_PinRW
  56.  
  57.         bcf     STATUS,RP0
  58.  
  59.         bcf     LCD_PinRW               ; En caso de que esté conectado le indica
  60.  
  61.                                         ; que se va a escribir en el LCD.
  62.  
  63.         bcf     LCD_PinEnable           ; Impide funcionamiento del LCD poniendo E=0.
  64.  
  65.         bcf     LCD_PinRS               ; Activa el Modo Comando poniendo RS=0.
  66.  
  67.         call    Retardo_20ms
  68.  
  69.         movlw   b'00110000'    
  70.  
  71.         call    LCD_EscribeLCD          ; Escribe el dato en el LCD.
  72.  
  73.         call    Retardo_5ms    
  74.  
  75.         movlw   b'00110000'    
  76.  
  77.         call    LCD_EscribeLCD
  78.  
  79.         call    Retardo_200micros
  80.  
  81.         movlw   b'00110000'    
  82.  
  83.         call    LCD_EscribeLCD
  84.  
  85. ;call Retardo_20micros ; Retardo necesario para simular en PROTEUS.
  86.  
  87.         movlw   b'00100000'             ; Interface de 4 bits.
  88.  
  89.         call    LCD_EscribeLCD
  90.  
  91. ;call Retardo_20micros ; Retardo necesario para simular en PROTEUS.
  92.  
  93. ; Ahora configura el resto de los parámetros:
  94.  
  95.  
  96.  
  97.         call    LCD_2Lineas4Bits5x7     ; LCD de 2 líneas y caracteres de 5x7 puntos.
  98.  
  99.         call    LCD_Borra               ; Pantalla encendida y limpia. Cursor al principio
  100.  
  101.         call    LCD_CursorOFF           ; de la línea 1. Cursor apagado.
  102.  
  103.         call    LCD_CursorIncr          ; Cursor en modo incrementar.
  104.  
  105.         return
  106.  
  107.  
  108.  
  109. ; Subrutina "LCD_EscribeLCD" -----------------------------------------------------------
  110.  
  111. ;
  112.  
  113. ; Envía el dato del registro de trabajo W al bus de dato y produce un pequeño pulso en el pin
  114.  
  115. ; Enable del LCD. Para no alterar el contenido de las líneas de la parte baja del Puerto B que
  116.  
  117. ; no son utilizadas para el LCD (pines RB3:RB0), primero se lee estas líneas y después se
  118.  
  119. ; vuelve a enviar este dato sin cambiarlo.
  120.  
  121.  
  122.  
  123. LCD_EscribeLCD
  124.  
  125.         andlw   b'11110000'             ; Se queda con el nibble alto del dato que es el
  126.  
  127.         movwf   LCD_Dato                ; que hay que enviar y lo guarda.
  128.  
  129.         movf    LCD_BusDatos,W          ; Lee la información actual de la parte baja
  130.  
  131.         andlw   b'00001111'             ; del Puerto B, que no se debe alterar.
  132.  
  133.         iorwf   LCD_Dato,F              ; Enviará la parte alta del dato de entrada
  134.  
  135.                                         ; y en la parte baja lo que había antes.
  136.  
  137.         bsf     STATUS,RP0              ; Acceso al Banco 1.
  138.  
  139.         movf    TRISB,W         ; Guarda la configuración que tenía antes TRISB.
  140.  
  141.         movwf   LCD_GuardaTRISB
  142.  
  143.         movlw   b'00001111'             ; Las 4 líneas inferiores del Puerto B se dejan
  144.  
  145.         andwf   PORTB,F                 ; como estaban y las 4 superiores como salida.
  146.  
  147.         bcf     STATUS,RP0              ; Acceso al Banco 0.
  148.  
  149. ;
  150.  
  151.         movf    LCD_Dato,W              ; Recupera el dato a enviar.
  152.  
  153.         movwf   LCD_BusDatos            ; Envía el dato al módulo LCD.
  154.  
  155.         bsf     LCD_PinEnable           ; Permite funcionamiento del LCD mediante un pequeño
  156.  
  157.         bcf     LCD_PinEnable           ; pulso y termina impidiendo el funcionamiento del LCD.
  158.  
  159.         bsf     STATUS,RP0              ; Acceso al Banco 1. Restaura el antiguo valor en
  160.  
  161.         movf    LCD_GuardaTRISB,W       ; la configuración del Puerto B.
  162.  
  163.         movwf   PORTB                   ; Realmente es TRISB.
  164.  
  165.         bcf     STATUS,RP0              ; Acceso al Banco 0.
  166.  
  167.         return
  168.  
  169.  
  170.  
  171. ; Subrutinas variadas para el control del módulo LCD -----------------------------------------
  172.  
  173. ;
  174.  
  175. ;Los comandos que pueden ser ejecutados son:
  176.  
  177. ;
  178.  
  179. LCD_CursorIncr                          ; Cursor en modo incrementar.
  180.  
  181.         movlw   b'00000110'
  182.  
  183.         goto    LCD_EnviaComando
  184.  
  185. LCD_Linea1                              ; Cursor al principio de la Línea 1.
  186.  
  187.         movlw   b'10000000'             ; Dirección 00h de la DDRAM
  188.  
  189.         goto    LCD_EnviaComando
  190.  
  191. LCD_Linea2                              ; Cursor al principio de la Línea 2.
  192.  
  193.         movlw   b'11000000'             ; Dirección 40h de la DDRAM
  194.  
  195.         goto    LCD_EnviaComando
  196.  
  197. LCD_PosicionLinea1                      ; Cursor a posición de la Línea 1, a partir de la
  198.  
  199.         iorlw   b'10000000'             ; dirección 00h de la DDRAM más el valor del
  200.  
  201.         goto    LCD_EnviaComando        ; registro W.
  202.  
  203. LCD_PosicionLinea2                      ; Cursor a posición de la Línea 2, a partir de la
  204.  
  205.         iorlw   b'11000000'             ; dirección 40h de la DDRAM más el valor del
  206.  
  207.         goto    LCD_EnviaComando        ; registro W.
  208.  
  209. LCD_OFF                         ; Pantalla apagada.
  210.  
  211.         movlw   b'00001000'
  212.  
  213.         goto    LCD_EnviaComando
  214.  
  215. LCD_CursorON                            ; Pantalla encendida y cursor encendido.
  216.  
  217.         movlw   b'00001110'
  218.  
  219.         goto    LCD_EnviaComando
  220.  
  221. LCD_CursorOFF                           ; Pantalla encendida y cursor apagado.
  222.  
  223.         movlw   b'00001100'
  224.  
  225.         goto    LCD_EnviaComando
  226.  
  227. LCD_Borra                               ; Borra toda la pantalla, memoria DDRAM y pone el
  228.  
  229.         movlw   b'00000001'             ; cursor a principio de la línea 1.
  230.  
  231.         goto    LCD_EnviaComando
  232.  
  233. LCD_2Lineas4Bits5x7                     ; Define la pantalla de 2 líneas, con caracteres
  234.  
  235.         movlw   b'00101000'             ; de 5x7 puntos y conexión al PIC mediante bus de
  236.  
  237. ;       goto    LCD_EnviaComando        ; 4 bits.
  238.  
  239.  
  240.  
  241. ; Subrutinas "LCD_EnviaComando" y "LCD_Caracter" ------------------------------------
  242.  
  243. ;
  244.  
  245. ; "LCD_EnviaComando". Escribe un comando en el registro del módulo LCD. La palabra de
  246.  
  247. ; comando ha sido entregada a través del registro W.  Trabaja en Modo Comando.
  248.  
  249. ; "LCD_Caracter". Escribe en la memoria DDRAM del LCD el carácter ASCII introducido a
  250.  
  251. ; a través del registro W. Trabaja en Modo Dato.
  252.  
  253. ;
  254.  
  255. LCD_EnviaComando
  256.  
  257.         bcf     LCD_PinRS               ; Activa el Modo Comando, poniendo RS=0.
  258.  
  259.         goto    LCD_Envia
  260.  
  261. LCD_Caracter
  262.  
  263.         bsf     LCD_PinRS               ; Activa el "Modo Dato", poniendo RS=1.
  264.  
  265.         call    LCD_CodigoCGROM ; Obtiene el código para correcta visualización.
  266.  
  267. LCD_Envia
  268.  
  269.         movwf   LCD_GuardaDato          ; Guarda el dato a enviar.
  270.  
  271.         call    LCD_EscribeLCD          ; Primero envía el nibble alto.
  272.  
  273.         swapf   LCD_GuardaDato,W        ; Ahora envía el nibble bajo. Para ello pasa el
  274.  
  275.                                         ; nibble bajo del dato a enviar a parte alta del byte.
  276.  
  277.         call    LCD_EscribeLCD          ; Se envía al visualizador LCD.
  278.  
  279.         btfss   LCD_PinRS               ; Debe garantizar una correcta escritura manteniendo
  280.  
  281.         call    Retardo_2ms             ; 2 ms en modo comando y 50 µs en modo cáracter.
  282.  
  283.         call    Retardo_50micros
  284.  
  285.         return 
  286.  
  287.  
  288.  
  289. ; Subrutina "LCD_CodigoCGROM" -----------------------------------------------------------
  290.  
  291. ;
  292.  
  293. ; A partir del carácter ASCII número 127 los códigos de los caracteres definidos en la
  294.  
  295. ; tabla CGROM del LM016L no coinciden con los códigos ASCII. Así por ejemplo, el código
  296.  
  297. ; ASCII de la "Ñ" en la tabla CGRAM del LM016L es EEh.
  298.  
  299. ;
  300.  
  301. ; Esta subrutina convierte los códigos ASCII de la "Ñ", "º" y otros, a códigos CGROM para que
  302.  
  303. ; que puedan ser visualizado en el módulo LM016L.
  304.  
  305. ;
  306.  
  307. ; Entrada:      En (W) el código ASCII del carácter que se desea visualizar.
  308.  
  309. ; Salida:       En (W) el código definido en la tabla CGROM.
  310.  
  311.  
  312.  
  313. LCD_CodigoCGROM
  314.  
  315.         movwf   LCD_Dato                ; Guarda el valor del carácter y comprueba si es
  316.  
  317. LCD_EnheMinuscula                       ; un carácter especial.
  318.  
  319.         sublw   'ñ'                    ; ¿Es la "ñ"?
  320.  
  321.         btfss   STATUS,Z
  322.  
  323.         goto    LCD_EnheMayuscula       ; No es "ñ".
  324.  
  325.         movlw   b'11101110'             ; Código CGROM de la "ñ".
  326.  
  327.         movwf   LCD_Dato
  328.  
  329.         goto    LCD_FinCGROM
  330.  
  331. LCD_EnheMayuscula
  332.  
  333.         movf    LCD_Dato,W              ; Recupera el código ASCII de entrada.
  334.  
  335.         sublw   'Ñ'                    ; ¿Es la "Ñ"?
  336.  
  337.         btfss   STATUS,Z
  338.  
  339.         goto    LCD_Grado               ; No es "Ñ".
  340.  
  341.         movlw   b'11101110'             ; Código CGROM de la "ñ". (No hay símbolo para
  342.  
  343.         movwf   LCD_Dato                ; la "Ñ" mayúscula en la CGROM).
  344.  
  345.         goto    LCD_FinCGROM   
  346.  
  347. LCD_Grado
  348.  
  349.         movf    LCD_Dato,W              ; Recupera el código ASCII de entrada.
  350.  
  351.         sublw   'º'                    ; ¿Es el símbolo "º"?
  352.  
  353.         btfss   STATUS,Z
  354.  
  355.         goto    LCD_FinCGROM            ; No es "º".
  356.  
  357.         movlw   b'11011111'             ; Código CGROM del símbolo "º".
  358.  
  359.         movwf   LCD_Dato
  360.  
  361. LCD_FinCGROM
  362.  
  363.         movf    LCD_Dato,W              ; En (W) el código buscado.
  364.  
  365.         return
  366.  
  367.  
  368.  
  369. ; Subrutina "LCD_DosEspaciosBlancos" y "LCD_LineaBlanco" --------------------------------
  370.  
  371. ;
  372.  
  373. ; Visualiza espacios en blanco.
  374.  
  375.  
  376.  
  377. LCD_LineaEnBlanco
  378.  
  379.         movlw   LCD_CaracteresPorLinea
  380.  
  381.         goto    LCD_EnviaBlancos
  382.  
  383. LCD_UnEspacioBlanco
  384.  
  385.         movlw   .1
  386.  
  387.         goto    LCD_EnviaBlancos
  388.  
  389. LCD_DosEspaciosBlancos
  390.  
  391.         movlw   .2
  392.  
  393.         goto    LCD_EnviaBlancos
  394.  
  395. LCD_TresEspaciosBlancos
  396.  
  397.         movlw   .3
  398.  
  399. LCD_EnviaBlancos
  400.  
  401.         movwf   LCD_Auxiliar1           ; (LCD_Auxiliar1) se utiliza como contador.
  402.  
  403. LCD_EnviaOtroBlanco    
  404.  
  405.         movlw   ' '                     ; Esto es un espacio en blanco.
  406.  
  407.         call    LCD_Caracter            ; Visualiza tanto espacios en blanco como se
  408.  
  409.         decfsz  LCD_Auxiliar1,F         ; haya cargado en (LCD_Auxiliar1).
  410.  
  411.         goto    LCD_EnviaOtroBlanco
  412.  
  413.         return
  414.  
  415.  
  416.  
  417. ; Subrutinas "LCD_ByteCompleto" y "LCD_Byte" --------------------------------------------
  418.  
  419. ;
  420.  
  421. ; Subrutina "LCD_ByteCompleto", visualiza el byte que almacena el registro W en el
  422.  
  423. ; lugar actual de la pantalla. Por ejemplo, si (W)=b'10101110' visualiza "AE".
  424.  
  425. ;
  426.  
  427. ; Subrutina "LCD_Byte" igual que la anterior, pero en caso de que el nibble alto sea cero
  428.  
  429. ; visualiza en su lugar un espacio en blanco. Por ejemplo si (W)=b'10101110' visualiza "AE"
  430.  
  431. ; y si (W)=b'00001110', visualiza " E" (un espacio blanco delante).
  432.  
  433. ;
  434.  
  435. ; Utilizan la subrutina "LCD_Nibble" que se analiza más adelante.
  436.  
  437. ;
  438.  
  439. LCD_Byte
  440.  
  441.         movwf   LCD_Auxiliar2           ; Guarda el valor de entrada.
  442.  
  443.         andlw   b'11110000'             ; Analiza si el nibble alto es cero.
  444.  
  445.         btfss   STATUS,Z                ; Si es cero lo apaga.
  446.  
  447.         goto    LCD_VisualizaAlto               ; No es cero y lo visualiza.
  448.  
  449.         movlw   ' '                     ; Visualiza un espacio en blanco.
  450.  
  451.         call    LCD_Caracter
  452.  
  453.         goto    LCD_VisualizaBajo
  454.  
  455.  
  456.  
  457. LCD_ByteCompleto
  458.  
  459.         movwf   LCD_Auxiliar2           ; Guarda el valor de entrada.
  460.  
  461. LCD_VisualizaAlto
  462.  
  463.         swapf   LCD_Auxiliar2,W         ; Pone el nibble alto en la parte baja.
  464.  
  465.         call    LCD_Nibble              ; Lo visualiza.
  466.  
  467. LCD_VisualizaBajo
  468.  
  469.         movf    LCD_Auxiliar2,W         ; Repite el proceso con el nibble bajo.
  470.  
  471. ;       call    LCD_Nibble              ; Lo visualiza.
  472.  
  473. ;       return
  474.  
  475.  
  476.  
  477. ; Subrutina "LCD_Nibble" ----------------------------------------------------------------
  478.  
  479. ;
  480.  
  481. ; Visualiza en el lugar actual de la pantalla, el valor hexadecimal que almacena en el nibble
  482.  
  483. ; bajo del registro W. El nibble alto de W no es tenido en cuenta. Ejemplos:
  484.  
  485. ; - Si (W)=b'01010110', se visualizará "6".
  486.  
  487. ; - Si (W)=b'10101110', se visualizará "E".
  488.  
  489. ;
  490.  
  491. LCD_Nibble
  492.  
  493.         andlw   b'00001111'             ; Se queda con la parte baja.
  494.  
  495.         movwf   LCD_Auxiliar1           ; Lo guarda.
  496.  
  497.         sublw   0x09                    ; Comprueba si hay que representarlo con letra.
  498.  
  499.         btfss   STATUS,C       
  500.  
  501.         goto    LCD_EnviaByteLetra
  502.  
  503.         movf    LCD_Auxiliar1,W
  504.  
  505.         addlw   '0'                     ; El número se pasa a carácter ASCII sumándole
  506.  
  507.         goto    LCD_FinVisualizaDigito  ; el ASCII del cero y lo visualiza.
  508.  
  509. LCD_EnviaByteLetra
  510.  
  511.         movf    LCD_Auxiliar1,W
  512.  
  513.         addlw   'A'-0x0A                        ; Sí, por tanto, se le suma el ASCII de la 'A'.
  514.  
  515. LCD_FinVisualizaDigito
  516.  
  517.         goto    LCD_Caracter            ; Y visualiza el carácter. Se hace con un "goto"
  518.  
  519.                                         ; para no sobrecargar la pila.
LCD_MENS.INC
Código: ASM
  1. Librería de subrutinas para el manejo de mensajes a visualizar en un visualizador LCD.
  2.  
  3.  
  4.  
  5.         CBLOCK  0x25
  6.  
  7.         LCD_ApuntaCaracter              ; Indica la posición del carácter a visualizar
  8.  
  9.                                         ; respecto del comienzo de todos los mensajes,
  10.  
  11.                                         ; (posición de la etiqueta "Mensajes").
  12.  
  13.         LCD_ValorCaracter               ; Código ASCII del carácter a visualizar
  14.  
  15.         ENDC                           
  16.  
  17.  
  18.  
  19. ; Los mensajes tienen que estar situados dentro de las 256 primeras posiciones de la
  20.  
  21. ; memoria de programa, es decir, no pueden superar la dirección 0FFh.
  22.  
  23.  
  24.  
  25. ; Subrutina "LCD_Mensaje" ---------------------------------------------------------------
  26.  
  27. ;
  28.  
  29. ; Visualiza por pantalla el mensaje apuntado por el registro W.
  30.  
  31. ;
  32.  
  33. ; Los mensajes deben localizarse dentro de una zona encabezada por la etiqueta "Mensajes" y que
  34.  
  35. ; tenga la siguiente estructura:
  36.  
  37. ;
  38.  
  39. ; Mensajes                              ; ¡Etiqueta obligatoria!
  40.  
  41. ;       addwf   PCL,F
  42.  
  43. ; Mensaje0                              ; Posición inicial del mensaje.
  44.  
  45. ;       DT ".. ..", 0x00                        ; Mensaje terminado en 0x00.
  46.  
  47. ; Mensaje1
  48.  
  49. ;       ...    
  50.  
  51. ;       ...
  52.  
  53. ; FinMensajes
  54.  
  55. ;
  56.  
  57. ; La llamada a esta subrutina se realizará siguiendo este ejemplo:
  58.  
  59. ;
  60.  
  61. ;       movlw   Mensaje0                        ; Carga la posición del mensaje.
  62.  
  63. ;       call    LCD_Mensaje             ; Visualiza el mensaje.
  64.  
  65. ;
  66.  
  67. LCD_Mensaje
  68.  
  69.         movwf   LCD_ApuntaCaracter      ; Posición del primer carácter del mensaje.
  70.  
  71.         movlw   Mensajes                        ; Halla la posición relativa del primer carácter
  72.  
  73.         subwf   LCD_ApuntaCaracter,F    ; del mensaje respecto de etiqueta "Mensajes".
  74.  
  75.         decf    LCD_ApuntaCaracter,F    ; Compensa la posición que ocupa "addwf PCL,F".
  76.  
  77. LCD_VisualizaOtroCaracter
  78.  
  79.         movf    LCD_ApuntaCaracter,W
  80.  
  81.         call    Mensajes                        ; Obtiene el código ASCII del carácter apuntado.
  82.  
  83.         movwf   LCD_ValorCaracter               ; Guarda el valor de carácter.
  84.  
  85.         movf    LCD_ValorCaracter,F     ; Lo único que hace es posicionar flag Z. En caso
  86.  
  87.         btfsc   STATUS,Z                ; que sea "0x00", que es código indicador final       
  88.  
  89.         goto    LCD_FinMensaje          ; de mensaje, sale fuera.
  90.  
  91. LCD_NoUltimoCaracter
  92.  
  93.         call    LCD_Caracter            ; Visualiza el carácter ASCII leído.
  94.  
  95.         incf    LCD_ApuntaCaracter,F    ; Apunta a la posición del siguiente carácter
  96.  
  97. ;-----------------------------------------------------------------
  98.  
  99.         btfss   STATUS,C        ;Si hay acarreo al incrementar LCD_ApuntaCaracter es por
  100.  
  101.         incf    PCLATH          ;haber cambiado de página por lo que hay que sumar 1 al PCLATH
  102.  
  103. ;----------------------------------------------------------------
  104.  
  105.         goto    LCD_VisualizaOtroCaracter       ; dentro del mensaje.
  106.  
  107. LCD_FinMensaje
  108.  
  109.         return                          ; Vuelve al programa principal.
  110.  
  111.  
  112.  
  113. ; Subrutina "LCD_MensajeMovimiento" -----------------------------------------------------
  114.  
  115. ;
  116.  
  117. ; Visualiza un mensaje de mayor longitud que los 16 caracteres que pueden representarse
  118.  
  119. ; en una línea, por tanto se desplaza a través de la pantalla.
  120.  
  121. ;
  122.  
  123. ; En el mensaje debe dejarse 16 espacios en blanco, al principio y al final para
  124.  
  125. ; conseguir que el desplazamiento del mensaje sea lo más legible posible.
  126.  
  127. ;
  128.  
  129.         CBLOCK
  130.  
  131.         LCD_CursorPosicion              ; Contabiliza la posición del cursor dentro de la
  132.  
  133.         ENDC                            ; pantalla LCD
  134.  
  135.  
  136.  
  137. LCD_MensajeMovimiento
  138.  
  139.         movwf   LCD_ApuntaCaracter      ; Posición del primer carácter del mensaje.
  140.  
  141.         movlw   Mensajes                        ; Halla la posición relativa del primer carácter
  142.  
  143.         subwf   LCD_ApuntaCaracter,F    ; del mensaje respecto de la etiqueta "Mensajes".
  144.  
  145.         decf    LCD_ApuntaCaracter,F    ; Compensa la posición que ocupa "addwf PCL,F".
  146.  
  147. LCD_PrimeraPosicion
  148.  
  149.         clrf    LCD_CursorPosicion      ; El cursor en la posición 0 de la línea.
  150.  
  151.         call    LCD_Borra               ; Se sitúa en la primera posición de la línea 1 y
  152.  
  153. LCD_VisualizaCaracter                   ; borra la pantalla.
  154.  
  155.         movlw   LCD_CaracteresPorLinea  ; ¿Ha llegado a final de línea?
  156.  
  157.         subwf   LCD_CursorPosicion,W
  158.  
  159.         btfss   STATUS,Z
  160.  
  161.         goto    LCD_NoEsFinalLinea
  162.  
  163. LCD_EsFinalLinea
  164.  
  165.         call    Retardo_200ms           ; Lo mantiene visualizado durante este tiempo.
  166.  
  167.         call    Retardo_200ms
  168.  
  169.         movlw   LCD_CaracteresPorLinea-1; Apunta a la posición del segundo carácter visualizado
  170.  
  171.         subwf   LCD_ApuntaCaracter,F    ; en pantalla, que será el primero en la siguiente
  172.  
  173.         goto    LCD_PrimeraPosicion      ; visualización de línea, para producir el efecto
  174.  
  175. LCD_NoEsFinalLinea                      ; de desplazamiento hacia la izquierda.
  176.  
  177.         movf    LCD_ApuntaCaracter,W
  178.  
  179.         call    Mensajes                        ; Obtiene el ASCII del carácter apuntado.
  180.  
  181.         movwf   LCD_ValorCaracter               ; Guarda el valor de carácter.
  182.  
  183.         movf    LCD_ValorCaracter,F     ; Lo único que hace es posicionar flag Z. En caso
  184.  
  185.         btfsc   STATUS,Z                ; que sea "0x00", que es código indicador final       
  186.  
  187.         goto    LCD_FinMovimiento       ; de mensaje, sale fuera.
  188.  
  189. LCD_NoUltimoCaracter2
  190.  
  191.         call    LCD_Caracter            ; Visualiza el carácter ASCII leído.
  192.  
  193.         incf    LCD_CursorPosicion,F    ; Contabiliza el incremento de posición del
  194.  
  195.                                         ; cursor en la pantalla.
  196.  
  197.         incf    LCD_ApuntaCaracter,F    ; Apunta a la siguiente posición por visualizar.
  198.  
  199.         goto    LCD_VisualizaCaracter   ; Vuelve a visualizar el siguiente carácter
  200.  
  201. LCD_FinMovimiento                       ; de la línea.
  202.  
  203.         return                          ; Vuelve al programa principal.
Bin_BCD.INC
Código: ASM
  1. ; REGISTROS USADOS PARA LA CONVERSION
  2.         ;Num_Binario
  3.         ;Centena
  4.         ;Decena
  5.         ;Unidad
  6.  
  7. ;Rutina de Conversion............
  8. Binario_BCD
  9.         movf    Num_Binario,W   ;Num_Binario ---> W
  10.         movwf   Unidad          ;W ---> Unidad
  11.         clrf    Decena          ;Borramos Decena
  12.         clrf    Centena         ;Borramos Centena
  13. BCD_0
  14.         movlw   d'10'           ;Movemos .10 ---> W
  15.         subwf   Unidad,W        ;Restamos Unidad - W y guardamos en W
  16.         btfss   STATUS,C        ;Preguntamos por el estado del bit Carry
  17.         goto    BCD_Fin         ;Si es 0 salimos de la Rutina
  18. BCD_1
  19.         movwf   Unidad          ;Guardamos el valor de la resta en Unidad
  20.         incf    Decena,f        ;Incrementamos Decena y guardamos en Decena
  21.         movlw   d'10'           ;Movemos .10 ---> W
  22.         subwf   Decena,W        ;Restamos Decena - W y guardamos en W
  23.         btfss   STATUS,C        ;Preguntamos por el estado del bit Carry
  24.         goto    BCD_0
  25. BCD_2
  26.     clrf        Decena          ;Borramos Decena
  27.         incf    Centena,f       ;Incrementamos Centena y guardamos en Centena
  28.         goto    BCD_0
  29. BCD_Fin
  30.        
  31.         return

Muchas Gracias.
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Guardar valor modulo ADC
« Respuesta #17 en: 10 de Mayo de 2015, 11:17:27 »
Mirando las funciones deberias poner lo que quieras escribir en W y luego usar un CALL LCD_Caracter

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Guardar valor modulo ADC
« Respuesta #18 en: 10 de Mayo de 2015, 11:30:22 »
Hola KILLERJC eso mismo es lo que creo que estoy haciendo, pero no me da el valor que debería dar, voy a probar a hacer las divisiones paso a paso para convertir a BCD.
Primero voy a dividir por 100 el numero binario para conseguir las centenas, luego por 10 para las decenas y luego unidades, a ver si de esta manera consigo el resultado para cargar en W y después llamar a LCD_Caracter.

Gracias.
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Guardar valor modulo ADC
« Respuesta #19 en: 10 de Mayo de 2015, 11:59:05 »
El codigo BCD esta bien, creo que el problema esta en lo que se envia al LCD.

Proba una cosa... antes de enviar lo que esta en W, sumale 48 (0x30), que es el valor del caracter 0 en el LCD, luego si lo dejas en W al resultado de eso y llamas a la funcion.

Es decir


Código: ASM
  1. MOVLW Centena
  2. ADDLW 0x30
  3. CALL LCD_Caracter
« Última modificación: 10 de Mayo de 2015, 12:02:03 por KILLERJC »

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Guardar valor modulo ADC
« Respuesta #20 en: 10 de Mayo de 2015, 19:12:41 »
Hola KILLERJC después de probar lo que me comentas el resultado no es el esperado:
Código: ASM
  1. ;Conversion a decimal........
  2.         call        LCD_Linea2      ;Visualizamos en la segunda linea del LCD
  3.         pageselw    Mensaje1
  4.         movlw       Mensaje1
  5.         call        LCD_Mensaje
  6.         movlw       0xAF            ;Cargamos W con el valor 175 en decimal
  7.         movwf       Num_Binario
  8.         call        Binario_BCD     ;Llamamos a la rutina de conversion
  9.         movlw       Centena
  10.         addlw       0x30
  11.         call        LCD_Caracter
  12.         sleep                       ;Modo reposo
sumando 0x30 me sale el carácter 'a' cuando el carácter 'a' debería de ser 0x61 y sumando 0x31 me sale la 'b' voy a intentar averiguar el porque.

Gracias. 
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Guardar valor modulo ADC
« Respuesta #21 en: 10 de Mayo de 2015, 22:42:39 »
Tenes un error en tu codigo:

Cambia:

Código: ASM
  1. movlw       Centena

Por

Código: ASM
  1. movf       Centena,W

Por que si haces eso como hiciste solo cargarias el numero de la direccion de memoria de Centena
« Última modificación: 10 de Mayo de 2015, 22:46:23 por KILLERJC »

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Guardar valor modulo ADC
« Respuesta #22 en: 11 de Mayo de 2015, 04:29:33 »
De nuevo gracias por la ayuda, ahora si funciona con cualquier numero, lo que no entiendo el porque de sumarle el valor del carácter 0.
Código: ASM
  1. ;Conversion a decimal........
  2.         call        LCD_Linea2      ;Visualizamos en la segunda linea del LCD
  3.         pageselw    Mensaje1
  4.         movlw       Mensaje1
  5.         call        LCD_Mensaje
  6.         movlw       0x64            ;Cargamos W con el valor 100 en decimal
  7.         movwf       Num_Binario
  8.         call        Binario_BCD     ;Llamamos a la rutina de conversion
  9.         movf        Centena,W
  10.         addlw       0x30
  11.         call        LCD_Caracter
  12.         movf        Decena,W
  13.         addlw       0x30
  14.         call        LCD_Caracter
  15.         movf        Unidad,W
  16.         addlw       0x30
  17.         call        LCD_Caracter
  18.         sleep                       ;Modo reposo

Gracias KILLERJC.
« Última modificación: 11 de Mayo de 2015, 04:36:45 por Miquel_S »
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Guardar valor modulo ADC
« Respuesta #23 en: 11 de Mayo de 2015, 05:11:52 »
Por que el codigo que tenes de binario a BCD, te deja un numero de 0x00 a 0x09 , sea para Centenas,Decenas y Unidades.
El caracter del 0 en el LCD esta representado por su ASCII, 0x30. Podes ver la tabla de caracteres en el datasheet del driver del LCD o


Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Guardar valor modulo ADC
« Respuesta #24 en: 11 de Mayo de 2015, 18:49:43 »
Hola, lo primero quiero dar las gracias a KILLERJC por toda la ayuda ofrecida desinteresadamente, os dejo el programa completo de la conversión BCD  para 8 bits por si alguien puede interesarle:
main:
Código: ASM
  1. ;------------------------------------------------------------------------------
  2. ; PROCESSOR DECLARATION
  3. ;------------------------------------------------------------------------------
  4.  
  5.      LIST      p=16F88              ; list directive to define processor
  6.      #INCLUDE <p16f88.inc>          ; processor specific variable definitions
  7.  
  8. ;------------------------------------------------------------------------------
  9. ;
  10. ; CONFIGURATION WORD SETUP
  11. ;
  12. ; The 'CONFIG' directive is used to embed the configuration word within the
  13. ; .asm file. The lables following the directive are located in the respective
  14. ; .inc file.  See the data sheet for additional information on configuration
  15. ; word settings.
  16. ;
  17. ;------------------------------------------------------------------------------
  18.  
  19.      __CONFIG    _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO
  20.      __CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF
  21.  
  22.      ERRORLEVEL -207
  23.      ERRORLEVEL -302
  24.      ERRORLEVEL -305
  25.  
  26. ;------------------------------------------------------------------------------
  27. ;
  28. ; VARIABLE DEFINITIONS
  29. ;
  30. ; Available Data Memory divided into Bank 0 through Bank 3.  Each Bank contains
  31. ; Special Function Registers and General Purpose Registers at the locations
  32. ; below:
  33. ;
  34. ;           SFR           GPR               SHARED GPR's
  35. ; Bank 0    0x00-0x1F     0x20-0x6F         0x70-0x7F
  36. ; Bank 1    0x80-0x9F     0xA0-0xEF         0xF0-0xFF
  37. ; Bank 2    0x100-0x10F   0x110-0x16F       0x170-0x17F
  38. ; Bank 3    0x180-0x18F   0x190-0x1EF       0x1F0-0x1FF
  39. ;
  40. ;------------------------------------------------------------------------------
  41.  
  42.     CBLOCK 0x30
  43.         Num_Binario
  44.         Centena
  45.         Decena
  46.         Unidad
  47.     ENDC
  48.  
  49.     Valor   equ     0xFF    ;Constante para prueba de conversion
  50.  
  51. ;------------------------------------------------------------------------------
  52. ; RESET VECTOR
  53. ;------------------------------------------------------------------------------
  54.  
  55. RESET     ORG     0x0000            ; processor reset vector
  56.           PAGESEL START
  57.           GOTO    START             ; go to beginning of program
  58.  
  59. ;Tabla para Mensajes.........................
  60. Mensajes                            ;Etiqueta obligatoria
  61.         addwf       PCL,F
  62. Mensaje0                            ;Posicion inicial del mensaje
  63.         DT " CONVERSION BCD ",0x00  ;Mensaje terminado en 0x00
  64. Mensaje1                        
  65.         DT "  PARA 8-bits ",0x00    
  66. Mensaje2
  67.         DT "HEX: 0x",0x00
  68. Mensaje3
  69.         DT "DEC: .",0x00
  70.  
  71. ;------------------------------------------------------------------------------
  72. ; MAIN PROGRAM
  73. ;------------------------------------------------------------------------------
  74.  
  75. START
  76. ;Configuramos el oscilador interno para 4MHz........
  77.         banksel     OSCCON          ;Banco 1
  78.         bsf         OSCCON,IRCF2
  79.         bsf         OSCCON,IRCF1
  80.         bcf         OSCCON,IRCF0
  81.  
  82. ;Configuramos los puertos del PIC........
  83.         banksel     PORTA           ;Banco 0
  84.         clrf        PORTA
  85.         clrf        PORTB
  86.         banksel     ANSEL           ;Banco 1
  87.         movlw       b'00000000'
  88.         movwf       ANSEL
  89.         clrf        TRISA
  90.         clrf        TRISB
  91.  
  92. ;Configuramos el LCD........
  93.         call        LCD_Inicializa  ;Inicializamos el LCD
  94.  
  95. ;Mensaje de Bienvenida........
  96.         pageselw    Mensaje0
  97.         movlw       Mensaje0
  98.         call        LCD_Mensaje    
  99.         call        LCD_Linea2      
  100.         pageselw    Mensaje1
  101.         movlw       Mensaje1
  102.         call        LCD_Mensaje
  103.         call        Retardo_2s
  104.  
  105. ;Visualizamos el numero en Hexadecimal
  106.         call        LCD_Borra
  107.         pageselw    Mensaje2
  108.         movlw       Mensaje2
  109.         call        LCD_Mensaje
  110.         movlw       Valor
  111.         call        LCD_ByteCompleto
  112.  
  113. ;Conversion a decimal........
  114.         call        LCD_Linea2
  115.         pageselw    Mensaje3
  116.         movlw       Mensaje3
  117.         call        LCD_Mensaje
  118.         movlw       Valor            ;Cargamos W con el valor 121 en decimal
  119.         movwf       Num_Binario
  120.         call        Binario_BCD      ;Llamamos a la rutina de conversion
  121.         movf        Centena,W
  122.         addlw       0x30
  123.         call        LCD_Caracter
  124.         movf        Decena,W
  125.         addlw       0x30
  126.         call        LCD_Caracter
  127.         movf        Unidad,W
  128.         addlw       0x30
  129.         call        LCD_Caracter
  130.         sleep                       ;Modo reposo
  131.  
  132. ;Rutinas para control del LCD........
  133. #include retardos.INC
  134. #include lcd_4bit.INC
  135. #include LCD_MENS.INC
  136. #include Bin_BCD.INC
  137.  
  138.         END
Ahora tocara estudiar la conversión BCD a 16 bits para luego conectar el potenciómetro y el servo.

Saludos!
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Guardar valor modulo ADC
« Respuesta #25 en: 12 de Mayo de 2015, 09:16:31 »
El BCD a 16 bits lo podes extender utilizando el mismo codigo, nomas que ahora cada operacion de la primera resta ( ya que las otras son de los registros BCD y ocupan solo 4bits de los 8 ) va a tener que ser de 16bits. Vas a tener que agregar 2 variables mas y seguir agregando bloques para tus miles y decenas de miles.

Esa es la mas simple que te queda por hacer. Si seguis con la logica de restar 10, lo que si 16bits = 65536, serian 6553 restas de 10 y suma 1 + 655 resta de 10 y sumo 1 + 65 resta de 10 y suma 1 + 6 resta de 10 y suma 1 = 7279 *2 = 14558 instrucciones sin contar que la primera resta es de 16bits, testeo de condiciones y saltos. No creo estar tan equivocado :)


Luego tenes otras formas:

Esta muy interesante, constaria de 16 dezplazamientos ( en realidad mas por que estamos limitados a 8bits ) y luego suma de a 3 y restas.
http://en.wikipedia.org/wiki/Double_dabble

Como dije esta me parecio la mas interesante, un bucle de 16 que dentro posea shifts, luego 4 restas para saber si sumar o no, y sumar si es necesario

Esta ya tiene otro enfoque completamente distinto y BASTANTE matematico, bastante loco y mucho mas corto en terminos de memoria a mi parecer.
http://www.piclist.com/techref/microchip/math/radix/b2bu-16b5d.htm

Y luego este que no analize:
http://www.piclist.com/techref/microchip/math/radix/b2bu-16b5d-jm.htm

Eso si necesitas 16 bits, si necesitas 12 o 10, entonces es mas corto,el de 12 bits utiliza el mismo enfoque matematico del que hable antes y el de 10 realiza una division por 10:
http://www.piclist.com/techref/microchip/math/radix/b2bu-10b4d-eag.htm

Si se te ocurre preguntar como es posible dividir por 10, aqui tenes la solucion:
Titulo: Approximate Multiplication by 1/10
http://homepage.cs.uiowa.edu/~jones/bcd/divide.html
« Última modificación: 12 de Mayo de 2015, 09:35:35 por KILLERJC »