Autor Tema: Como cambiar lectura de LCD a 7 segmentos  (Leído 4298 veces)

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

Desconectado Vangeluz

  • PIC12
  • **
  • Mensajes: 74
    • Vangeluzweb
Como cambiar lectura de LCD a 7 segmentos
« en: 01 de Noviembre de 2017, 14:56:44 »
Hola a todos de nuevo

Basandome en un viejo, pero efectivo circuito de la pagina Pablin.com, he apuntado al famoso ( para muchos ) Termostado LCD de Pablin

Termometro Pablin

No hay mucho que decir ... Funciona perfecto, me ha funcionado con un 16F876A.

Este es el codigo Original que funciona perfecto con LCD.

Codigo Original con LCD

Y este es mi triste intento de pasarlo a 7 segmentos

Intento fallido a 3 digitos 7 Segmentos

He omitido EEPROM, todo lo que es relacionado a LCD, tambien pulsadores, buffer y salida relays.
Solo he dejado la visualización de lectura del LM35 como un simple termómetro ( al menos eso quise intentar )  :o

He intentado varias cosas y queda encendido un digito solo el segmento punto, antes tenía otra rutina de tiempo entre displays que tambien me mostraba un segmento de digito central ...

Mi pregunta es ... está bien formado el codigo para sacar a 3 dig 7 segmentos o estoy errado feo ?? :shock:

Gracias por alguna opinión que me pueda ir orientando !!!
Vangeluz

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Como cambiar lectura de LCD a 7 segmentos
« Respuesta #1 en: 01 de Noviembre de 2017, 21:11:30 »
Yo haria lo siguiente:

- Quitar todo lo del LCD, pero dejar la parte donde se pasa de decimal(binario) a BCD.
- Usar un timer con una interrupcion para multiplexar los datos.


Las diferencias que tiene el 7 segmento con el LCD, es que el LCD es persistente, es decir pusiste el dato y listo, se termino. Mientras que el 7 segmento tenes que estar multiplexandolo. Por lo tanto el codigo que usaron con todos esos delays no lo tiene en cuenta a eso. Por eso es usar un Timer.

Otro tema es que alli tiene 2 salidas, a mostrar en el LCD, segun el codigo:

Código: ASM
  1. call    VERINF          ;Coloca en el LCD la temp. inferior (de activación)
  2.         call    VERSUP          ;Coloca en el LCD la temp. superior (de desactivación)

Entonces cual vas a mostrar?, los botones tambien afectan a uno u otro.

Desconectado Vangeluz

  • PIC12
  • **
  • Mensajes: 74
    • Vangeluzweb
Re:Como cambiar lectura de LCD a 7 segmentos
« Respuesta #2 en: 02 de Noviembre de 2017, 06:13:41 »

Gracias Killer

Mira en realidad buscaba hacer lo mismo, con 2 pulsadores, y 2 escrituras / lecturas ( Minima y Maxina ) en la EEPROM ...

Así como has citado sería la idea incluirlo:
Código: ASM
  1. call    VERINF          ;Coloca en el LCD la temp. inferior (de activación)
  2.         call    VERSUP          ;Coloca en el LCD la temp. superior (de desactivación)

Eso agrega algo en display como:
 TEMPERATURA 25º
   22º <--  -- > 26º


Pero primero quería como un simple termómetro intentar solo reflejar lo mismo en los 7 segmentos como una base ...

Con contadores no he tenido problemas, ya que uno mismo crea los numeros ... pero con esto de convertir una lectura me tiene un poco liado
Por otro lado encontré otro googleando, aunque ese si es solo un termómetro es con 7 segmentos pero .... con un 16F628 y un sensor 18b20 ...

Termo 16F628 y DS18B20

Este usa interrupcion y TMR ( como comentas ) ... ... No me familiarizo con esas interrupciones ... La verdad, me han decepcionado los TMR ...
En principio pensaba que eran mágicos y desatendidos como un micro a parte  :o
Luego me di cuenta que al hacer otras cosas se retrazaba el TMR y dije ( Osea que no es mágico, también lo toma en cuenta el programa )  :D :D
 
Bueno volviendo al hallazgo googleando ...
Lo pude hacer funcionar porque tenía todo, aunque en lecturas bajas tomando una heladera se quedaba en unos 15ºC ... y probé con 2 18B20 ...

Pero bueno al margen de eso, si lo quisiera usar igual .. no pude aun ingresarle los pulsadores ... 
En un contador me había resultado facil, algo así ...

Pulsador 1:_ Ingresaba a una rutina de Programación, encendiendo solo digito UNIDAD a cambiar deseado y guardando en EEPROM ...
Pulsador 2:_ pasaba a DECENAS, ( lo mismo ) y así sucesivamente guardaba ....
Luego comparaba todo el tiempo Unidades, Decenas y Centenas Actuales con las guardadas ... Y todo perfecto !!!

Volviendo a ésto, en el primero no saco nada en displays ... y en el segundo mas allá de lectura errónea, no logro agregarle pulsadores ...
Estoy bastante liado, creo que con cualquiera podría llegar a fin ... pero está todo a medio camino !!! :?

 
« Última modificación: 02 de Noviembre de 2017, 06:19:10 por Vangeluz »
Vangeluz

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Como cambiar lectura de LCD a 7 segmentos
« Respuesta #3 en: 02 de Noviembre de 2017, 08:45:30 »
Nada es magico, y no son desatendidas del micro, pero como el micro se maneja muy rapido, atender estas interrupciones, salir y seguir ejecutando el programa principal sin que se note. Donde seguramente en el programa principal tengas demoras y otras cosas.

Desde el punto de vista del programador el programa principal y la interrupcion son 2 programas apartes, pero que comparten los mismos registros, asi que hay que tener un cierta precaucion para los registros STATUS y W (que esta en el datasheet).

Citar
Luego me di cuenta que al hacer otras cosas se retrazaba el TMR y dije ( Osea que no es mágico, también lo toma en cuenta el programa )

El Timer no retrasa, el problema que puede ocurrir es que hasta que resetees el TMR (pongas el valor de nuevo) hay unos ciclos perdidos. Y eso presenta un error que se va acumulando. Pero que si usas el modulo CCP se reduce.

Citar
Pero bueno al margen de eso, si lo quisiera usar igual .. no pude aun ingresarle los pulsadores ... 

Es porque borraste todo xD jeje.

Luego veo un poco mas el programa de pablin, y le quito lo del LCD.

Citar
pero con esto de convertir una lectura me tiene un poco liado

Por ahi en el codigo de pablin debe estar la magia que trasforma la lectura del ADC en BCD

Desconectado Vangeluz

  • PIC12
  • **
  • Mensajes: 74
    • Vangeluzweb
Re:Como cambiar lectura de LCD a 7 segmentos
« Respuesta #4 en: 02 de Noviembre de 2017, 23:05:57 »
Bueno, gracias Killer ....
Si te haces unos minutitos para ojear el termo de pablin y me das un poco de luz bienvenido sea !!!

Aclarando una mal expresión mia ... Cuando te decía de que no pude agregar los pulsadores ( era con el termo segundo que encontré ) no con el de pablin !! ... Ya que el segundo que encontré funciona correcto, pero solo muestra temperatura, sin pulsadores ..  no guarda ni configura nada.

Al de Pablin siii lo dejé pelado con lo minimo y suficiente para que por lo menos solo muestre lo que lee en displays !! ... aunque exageré un poquin  :P :P

Vangeluz

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Como cambiar lectura de LCD a 7 segmentos
« Respuesta #5 en: 04 de Noviembre de 2017, 11:26:18 »
Bueno explico un poco el tema, corregi un poco el programa, quite todas las definiciones extras que usan en pablin, ya que eso se resuelve agregando los .inc

Vos me preguntabas como es que transformaban el voltaje a temperatura, Es simple.. en realidad bastante simple xD jeje.

El LM35 como esta conectado posee una salida de 0mv + 10mV/ºC (para un rango de 2ºC a 150ºC). Es decir si poseo 5 grados quiere decir que tengo 50mV. Y el maximo que puede alcanzar es de 1.5V.

El PIC esta alimentado con 5V, y cada cuenta del ADC es de 5V/1024 = 4.88mV, pero luego en la conversion lo que hace rotarlo 1 ves a la derecha, eliminando el bit menos significante, o que es lo mismo que obtener solo 9 bits de los 10, eso te deja con 5V/512 = 9.76mV por cada cuenta que tome el ADC.

Si uno no tiene en cuenta ese error que va a ser maximo para los 150ºC, el valor resultante de la conversion del ADC mas una rotacion a la izquierda es de los grados del LM.

Código: ASM
  1. LIST  p=16F876A
  2.   INCLUDE "p16f876a.inc"
  3.   __config _CP_OFF&_CPD_OFF&_LVP_OFF&_WDT_OFF&_XT_OSC
  4.  
  5.   CBLOCK 0XF0
  6.   UNI
  7.   DEC
  8.   CEN
  9.   DISPLAY_ACTIVO
  10.   TIEMPO1
  11.   TIEMPO2
  12.   BUFFER
  13.   CONTADOR1
  14.   CONTADOR2
  15.   ENDC
  16.  
  17.   ORG 0x00
  18.   GOTO INICIO
  19.   ORG 0x04
  20.   RETURN
  21.  
  22.  
  23. INICIO:
  24.  
  25.   BANKSEL TRISA
  26.   movlw b'00011111' ;Configura puerto A
  27.   movwf TRISA
  28.   clrf  TRISB    ;Puerto B completo como salidas (bus del LCD)
  29.   clrf  TRISC    ;Puerto C completo como salidas
  30.   movlw b'10001110' ;Configura los pines del Puerto A
  31.   movwf ADCON1   ;AN0 como única entrada análoga
  32.  
  33.   BANKSEL PORTA
  34.  
  35.   movlw b'01000001' ;Enciende y configura el convertidor A/D - Selecciona AN0 como entrada
  36.   movwf ADCON0
  37.  
  38.  
  39.   ; Configurar el timer aca
  40.  
  41.   clrf  PORTA    ;Apaga todo
  42.   clrf  PORTB
  43.   clrf  PORTC
  44.  
  45.   CLRF DISPLAY_ACTIVO  ; Ponemos a 0 el indicador de display
  46.  
  47. CICLO:
  48.  
  49.   CALL CONVERSION_ADC
  50.   CALL ADC_TO_BCD
  51.   CALL MOSTRAR
  52.  
  53.   goto  CICLO   ;Vuelve a medir y mostrar
  54.  
  55. ; ------------------------------------------------------------------------
  56. ;  Inicia la conversion del ADC y espera a que termine
  57. ; ------------------------------------------------------------------------
  58.  
  59. CONVERSION_ADC:
  60.   bsf  ADCON0, GO   ;Inicia la conversión A/D
  61.   btfsc ADCON0, GO  ;Espera que termine de convertir
  62.   goto  $ -1
  63.   RETURN
  64.  
  65. ; ------------------------------------------------------------------------------------------
  66. ;  Toma los datos del ADC y los usa.
  67. ;  Toma los bits del 1 al 8 del resultado del ADC. De esa forma con un poco de error tiene
  68. ;  un resultado cercano respecto a la temperatura.
  69. ;  Entrada: ADRESH, ADRESL
  70. ;  Salida: UNI, DEC, CEN
  71. ; ------------------------------------------------------------------------------------------
  72.  
  73. ADC_TO_BCD:
  74.  
  75.   RRF   ADRESH, W     ; Giro para que quede el bit 8 en el carry
  76.   BANKSEL ADRESL      ; Voy al banco 1
  77.   RRF  ADRESL, W      ; Giro nuevamente esta ves eliminando el bit de menos peso de ADRESL y poniendo el valor del carry en el bit 7, todo eso en W
  78.   BANKSEL PORTA       ; Vuelvo al banco 0, para evitar posibles problemas
  79.  
  80.   call  DECIMAL       ; Obtiene resultado en BCD: UNI, DEC y CEN
  81.  
  82.   RETURN
  83.  
  84. ; ------------------------------------------------------------------------------------------
  85. ;  Muestra los datos en el display
  86. ;  Usamos un timer con un tiempo de 5ms
  87. ;  Entrada: UNI, DEC, CEN
  88. ; ------------------------------------------------------------------------------------------
  89.  
  90. MOSTRAR:
  91.  
  92.   BANKSEL PORTA         ; Vuelvo al banco 0, para evitar posibles problemas
  93.  
  94.   BTFSS INTCON, T0IF    ; Paso el tiempo del Timer?
  95.   RETURN                ; No paso entonces salgo de aca
  96.  
  97.   MOVLW   0x00          ; Recargo el TMR0
  98.   MOVWF   TMR0
  99.   BCF     INTCON, T0IF
  100.   MOVF    DISPLAY_ACTIVO
  101.   ADDWF   PCL, F
  102.   GOTO    DISPLAY_UNI
  103.   GOTO    DISPLAY_DEC
  104.   GOTO    DISPLAY_CEN
  105.   ; Seguridad aca
  106.   CLRF    DISPLAY_ACTIVO
  107.   RETURN
  108.  
  109. DISPLAY_UNI
  110.   CLRF  PORTC   ; Apago cualquier valor
  111.   MOVF  UNI, W  ;Carga W con el valor de unidad       UNIDAD
  112.   call  tabla   ;Vuelve W con los bits para formar el digito
  113.   movwf PORTB   ;manda el digito al puerto B
  114.   bsf   PORTC,2   ;enciende el bit 2 del puerto A
  115.   RETURN
  116.  
  117. DISPLAY_DEC
  118.   CLRF  PORTC   ; Apago cualquier valor
  119.   MOVF  UNI, W  ;Carga W con el valor de unidad       UNIDAD
  120.   call  tabla   ;Vuelve W con los bits para formar el digito
  121.   movwf PORTB   ;manda el digito al puerto B
  122.   bsf   PORTC,1   ;enciende el bit 2 del puerto A
  123.   RETURN
  124.  
  125. DISPLAY_CEN
  126.   CLRF  PORTC   ; Apago cualquier valor
  127.   MOVF  UNI, W  ;Carga W con el valor de unidad       UNIDAD
  128.   call  tabla   ;Vuelve W con los bits para formar el digito
  129.   movwf PORTB   ;manda el digito al puerto B
  130.   bsf   PORTC,0   ;enciende el bit 2 del puerto A
  131.   RETURN    
  132.  
  133. ; ------------------------------------------------------------------------------------------
  134. ;  Convierte el valor binario en BCD
  135. ;  Entrada: W
  136. ;  Salida: UNI, DEC, CEN
  137. ; ------------------------------------------------------------------------------------------
  138.  
  139. DECIMAL
  140.   movwf uni   ;Convierte el dato presente en W en UNI, DEC y CEN
  141.   clrf  dec
  142.   clrf  cen
  143.   movlw d'100'    ;Determina la cant. de centenas
  144. CENTENA
  145.   subwf uni, F
  146.   btfss STATUS, C
  147.   goto  CIEN
  148.   incf  cen, F
  149.   goto  CENTENA
  150. CIEN  
  151.   addwf uni, F
  152.   movlw d'10'   ;Determina la cant. de decenas
  153. DECENA  
  154.   subwf uni, F
  155.   btfss STATUS, C
  156.   goto  DIEZ
  157.   incf  dec, F
  158.   goto  DECENA
  159. DIEZ  
  160.   addwf uni, 1    ;Uni queda con la cant. de unidades (sin decenas ni centenas)
  161.   return
  162.  
  163. ;===========================================
  164. ;   TABLA
  165. ;===========================================  
  166. tabla       ; retlw b'gfedcba'  para display catodo comun
  167.   addwf PCL,1   ; Se incrementa el contador del programa.-
  168.   DT 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F
  169.  
  170.   end

- Faltaria configurar el TMR0 para los 5ms
- Faltaria cambiarle el valor del cual se debe cargar el TMR0

Cambios:

- Se usaron las definiciones del .inc y no de lo definido.
- Se cambio el loop principal a algo mas entendible.
- Se creo la funcion de mostrar en el display, se accede solo cuando paso el tiempo del timer, no importa que sea tan preciso.
- Rotar el resultado del ADC fue realizado de otra forma.
- Se movieron todos los registros usados a la parte alta que es 0xF0 a 0xFF la cual puede ser accedido desde cualquier banco.

De aca en mas queda en vos :P..
Si queres mejorarlo tenes que tener en cuenta que podes reducir un poco mas el error. A partir de los 42/43ºC aproximadamente, la lectura va a tener un error de 1ºC. Eso sin contar algun ruido posible que exista.


Desconectado Vangeluz

  • PIC12
  • **
  • Mensajes: 74
    • Vangeluzweb
Re:Como cambiar lectura de LCD a 7 segmentos
« Respuesta #6 en: 04 de Noviembre de 2017, 23:40:26 »

Wowww !!! muchas gracias por tomarte tu tiempo !!!

Veo que has simplificado todo el programa !!!

Bien !!! si no entendí mal ... solo debo configurar el Timer deseado en el punto 39 y cargarlo en el 97 e ir probando  ...

Lo que no entendí mucho en el:
     ORG   0x04
     RETURN    ... Generalmente suelen poner la configuración TMR acá o algo como GOTO   Interrupcion ( enviado a una etiqueta ) , ... no se si ese RETURN simplemente retorna luego del desborde o algo asi ... Nunca lo he visto expresado asi !!!

Pero bueno me despreocupo de eso ... voy a intentar ir probando a ver que pasa !!!

Desde ya muchas Gracias !!! 
 





Vangeluz

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Como cambiar lectura de LCD a 7 segmentos
« Respuesta #7 en: 05 de Noviembre de 2017, 00:02:10 »
El vector de interrupcion es 0x04, es decir si por algun motivo activas una interrupcion sin querer, este va a saltar a la posicion 0x04, para evitar cualquier problema. uno pone un RETURN, que a diferencia del RETFIE este no activa la interrupciones.

Resumen: Como aca NO usamos interrupciones, dejamos el codigo por las dudas si hay algun error y activamos alguno para que vuelva sin provocar ningun descontrol.


 

anything