Reloj Digital con PIC16F84A

Hola que tal, verán. Estoy en pleno desarrollo de un circuito de un reloj digital. Utilizando el pic16F84A y un IC 74LS138 con displays de cátodo común a 1 dígito y 7 segmentos. Segun yo tengo todo bien conectado, a todo esto, lo estoy emulando con proteus 7.7 y mis displays no encienden. No se si esté conectando algo mal o no le esté mandando suficiente corriente o de plano, sea mi código. Cuando enciendo el emulador, los foquitos de las patitas RB0 a RB7 del PIC parpadean y no se si eso sea normal. Les dejo una imagen de lo que me manda el Proteus cuando comienzo la emulación y pues, creo que si se ve claro el diagrama. Si me pudieran orientar, les agradecería muchisimo. Saludos y buena vibra.
 

Adjuntos

  • j.png
    j.png
    29 KB · Visitas: 193
Hola, yo hice algo parecido pero no use ese integrado, use transistores, pero supongo que el funcionamiento es asi:
lo que sale por el puerto b esta multiplexado en el tiempo y debe salir datos de las horas minutos y segundos, ese es el parpadeo que ves. por ahi en la simulacion no se vea en tiempo real y tengas que bajar la frecuencia del oscilador del pic. si tenes a 4 mhz cambialo a 1 mhz y al estar mas lento podes ver los datos en los displays.
proba eso. saludos
 
Hola, gracias por tu respuesta, he cambiado la frecuencia del pic, a 1MHz tal y como me lo sugeriste, pero, sigue igual. He conectado unas resistencias en las entradas del puerto A del pic, las que conectan a éste con el CI 138, y conecté todos los displays a la patita 17 del 138. Ahora los displays encienden, pero nada hacen, los botones no funcionan, solamente el de reset. Me podrias explicar como es que usaste los transistores? Gracias de antemano.
 
Lo de los transistores que menciona sdel hacen lo mismo que el multiplexor que tu has usado. Un transistor que conmuta la alimentación de cada display y los activas atacando las bases des de el PIC. Yo más bien me inclino a pensar que tienes algo mal en tu programa. Si no es eso, es que has conectado mal el multiplexor.
 
aparte de lo que dice kalamarus en el programa del pic de cuanto es el retardo que usas para sacar los valores? proba con retardos de 100 o 200ms

fijate si tenes los pines ra2 ra3 y ra4 configurados como salida, aparecen como deshabilitados en tu diagrama.

saludos
 
Última edición:
aparte de lo que dice kalamarus en el programa del pic de cuanto es el retardo que usas para sacar los valores? proba con retardos de 100 o 200ms

fijate si tenes los pines ra2 ra3 y ra4 configurados como salida, aparecen como deshabilitados en tu diagrama.

saludos

Si, le conecté unas resistencias y se habilitaron. Como comenté antes, ahora se encienden, pero los botones nada mandan, al parecer es error de mi código. Ahora solo tengo una pregunta aparte de todo esto. Alguien sabe, porque en proteus al emular me manda este error: "no model specified for J1". J1, es un conector al que conecto los cables del display. Pero no se si se necesite alguna configuración extra.
 
Alguien sabe, porque en proteus al emular me manda este error: "no model specified for J1". J1, es un conector al que conecto los cables del display. Pero no se si se necesite alguna configuración extra.
Ese error quiere decir que no se encontro un modelo simulable para el conector J1
Edita sus propiedades seleccionando la casilla que dice Exclude from Simulation y listo. :apreton:
 
Bueno tengo un diseño en Proteus y estoy interesado en hacer un reloj de 6 digitos con display de 7 segmentos.

(00 : 00 : 00 )
hrs : min : seg

Ver el archivo adjunto 63730

Por ahora, quise implementar mi idea en un código que está hecho para hacer solamente minutos y segundos.

Incorporé las horas, lo corri y sólo me aparece un 7 y se apagan mientras que los min. y seg. funcionan correctamente.

¿Alguien me podría dar una ayuda? mi código es en ensamblador y soy novato con esta cosas y pues me gustaría saber como hacerlo.

Gracias
 
Hola MrCarlos por responder, estuve viendo y creo que encontré una forma de hacer funcionar a un display de la hora, pero no lo toma al 100%.

anexo codigo con el diseño:
Ver el archivo adjunto RELOJ.rar


El código no me sale x mas que intento, estoy seguro que se puede hacer con el pic 16f84A vi la pagina que me pasaste pero está utilizando otra forma extraña jeje sin ofender, pero siento que estoy por terminar esto, quizá se me cerró el mundo momentaneamente pero ya saldrá.
 
Hola miguelrmz08

Aunado a que no sé prácticamente nada de ensamblador, no tengo herramientas de SoftWare como para compilar el código que adjuntaste.

Pero por aquí, en el foro, podrías encontrar algo que te ayude a desarrollar tu código, hay varios solo buscalos.

saludos
a sus ordenes
 
El código que postea MrCarlos, es para un Atmel... nada que ver con el PIC, no es que sea una "forma extraña", es solo una manera más de resolver lo planteado.
¿Si o sí tenés que emplear el 16F84? se queda corto de pines... me parece que deberías pasarte a un PIC16F873.
Para el 16F84 hay un truco, pero significa introducir dos integrados más.
Es la imagen, claro todo esto para no volverse loco con la programación, no es sano para la mente emplear las sugerencias de la AN234 (pag.3)
 

Adjuntos

  • Pic&Disp8D.jpg
    Pic&Disp8D.jpg
    29 KB · Visitas: 32
Última edición:
Hola que tal, veo que el post tiene mas de 2 años pero como esta vivo .....
yo tengo un reloj digital de 24Hs con 4 display 7seg.
Le hice modificaciones para que que quede bien funcionando correctamente.
Salvo que cuando uno va a segundos se resetea, pero solo perderia unos segundos, sino funciona correctamente.aca el codigo en asm
Código:
;*************************************************************
; RELOJ DE 24 HORAS
;*************************************************************
;
; Programa original:  CLOCK54.ASM
;      Dan Matthews
;      Microchip Technology Inc.
;      16 de enero de 1997
;      [URL="http://www.microchip.com"]www.microchip.com[/URL], AN590.PDF
; Revisión:    RELOJ24H.ASM
;      Emilio Toboso
;      I.E.S. "La Fuensanta" Córdoba
;      Abril de 2005
; Programa para PIC16F84A
; Frecuencia de reloj: 4 MHz
; Instrucción: 1Mz = 1 us
; Perro Guardián: OFF
; Tipo de Reloj: XT
; Protección de código: OFF
; POR: ON
; 
;*************************************************************
; DESCRIPCIÓN DEL PROGRAMA
;*************************************************************
;
; Este programa funciona en un PIC16F84A y se trata de un reloj
; de 24 horas que muestra horas y minutos.
; Dispone de dos displays LED para las horas y otros dos para los
; minutos.
; Para programar la hora se dispone de un pulsador de avance rápido
; de horas y de otro para avance rápido de minutos.
; También se dispone de un tercer pulsador que se utiliza para mostrar
; los segundos mientras permanezca pulsado. 
;  
; DESCRIPCIÓN DEL HARDWARE
;  
; VISUALIZACIÓN:  
;
; La hora se muestra mediante cuatro displays de 7 segmentos de cátodo
; común multiplexados. Los segmentos de cada display se unen y estan
; controlados a través de resistencias por salidas del PIC. Cada cátodo
; común de cada display es controlado por el PIC a través de un transistor.
; El reloj presenta las horas y minutos por dos puntos (88:88). Los
; segmentos se asignan al puerto B.
; Los dos puntos se realizan mediante dos LED en serie con una resistencia
; y se conectan a RB0.
; Los segmentos de los displays, de "a" hasta "f" se asignan a las salidas
; de RB1 a RB7.  
; Los cuatro cátodos comunes se controlan mediante el puerto A a través de
; los transistores.  
; RA0 controla la decena de hora, RA1 la unidad de hora; RA2 la decena de
; minuto y RA3 la unidad de minuto.  
;  
; PULSADORES:  
;
; Sobre los tres pulsadores:
; Pulsador avance rápido de horas conectado a RB3
; Pulsador avance rápido de minutos conectado a RB2
; Pulsador para mostrar los segundos conectado a RB1
;
; Debido a que todas las patillas E/S (salvo RA4) están utilizadas,  
; se debe comprobar el estado de los pulsadores estableciendo como salidas
; o como entradas alternativamente las patillas a las que están conectados.
; Los pulsadores utilizan el Puerto B que cambiará a entrada durante un
; instante para comprobar el estado de los pulsadores.  
;
;
;
;
;
;
;
;
;
;
;
;
;*************************************************************
; PATILLAS
;*************************************************************
;                                           ___________
; DISPLAY DECENA MIN / DECENA SEG -> RA,2 -|1   \__/ 18|- RA,1 <- DISPLAY UNIDAD HR
; DISPLAY UNIDAD MIN / UNIDAD SEG -> RA,3 -|2        17|- RA,0 <- DISPLAY DECENA HR
;                                      NC -|3 16F84A 16|- XT          
;                                   MCLR/ -|4        15|- XT
;                                     GND -|5        14|- Vcc
;                        PUNTO dp -> RB,0 -|6        13|- RB,7 -> SEGMENTO g
;        PUL A (SEG) / SEGMENTO a -> RB,1 -|7        12|- RB,6 -> SEGMENTO f
;        PUL B (MIN) / SEGMENTO b -> RB,2 -|8        11|- RB,5 -> SEGMENTO e
;        PUL C (HOR) / SEGMENTO c -> RB,3 -|9________10|- RB,4 -> SEGMENTO d      
;
; PORTA, control displays 7 segmentos de cátodo común
; PORTB, segmetos de los displays, led separadores, pulsadores como entrada
;
; El pulsador A (conectado a RB1) muestra el segundero en tanto permanezca presionado.
; El pulsador B (conectado a RB2) avanza rápidamente los minutos.
; El pulsador C (conectado a RB3) avanza rápidamente las horas.
;
;*************************************************************
 LIST P=PIC16F84A  ; Pic a usar
#INCLUDE <P16F84A.INC>  ; Lista de etiquetas de microchip
;
;*************************************************************
; Configuración opciones de hardware para la programación
  __CONFIG    _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC       
;
;**************************************************************
; Lista de constantes y variables para el uso del programa
;**************************************************************
;
; Valores de constantes ***************************************
;
FRAC_INI equ  D'12' ; Constante para inicio cuenta de fracciones de segundo
SEGS_INI equ  D'196' ; Constante para inicio cuenta de segundos
MINS_INI equ  D'196' ; Constante para inicio cuenta de minutos
HORS_INI equ  D'232' ; Constante para cuenta de horas
ADJMIN  equ  D'9' ; Número de "frac_sec" que se necesita sumar cada minuto
       ; para ajustar el tiempo
ADJHOR  equ  D'34' ; Número de "frac_sec" que se necesita restar cada hora
       ; para ajustar el tiempo
ADJDIA  equ  D'6' ; Número de "frac_sec" que se necesita sumar cada 24 horas
       ; para ajustar el tiempo
;Ajustes
; Un "frac_sec" es aproximadamente 1 / 244 s
; 1 MHz / 16 = 62.500 Hz ; 62.500 Hz / 256 = 244,140625 Hz ; T = 0,004096 s
; 0,004096 s * 244 = 0,999424 s; dif 1 segundo = -0,000576 s
; 1 "minuto" = 0,999424 s * 60 = 59,96544 s
; 60 s - 59,96544 s = 0,03456 s ; 0,03456 s / 0,004096 s = 8,4375
; 1 "minutoadj" = 59,96544 s + (0,004096 s * 9) = 59,96544 s + 0,036864 s = 60,002304 s
; 1 "hora" = 60,002304 s * 60 = 3600,13824 s
; 3600 s - 3600,13824 s = -0,13824 s ; -0,13824 s / 0,004096 s = -33,75 s
; 1 "horaadj" = 3600,13824 s - (0,004096 s * 34) = 3600,13824 s - 0,139264 s = 3599,998976 s
; 24 "horas" = 3599,998976 s * 24 = 86399,975424 s
; 86400 s - 86399,975424 s = 0,024576 s ; 0,024576 s /  0,004096 s = 6
; 24 "horasadj" = 86399,975424 s + 0,004096 s * 6 = 86399,975424 s + 0,024576 s = 86400 s
;
; Activación de RB1-3 para las entradas de los pulsadores
PULSADOR equ  B'00001110' ; RB1, RB2 y RB3
;
; Asignación de banderas. Los pulsadores activos proporcionan un "1"
CHG   equ  H'03' ; Indica que se ha activado un pulsador o que es necesario
       ; actualizar los valores de la hora que tienen que mostrarse
       ; en los displays
PSEG  equ  H'04' ; Pulsador A, modo segundero.
PMIN  equ  H'05' ; Pulsador B, avance rápido minutos.
PHOR  equ  H'06' ; Pulsador C, avance rápido horas.
P_ON  equ  H'07' ; Un pulsador ha sido activado
;
DSPOFF  equ  B'11111111' ; Displays apagados (PORTA)
;
; Mapa de activación de segmentos para los displays (PORTB)
;         a
;   =========
;   |       |
; f |       | b
;   |   g   |
;   =========
;   |       |
; e |       | c
;   |       |
;   ========= # p
;         d
;
       ; gfedcbap
CERO  equ  H'7E' ; 01111110
UNO   equ  H'0C' ; 00001100
DOS   equ  H'B6' ; 10110110
TRES  equ  H'9E' ; 10011110
CUATRO  equ  H'CC' ; 11001100
CINCO  equ  H'DA' ; 11011010
SEIS  equ  H'FA' ; 11111010
SIETE  equ  H'0E' ; 00001110
OCHO  equ  H'FE' ; 11111110
NUEVE  equ  H'DE' ; 11011110
SEGM_OFF equ  H'00' ; Todos los segmentos apagados. Separador entre horas
       ; y minutos apagado (RB0).
;
; Posición de memoria de variables ************************************
; Las variables de tiempo comienzan con un número que permite contar y ajustar el tiempo  
; Por ejemplo la variable "segundos" se inicia con 196 decimal, para que después de 60
; incrementos de 1 segundo se produzca un 0 (196 + 60 = 256 -> 0)
frac_sec equ  H'0C' ; Fracciones de segundo (1/244)
segundos equ  H'0D' ; Segundos
minutos  equ  H'0E'   ; Minutos
horas  equ  H'0F'   ; Horas
conta1  equ  H'10' ; Variable 1 para bucle contador
;
display  equ     H'11' ; Indicador de display que debe actualizarse
digito1  equ  H'12' ; Display unidad de minuto / unidad de segundo
digito2  equ  H'13' ; Display decena de minuto / decena de segundo
digito3  equ  H'14' ; Display unidad de hora
digito4  equ  H'15' ; Display decena de hora
banderas equ     H'16' ; Banderas; 3-CHG, 4-PSEG, 5-PMIN, 6-PHOR, 7-P_ON
;
;**************************************************************
 ORG 0x00  ;Vector de Reset
 goto INICIO
 org 0x05  ;Salva el vector de interrupción
;**************************************************************
; SUBRUTINAS
;**************************************************************
CODIGO_7S ; Devuelve el código 7 segmentos
 addwf PCL,F
 retlw CERO
 retlw UNO
 retlw DOS
 retlw TRES
 retlw CUATRO
 retlw CINCO
 retlw SEIS
 retlw SIETE
 retlw OCHO
 retlw NUEVE
;**************************************************************
;
;
;
;
;
;
;
;
;
;
;**************************************************************
; Comienzo del programa
;**************************************************************
;
INICIO
;  Configurar puertos como salidas, blanquear display
 bsf  STATUS,RP0 ; Activa el banco de memoria 1.
 movlw B'10000011' ; Configuración del registro Option, RB Pull Up desconectadas
 movwf OPTION_REG ; TMR0 en modo temporizador (uso de pulsos de reloj internos, Fosc/4)
      ; prescaler TMR0 a 1:16 
 movlw B'00000000'
 movwf TRISA  ; Pone todas las patillas del puerto A como salidas
 movwf TRISB  ; Pone todas las patillas del puerto B como salidas
 bcf  STATUS,RP0 ; Activa el banco de memoria 0.
;
; Establecer estados iniciales de las salidas
 movlw DSPOFF
 movwf PORTA  ; Apaga los displays
 movlw B'00000001' ; Todos los segmentos apagados. Separador 
 movwf PORTB  ; entre horas y minutos encendido (RB0).
;
; Inicialización de variables:
 movlw H'01'
 movwf TMR0  ; Pone 01h en TMR0
 movlw B'11111110' 
 movwf display  ; Inicia display seleccionando decena de hora
 movlw CERO
 movwf digito1  ; Aparecerá un "0" en el display unidad de minutos
 movwf digito2  ; Aparecerá un "0" en el display decena de minutos
 movwf digito3  ; Aparecerá un "0" en el display unidad de hora
 ;movlw SEGM_OFF ======================= EDITADO =======================
 movwf digito4  ; No aparecerá nada en el display decena de hora
 movlw B'00000000'
 movwf banderas ; Coloca todas las banderas a 0
;
; Inicia las variables de tiempo
 movlw FRAC_INI
 movwf frac_sec ; 12
 movlw SEGS_INI
 movwf segundos ; 196
 movlw MINS_INI
 movwf minutos  ; 196
 movlw HORS_INI
 movwf horas  ; 232
;
;**************************************************************
PRINCIPAL ; Rutina principal cíclica
;**************************************************************
;
;  Esperar al desbordamiento de TMR0
TMR0_LLENO
; 4 MHz -> 1 MHz
;   1.000.000 Hz / 16 = 62.500 Hz
;   62.500 Hz / 256 = 244,140625 Hz -> 4,096 ms
 movf TMR0,W
 btfss STATUS,Z ; TMR0 cuenta libremente para no perder ciclos del reloj
      ; escribiendo valores
 goto TMR0_LLENO
;
; Se ha desbordado TMR0 y se han contado 256.
; Tarda en desbordarse 4.096 ciclos de reloj, 4,096 ms
 incfsz frac_sec,F  ; Se añade 1 a frac_sec
 goto COMPROBAR_CHG ; Se comprueba el estado de “CHG” por si se ha activado
       ; algún pulsador o es necesario actualizar los valores
       ; de la hora que tienen que mostrarse en los displays
;
; Se ha desbordado frac_sec y se han contado 244 "frac_sec", 1 segundo.
; Tarda en desbordarse 4.096 ciclos de reloj, 4,096 ms * 244 = 999,424 ms
; Al no consegirse exactamente 1 segundo sino 0,999424 s, luego se necesitan ajustes
 bsf  PORTB,0  ; Se activa separador horas-minutos
 movlw FRAC_INI
 movwf frac_sec  ; Restaura la variable frac_sec para la próxima vuelta
;
COMPROBAR_PUL ; Comprueba variables pulsadores
 btfss banderas,P_ON ; Si no se ha pulsado nada, se pasa a INC_HORA
 goto INC_HORA  ; Incrementa segundos, minutos y horas. Ajustes y “CHG” a 1
 btfsc banderas,PSEG ; Comprobar si se ha pulsado PSEG (Pulsador segundos)
 goto INC_HORA  ; Se ha pulsado PSEG, (Pul A) y se mostrarán
       ; los segundos en el display
;
PONER_RELOJ
 movlw SEGS_INI ; 196d
 movwf segundos ; Inicia los segundos cuando se pone el reloj en hora
;
PONER_MINUTOS
 btfss banderas,PMIN ; Comprobar si se ha pulsado PMIN (Pulsador minutos)
 goto PONER_HORAS     ; No se ha pulsado PMIN, ir a comprobar estado de PHOR
 movlw H'AF'   ; 175d
 movwf frac_sec     ; Avance rápido del tiempo cuando se ajustan minutos frac_sec = 175
 incfsz minutos,F  ; Incrementar los minutos
 goto PONER_HORAS
 movlw MINS_INI
 movwf minutos   ; Iniciar minutos si al incrementar se han desbordado
;
PONER_HORAS
 btfss banderas,PHOR ; Comprobar si se ha pulsado PHOR (Pulsador horas)
 goto OBTENER_H_M  ; No se ha pulsado PHOR, no se cambian las horas
 movlw H'7F'   ; 127d
 movwf frac_sec  ; Avance rápido del tiempo cuando se ajustan horas frac_sec = 127
 incfsz horas,F   ; Incrementar la hora
 goto OBTENER_H_M
 movlw HORS_INI
 movwf horas   ; Iniciar la hora si al incrementar se han desbordado
 goto OBTENER_H_M   
;
INC_HORA ; Incrementar segundos, minutos y horas
   ; Ajustes cada minuto, hora y 24 horas
 bsf  banderas,CHG ; Se especifica que se ha producido un cambio
;
 incfsz segundos,F   ; Como ha pasado un segundo se incrementa "segundos"
 goto COMPROBAR_CHG
 movlw SEGS_INI     ; Se ha desbordado "segundos" y se reestablece el valor inicial
 movwf segundos  ; de "segundos" para la próxima vuelta
;
 movlw ADJMIN   ; Se resta 9 a "frac_sec" cada minuto para los ajustes de tiempo 
 subwf frac_sec,F   ; El minuto será 9 "frac_sec" más largo
;
 incfsz minutos,F    ; Se añade 1 minuto
 goto COMPROBAR_CHG
 movlw MINS_INI  ; Se ha desbordado "minutos" y Se reestablece el valor inicial
 movwf minutos     ; de "minutos" para la próxima vuelta
;
 movlw ADJHOR   ; Se suma 34 a "frac_sec" cada hora para los ajustes de tiempo 
 addwf frac_sec,F  ; La hora será 34 "frac_sec" más corta
;
 incfsz horas,F     ; Se añade 1 hora
 goto COMPROBAR_CHG
 movlw HORS_INI  ; Se ha desbordado "horas" y se reestablece el valor inicial
 movwf horas     ; de "horas" para la próxima vuelta
 movlw ADJDIA   ; Se resta 6 a "frac_sec" cada 24 horas para los ajustes de tiempo
 subwf frac_sec,F   ; Cada 24 horas se añadirán 6 "frac_sec"
;
; Se comprueba el estado de “CHG” por si se ha activado
; algún pulsador o es necesario actualizar los valores
; de la hora que tienen que mostrarse en los displays
; Se actualiza hora, displays y pulsadores cada 4,096 ms (244 veces por segundo)
COMPROBAR_CHG  
 btfss banderas,CHG ; Si no se han activado pulsadores ni ha cambiado la hora
  goto DISPLAY_PUL  ; se salta a DISPLAY_PUL, que principalmente refresca uno de los
       ; displays cada vez que se accede a ella y escanea pulsadores.
;
COMPROBAR_SEG ;  Se comprueba si se activo el pulsador de segundos (Pul A)
    ; para mostrar los segundos en el display
 btfss banderas,PSEG
 goto OBTENER_H_M  ; No estaba pulsado PSEG
 movlw H'00'   ; Se mostrarán los segundos en el display de minutos
 movwf digito2   ; Variables "digito2" a 0
 movwf digito3   ; Variables "digito3" a 0
 movwf digito4   ; Variables "digito4" a 0
 movlw SEGS_INI
 subwf segundos,W
 movwf digito1   ; Se guarda temporalmente el número de segundos en “digito1”
 goto DIV_DIGITOS  
;
OBTENER_H_M
 movlw HORS_INI
 subwf horas,W
 movwf digito3  ; La variable digito3 almacena temporalmente el valor para las horas
 movlw MINS_INI
 subwf minutos,W
 movwf digito1  ; La variable digito1 almacena temporalmente el valor para los minutos
;
DIV_DIGITOS  ; Divide los segundos o los minutos y las horas en dígitos independientes
    ; ejemplo, [14] lo pasa a [1]-[4]
 movlw H'00'
 movwf digito4  ; Se ponen a cero las posiciones de las decenas
 movwf digito2  ; para el caso de que no se incrementen
 movlw H'02'
 movwf conta1  ; Bucle para convertir cada número (segundos o minutos y horas)
 movlw digito1  ; Dirección de digito1 en FSR para usar INDF
 movwf FSR   ; La primera vez, FSR = digito1 (minutos o segundos) y la segunda vez FSR = digito3 (horas)
 goto LOOP  
;
LOOP2 ; Este LOOP se utiliza para las horas después de trabajar con los minutos o los segundos
 movlw digito3
 movwf FSR   
;
LOOP ; Este LOOP se utiliza primero para los minutos o los segundos y después para las horas
 movlw D'10'   ; Averiguar cuantas "decenas" hay en el número
 subwf INDF,F   ; En cada LOOP restar 10 al número
 btfsc STATUS,C        ; Se comprueba "C", que se pone a 1 si en la resta no se ha
       ; producido llevada
 goto INC_DECENAS    ; C = 1 por lo que se añade 1 a la posición de las decenas
 addwf INDF,F   ; C = 0, no se incrementan las decenas y se suma 10 para restaurar
       ; las unidades
 goto PROX_NUM
;
INC_DECENAS
 incf FSR,F  ; El puntero apunta a la primera posición de las decenas
 incf INDF,F  ; Se añade 1 a las decenas
 decf FSR,F    ; Se restaura el valor de INDF para apuntar al número
 goto    LOOP  ; para la próxima resta hasta que se termine
      ; Con "goto LOOP" se vuelve a comprobar si es necesario
      ; sumar uno a la decena cada vez que esta se ha incrementado
;
PROX_NUM ; Próximo número, primero ha sido segundos o minutos y luego horas
 decfsz conta1,F
 goto LOOP2
;
CONVER_COD_7S ; Convierte cada dígito a código 7 segmentos para los displays
 movlw digito1 
 movwf FSR  ; Coloca la dirección del primer digito (digito1) en FSR
 movlw H'04'
 movwf conta1 ; Prepara la variable conta1 para el bucle de los 4 displays
;
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
 incf FSR,F  ; Incremente INDF para el próximo "digito"
 decfsz conta1,F ; Permitir que conta1 de sólo 4 vueltas
 goto PROX_DIGITO
;
BORRAR_CERO  ; Si hay un cero en el display de las decenas de hora
    ; no se muestra (borrado de los ceros a la izquierda)
 movlw CERO
 subwf digito4,W
 btfss STATUS,Z
 goto BORRAR_CERO_SEG
 ;movlw SEGM_OFF ;         =================================================
 movlw CERO ; EDITADO =================================================
 movwf digito4
;
BORRAR_CERO_SEG
 btfss banderas,PSEG ; Si está pulsado PSEG no se muestra nada en el display de la
 goto DISPLAY_PUL  ; posición de la unidad de hora.
 movlw SEGM_OFF  ; Contando con BORRAR_CERO, esto significa que sólo se
 ;movlw CERO ; EDITADO =================================================
 movwf digito3   ; mostrarán los segundos.
 movwf digito4   ; ====== EDITADO ======.
;
DISPLAY_PUL  ; Se borran los bits de flag para actualizar su estado
    ; Escanea pulsadores, si alguno está pulsado se pone a 1
    ; el pulsador que le correspoda así como "P_ON" y "CHG"
    ; Muestra los dígitos correspondientes a los segundos o a
    ; los minutos y horas en el display que corresponda.
;
 movlw B'00000000'
 movwf banderas ; Se borran los bits de flag para actualizar su estado
;
 ; Apagar los displays
 movlw DSPOFF
 movwf PORTA  
;
 ; Apagar los segmentos respetando separador horas-minutos
 movlw SEGM_OFF ; Respeta valor RB0
 xorwf PORTB, w
 andlw B'11111110' ;  Poner "1" el la posición del bit a copiar
 xorwf PORTB, f
;
 ; Configurar los bits 1, 2 y 3 de PORTB como entrada
 bsf  STATUS,RP0 ; Activa el banco 1.
 movlw PULSADOR
 movwf TRISB  ; Se configuran los bits 1, 2 y 3 de PORTB como entrada
 bcf  STATUS,RP0 ; Activa el banco 0.
 nop  ; Las instrucciones "nop" pueden no ser necesarias.
 nop  ; En principio proporcionan el tiempo suficiente para que los
 nop  ; estados anteriores de las salidas se actualicen a través de
 nop  ; las resistencias de 10K (y de las de 820 ohm si está activado
 nop  ; algún pulsador) antes de leer las patillas del puerto.
;
COMPROBAR_PSEG ; Se comprueba Pulsador PSEG
 btfss PORTB,1
 goto COMPROBAR_PMIN
 bsf  banderas,CHG
 bsf  banderas,PSEG
 bsf  banderas,P_ON
;
COMPROBAR_PMIN ; Se comprueba Pulsador PMIN
 btfss PORTB,2
 goto COMPROBAR_PHOR
 bsf  banderas,CHG
 bsf  banderas,PMIN
 bsf  banderas,P_ON
;
COMPROBAR_PHOR ; Se comprueba Pulsador PHOR
 btfss PORTB,3
 goto ACTIVAR_SEGM
 bsf  banderas,CHG
 bsf  banderas,PHOR
 bsf  banderas,P_ON
;
ACTIVAR_SEGM ; Se coloca en PORTB el valor para los segmentos del display actual
 bsf  STATUS,RP0 ; Activa el banco 1.
 movlw H'00'
 movwf TRISB  ; Puerto B como salida
 bcf  STATUS,RP0 ; Activa el banco 0.
;
 ; Se determina que display debe actualizarse, es decir, que dato debe
 ; presentarse en el puerto B y se establece el siguiente display
 btfss display,0 ; Si es el primer display (decena de hora) tomar digito4
 movf digito4,W
 btfss display,1 ; Si es el segundo display (unidad de hora) tomar valor digito3
 movf digito3,W
 btfss display,2 ; Si es el tercer display (decena de min/seg) tomar valor digito2
 movf digito2,W
 btfss display,3 ; Si es el cuarto display (unidad de min/seg) tomar valor digito1
 movf digito1,W
;
 ; Entregar el valor en puerto B y respetar valor RB0
 xorwf PORTB, w
 andlw B'11111110' ;  Poner "1" el la posición del bit a copiar
 xorwf PORTB, f
;
 btfsc frac_sec,7 ; Establecer el separador de horas y minutos a un 50% 
 bcf  PORTB,0  ; del ciclo (1/2 segundo encendido, 1/2 segundo apagado)
;
 movf display,W ; Tomar el valor del display que debe habilitarse
 movwf PORTA  ; Cada display se “enciende” con una cadencia de 244 Hz / 4 = 61 Hz   
 ; Cada display se “enciende” con una cadencia de 244 Hz / 4 = 61 Hz   
 ; En este momento están encendidos los segmentos correspondientes
;
 rlf  display,F ; Rota display 1 bit a la próxima posición
 bsf  display,0 ; Asegura un 1 en la posición más baja de display (luego se hará 0 si es necesario)
 btfss display,4 ; Comprueba si el último display fue actualizado
 bcf  display,0 ; Si lo fue, se vuelve a habilitar el primer display
      ; La variable display va cambiando:
      ; 1111 1101
      ; 1111 1011
      ; 1111 0111
      ; 1110 1110
      ; 1101 1101
      ; 1011 1011
      ; 0111 0111
      ; 1110 1110
      ; Sólo valen los 4 bits menos significativos
;
 goto    PRINCIPAL ; Volver a realizar todo el proceso
;
    END

Si desean la imagen la pueden solicitar, no la agregue porque me pedia subirla a la web, pero si alguien la necesita y se le hace dificil sacarla por codigo la subo ...
 
Última edición por un moderador:
Saludos Sres. Estoy de novato trabajando con PIC Simulator IDE y Proteus de ambos tengo conocimientos..
Me asignaron hacer el programa en .asm de un contador de 24 hrs que muestre min, seg y alguna otra unidad de tiempo mas pequeña para luego simularlo en un display usando proteus usando un PIC16F628A.
Les agradeceria cualquier tipo de ayuda referente a esta asignacion gracias de antemano!
 
Atrás
Arriba