TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado 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/)
-
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.
-
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
-
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.
-
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
-
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.
-
¿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???
-
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.
-
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.
-
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
-
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.
-
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??
-
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.
-
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.
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.
-
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.
-
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:
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.
-
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
-
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.
El registro de trabajo W no es un registro físico en un 16F84.
¿En otros de la serie 16F si funcionaria?
-
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,
-
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.
-
Claro que mi problema ya lo resolvi con la ayuda de los consejo de elreypic2, le estoy agradecido :)
Saludos