TODOPIC

Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: cmontoya en 02 de Marzo de 2014, 01:57:59

Título: Reloj digital con 16f84
Publicado por: cmontoya en 02 de Marzo de 2014, 01:57:59
Hola amigos
Navegando por internet encontré un buen proyecto con el pic 16f84, y pues bueno lo arme en la protoboar pero al momento de ver mejor la información del proyecto me di de cuentas que necesita 2 display dobles de cátodo común y pues yo tengo todos de ánodo común, entonces trate de modificar el código (las letras) pero no me funciona.
Aclaro que no se casi nada de assembler  se mas de C++.

Codigo
http://perso.wanadoo.es/pictob/prg/reloj12h/reloj12h.asm (http://perso.wanadoo.es/pictob/prg/reloj12h/reloj12h.asm)

http://www.instructables.com/id/Big-7-segment-Digital-Clock/ (http://www.instructables.com/id/Big-7-segment-Digital-Clock/)
Título: Re: Reloj digital con 16f84
Publicado por: tapi8 en 02 de Marzo de 2014, 17:37:19
Citar
2 display dobles de cátodo común y pues yo tengo todos de ánodo común, entonces trate de modificar el código (las letras) pero no me funciona.

Prueba a hacer un "comf" antes de enviar a los displays, te deberia funcionar. Tambien si en la tabla cambias los 0 por 1 y viceversa tambien tendria que funcionar.
Título: Re: Reloj digital con 16f84
Publicado por: cmontoya en 02 de Marzo de 2014, 19:54:49
Hola
Pues lo de cambiar la tabla de 0 al 1 ya lo hice.
CERO      equ      H'7E'   ; 01111110

Y lo cambie a
CERO      equ      B'10000001'   ; 01111110
 
Además tuve que cambiar  una línea de código

DSPOFF      equ      B'11111111'   ; Displays apagados (PORTA)

Por

DSPOFF      equ      B'00000000'   ; Displays apagados (PORTA)

Para que almeno funcionara con un display Ánodo, pero igual sigue teniendo sus fallas de visualización.
En cuanto a utilizar "comf" no sé cómo seria

En la imagen que aparece 1200 funciona con el codigo original y con display catodo.
En la otra imagen fue despues de la modificacion
Título: Re: Reloj digital con 16f84
Publicado por: tapi8 en 03 de Marzo de 2014, 08:09:34
Citar
Pues lo de cambiar la tabla de 0 al 1 ya lo hice.

Has cambiado todos? asi:

CERO      equ      H'7E'   ; 01111110 asi 10000001
UNO      equ      H'0C'   ; 00001100     11110011
DOS      equ      H'B6'   ; 10110110     01001001
TRES      equ      H'9E'   ; 10011110     01100001
CUATRO      equ      H'CC'   ; 11001100     00110011
CINCO      equ      H'DA'   ; 11011010     00100101
SEIS      equ      H'FA'   ; 11111010     00000101
SIETE      equ      H'0E'   ; 00001110     11110001
OCHO      equ      H'FE'   ; 11111110     00000001
NUEVE      equ      H'DE'   ; 11011110     00100001
SEGM_OFF   equ      H'00'   ;              11111111Todos los segmentos apagados. Separador entre horas
                     ; y minutos apagado (RB0).

La otra solucion que te decia era esta:

PROX_DIGITO
   movf   INDF,W      ; Obtener el valor de la variable "digito" actual
   call   CODIGO_7S   ; LLamar a la rutina de conversión a código 7 segmentos
   comf   W,0      ; Realiza el complemento, cambia 0 por 1 y viceversa   
                 movwf   INDF      ; Colocar en la variable "digito" el código 7 segmentos devuelto
   incf   FSR,F      ; Incremente INDF para el próximo "digito"
   decfsz   conta1,F   ; Permitir que conta1 de sólo 4 vueltas
   goto   PROX_DIGITO

Creo que aqui es el unico sitio que llama a la tabla. Pero seguramente habra que cambiar alguna cosa mas.
Título: Re: Reloj digital con 16f84
Publicado por: cmontoya en 03 de Marzo de 2014, 19:33:18
Citar
Pues lo de cambiar la tabla de 0 al 1 ya lo hice.

Has cambiado todos? asi:

CERO      equ      H'7E'   ; 01111110 asi 10000001
UNO      equ      H'0C'   ; 00001100     11110011
DOS      equ      H'B6'   ; 10110110     01001001
TRES      equ      H'9E'   ; 10011110     01100001
CUATRO      equ      H'CC'   ; 11001100     00110011
CINCO      equ      H'DA'   ; 11011010     00100101
SEIS      equ      H'FA'   ; 11111010     00000101
SIETE      equ      H'0E'   ; 00001110     11110001
OCHO      equ      H'FE'   ; 11111110     00000001
NUEVE      equ      H'DE'   ; 11011110     00100001
SEGM_OFF   equ      H'00'   ;              11111111Todos los segmentos apagados. Separador entre horas
                     ; y minutos apagado (RB0).

Eso ya lo hice pero no se entiende queda como loco
Título: Re: Reloj digital con 16f84
Publicado por: elreypic2 en 04 de Marzo de 2014, 00:18:15
Que tal cmontoya,

El circuito lo tienes montado en real o solamente lo estas simulando?

Si lo estas simulando necesitas agregar un inversor 7404 entre los pines de los anodos comunes y el microcontrolador.
Si el circuito lo tienes montado en real, entonces necesitas cambiar la conexion de los transistores 2N5401. Necesitas conectar el emisor de los 4 transistores a +5V y luego cada colector de cada transistor a su correspondiente pin de los anodos comunes.

y necesitas invertir los valores de CERO, UNO, ... hasta el NUEVE. El SEG_OFF no necesitas cambiarlo. (este cambio es para ambos casos tanto para la simulacion como en real).

Saludos.

Elreypic.
Título: Re: Reloj digital con 16f84
Publicado por: tapi8 en 04 de Marzo de 2014, 06:37:34
¿Donde esta el circuito? No lo he visto  :lol: :lol:

Si necesitas hacer los cambios que te dice elreypic2 en las conexiones de catodo comun que van a masa, por anodo comun que van al positivo. Incluso puede que necesites cambiar los transistores NPN por PNP???
Título: Re: Reloj digital con 16f84
Publicado por: elreypic2 en 04 de Marzo de 2014, 10:49:19
Que tal tapi9 y cmontoya,

El circuito es tomado de la nota de aplicacion AN590 de microchip y esta usa transistores PNP para conmutar los digitos, pero estan configurados para catodo comun. Por eso es que se tiene que cambiar su forma de conectarlos para hacerlo funcionar con displays de anodo comun.

Paso 1:
Cambiar el codigo ensamblador de la seccion ya mencionada, debe quedar asi:

CERO      equ      H'81'   ; 10000001
UNO         equ      H'F3'   ; 11110011
DOS         equ      H'49'   ; 01001001
TRES              equ      H'61'   ; 01100001
CUATRO      equ      H'33'   ; 00110011
CINCO      equ      H'25'   ; 00100101
SEIS              equ      H'05'   ; 00000101
SIETE      equ      H'F1'   ; 11110001
OCHO      equ      H'01'   ; 00000001
NUEVE      equ      H'21'   ; 00100001

2. Una vez cambiado el codigo deberas conectar los transistores como te indico en la imagen.

Saludos,

elreypic.
Título: Re: Reloj digital con 16f84
Publicado por: elreypic2 en 04 de Marzo de 2014, 11:00:18
Que tal,

Otra vez yo.

Adjunto imagenes de mi simulacion del reloj con displays de anodo comun. Quiero hacer mencion que el circuito en la simulacion no trabaja en la vida real, ya que los displays usados solo neceistan niveles logicos TTL, de ahi la razon que ven los inversores 74HC04 para poder manejar los displays. Como mencione previamente, en la vida real se tienen que usar los transistores PNP y usar el esquematico colocado en el post anterior.

Saludos,

Elreypic.
Título: Re: Reloj digital con 16f84
Publicado por: tapi8 en 04 de Marzo de 2014, 15:05:48
Como veo que conoces el circuito aprovecho a preguntarte, solo por curiosidad, ¿Haciendo esto solamente funcionaria o habria que cambiar alguna cosa mas?, como ves esa instruccion en negrita hace la misma funcion que estamos haciendo cambiando la tabla.
De esta manera lo guarda ya con el codigo que trae de la tabla invertido.

PROX_DIGITO
   movf   INDF,W      ; Obtener el valor de la variable "digito" actual
   call   CODIGO_7S   ; LLamar a la rutina de conversión a código 7 segmentos
   comf   W,0      ; Realiza el complemento, cambia 0 por 1 y viceversa   
   movwf   INDF      ; Colocar en la variable "digito" el código 7 segmentos devuelto
   incf   FSR,F      ; Incremente INDF para el próximo "digito"
   decfsz   conta1,F   ; Permitir que conta1 de sólo 4 vueltas
   goto   PROX_DIGITO

Título: Re: Reloj digital con 16f84
Publicado por: elreypic2 en 04 de Marzo de 2014, 19:17:32
Que tal tapi8,

Si esa es la unica seccion en donde se hace la conversion o uso del codigo de 7 segmentos, deberia funcionar. Pero si no habria que buscar en todo el codigo para ver si hay lagun otro lugar y hacer el cambio correspondiente.

Saludos,

Elreypic.
Título: Re: Reloj digital con 16f84
Publicado por: cmontoya en 05 de Marzo de 2014, 00:04:40
Hola
Gracias elreypic2 por tu colaboración y pues si lo probé en proteus y en físico y funciono bien el único problema que tiene ahora es que cuando marca  la 1:00  marca es 81:00 y el error está presente tanto en la simulación como en el montaje físico alguna solución??

Título: Re: Reloj digital con 16f84
Publicado por: elreypic2 en 05 de Marzo de 2014, 10:09:30
Que tal cmontoya,

Yo no tengo ese problema. Podrias subir el codigo que modificaste para darle un vistazo. Es posible que previamente hayas cambiado algo mas.

tapi8,

Cometi el error de no poner atencion en tu comando de comf. Tu idea esta correcta, pero no la forma de usar el comando.

comf  w,0 no se puede usar ya que W no es registro fisico
la coreector es usar el comf en el registro indf, por loq ue el codigo quedaria asi:
PROX_DIGITO
   movf   INDF,W      ; Obtener el valor de la variable "digito" actual
   call   CODIGO_7S   ; LLamar a la rutina de conversión a código 7 segmentos   
   movwf   INDF      ; Colocar en la variable "digito" el código 7 segmentos devuelto
   
   comf    INDF,F    ; Realiza el complemento, cambia 0 por 1 y viceversa 

   incf   FSR,F      ; Incremente INDF para el próximo "digito"
   decfsz   conta1,F   ; Permitir que conta1 de sólo 4 vueltas
   goto   PROX_DIGITO

Ademas de que no es el unico lugar en que hay que hacer cambios. Por lo que la mejor opcion es cambiar los valores de la codificacion de 7 segmentos. Como lo sugiero anteriormente.


Saludos,

Elreypic.
Título: Re: Reloj digital con 16f84
Publicado por: tapi8 en 05 de Marzo de 2014, 10:35:18
Citar
tapi8,

Cometi el error de no poner atencion en tu comando de comf. Tu idea esta correcta, pero no la forma de usar el comando.

comf  w,0 no se puede usar ya que W no es registro fisico
la coreector es usar el comf en el registro indf, por loq ue el codigo quedaria asi:
PROX_DIGITO
   movf   INDF,W      ; Obtener el valor de la variable "digito" actual
   call   CODIGO_7S   ; LLamar a la rutina de conversión a código 7 segmentos   
   movwf   INDF      ; Colocar en la variable "digito" el código 7 segmentos devuelto
   
   comf    INDF,F    ; Realiza el complemento, cambia 0 por 1 y viceversa 

   incf   FSR,F      ; Incremente INDF para el próximo "digito"
   decfsz   conta1,F   ; Permitir que conta1 de sólo 4 vueltas
   goto   PROX_DIGITO

Es lo mismo, creo, yo lo hago en W segun viene de la tabla antes de guardar y tu lo haces en INDF una vez que esta ya guardado, no lo he probado en el simulador, pero creo que hacemos lo mismo.

Citar
Ademas de que no es el unico lugar en que hay que hacer cambios. Por lo que la mejor opcion es cambiar los valores de la codificacion de 7 segmentos. Como lo sugiero anteriormente.

Si seguramente haya que hacer algun cambio mas, en la incializacion o algun otro sitio, por eso le puse a cmontoya las dos opciones.

Título: Re: Reloj digital con 16f84
Publicado por: elreypic2 en 05 de Marzo de 2014, 10:48:01
cmontoya,

Creo que el error es mio, anteriormente mencione que no debias cambiar el SEGM_OFF, pero no es asi. Sí tienes que complementarlo tambien.
Es decir:

SEGM_OFF   equ      H'FF'   ;              11111111Todos los segmentos apagados. Separador entre horas
                     ; y minutos apagado (RB0).

Tapi8,
Lo que yo quiero decirte es que tu idea es valida, pero la instruccion comf W,0 no es valida, al compilar tendras un error ya que comf complementa una variable, comf no puede usarse para el registro W. Por eso es que la tienes que usar con el registro indf.

Saludos,

Elreypic.
Título: Re: Reloj digital con 16f84
Publicado por: tapi8 en 05 de Marzo de 2014, 15:37:33
Citar
Lo que yo quiero decirte es que tu idea es valida, pero la instruccion comf W,0 no es valida, al compilar tendras un error ya que comf complementa una variable, comf no puede usarse para el registro W. Por eso es que la tienes que usar con el registro indf.

Pues tienes razon, compilar si compila pero hace cosas muy muy raras.

Puse este codigo para probar:

Código: [Seleccionar]
list p=16F84A
#include P16F84A.inc

conta1 equ 0x20


PROX_DIGITO
   movf   INDF,W      ; Obtener el valor de la variable "digito" actual
   call   CODIGO_7S   ; LLamar a la rutina de conversión a código 7 segmentos
   comf   W,0      ; Realiza el complemento, cambia 0 por 1 y viceversa   
   movwf   INDF      ; Colocar en la variable "digito" el código 7 segmentos devuelto
   incf   FSR,F      ; Incremente INDF para el próximo "digito"
   decfsz   conta1,F   ; Permitir que conta1 de sólo 4 vueltas
   goto   PROX_DIGITO

CODIGO_7S

retlw 0x81

END


No se si estoy tonto, quiero decir mas de lo habitual  :lol: :lol: si es un bug de mi MPLAB. Pero hace la conversion asi:

1 vez FFH-255
2 vez 00H-00
3 vez FCH-252 y a partir de aqui da siempre FCH que es justo el doble de lo que deberia dar y a parte el programa se bloquea en la siguiente instruccion aqui:

movwf   INDF      ; Colocar en la variable "digito" el código 7 segmentos devuelto

no sigue ejecutandolo y vuelve al principio, creo que debido a que el FSR se pone en 02, ya que si lo pongo a 0 vuelve a empezar.
Título: Re: Reloj digital con 16f84
Publicado por: BrunoF en 10 de Marzo de 2014, 13:32:18
El registro de trabajo W no es un registro físico en un 16F84. Esto significa que no está mapeado en memoria, por lo que intentar hacer una operación como la COMF W,0 es equivalente a hacer COMF 0,0 lo que es lo mísmo que hacer COMF INDF,W lo que no es lo deseado.

XORLW 0xFF sirve perfectamente para este caso.

Saludos
Título: Re: Reloj digital con 16f84
Publicado por: tapi8 en 10 de Marzo de 2014, 15:21:46
Gracias por la aclaracion Bruno, si que funciona con XORLW 0xFF, pero hace lo mismo, a la tercera vez que corres el programa el reg FSR llega "02" y entonces al llegar a la instruccion  movwf   INDF , en vez de seguir ejecutando el programa se va al comienzo.

Citar
El registro de trabajo W no es un registro físico en un 16F84.

¿En otros de la serie 16F si funcionaria?
Título: Re: Reloj digital con 16f84
Publicado por: BrunoF en 10 de Marzo de 2014, 15:41:28
Lo de que funcione en otros 16F sí. Los 16F más modernos ya mapean al WREG en la memoria y por lo tanto WREG puede utilizarse como un registro comun más. Pero es sólo en los micros más nuevos dentro de la familia de 16F, que hasta creo incluyen un set de instrucciones más completo que las 35 famosas conocidas en los 16F.

Volviendo al asunto:

Cuando uno pasa de común ánodo a común cátodo, no sólo es importante la lógica de los segmentos, sino del control de encendido de los displays. Mostranos el circuito eléctrico que estás queriendo usar, y te puedo explicar qué necesitás modificar en el código y el por qué. A lo sumo, serán un par de líneas de assembler.

Saludos,
Título: Re: Reloj digital con 16f84
Publicado por: tapi8 en 11 de Marzo de 2014, 06:23:55
Citar
Cuando uno pasa de común ánodo a común cátodo, no sólo es importante la lógica de los segmentos, sino del control de encendido de los displays. Mostranos el circuito eléctrico que estás queriendo usar, y te puedo explicar qué necesitás modificar en el código y el por qué. A lo sumo, serán un par de líneas de assembler.

No Bruno gracias, si quien tenia el problema era cmontoya, pero creo que con lo que le dijo Elreypic2 ya lo tendra solucionado, lo que pasa es que yo estaba convencido que haciendo esto "comf W,0" se evitaba tener que cambiar la tabla, pero hay que hacer el cambio en "comf    INDF,F", siempre se aprende algo.
Título: Re: Reloj digital con 16f84
Publicado por: cmontoya en 15 de Marzo de 2014, 00:19:50
Claro que mi problema ya lo resolvi con la ayuda de los consejo de elreypic2, le estoy agradecido :)

Saludos