Reloj con PIC16f84A

El presente tutorial contiene información sobre el funcionamiento del reloj que consiste en una serie de 6 display de ánodo común los cuales son manejados por un circuito  74LS47 el cual está  conectado al microcontrolador PIC16F84A, también cuenta con un multiplexor 74LS138 el cual funciona como selector de display los cuales por medio de transistores mandan señales a los display mandando una señal de reloj que permite el paso de 5 voltios posteriormente  para hacer los incrementos en cada uno.

Material y equipo:

  • PIC16F84A
  • Cristal oscilador de 4 MHz
  • 2 Capacitores cerámicos de 22 pF
  • 3 Push botón
  • 6 Display de  7 segmentos de ánodo comun
  • Transistores 558
  • Resistencias (330W, 1 KW, 1 KW)
  • Circuito 74LS47 (su función es expandir el número de salidas)
  • Circuito 74LS138 (funcionará como selector de display para realizar el efecto de barrido)

Diagrama de armado :

Diagrama de flujo :

Programación de PIC16F84A

__CONFIG   _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

LIST    P=16F84A

INCLUDE  <P16F84A.INC>

;——–

M_UNI equ  H’1D’

M_DEC equ  H’1C’

H_UNI equ  H’1F’

H_DEC equ  H’1E’

S_UNI equ  H’20’

S_DEC equ  H’21’

BARR equ  H’1B’

PAUSE equ  H’1A’

;—————————————————————————–

#DEFINE  REINICIO PORTA,0

#DEFINE  MINUTO  PORTA,1

#DEFINE  HORA  PORTA,2

#DEFINE  DISPLAY  PORTB

:—————————————————————————-

ORG 0

Inicio

bsf                   STATUS,RP0

clrf                  DISPLAY

movlw             b’00011111′

movwf            PORTA

bcf                  STATUS,RP0

;————————— ——————————————

clrf     S_UNI

clrf      S_DEC

clrf      M_UNI

clrf      M_DEC

clrf      H_UNI

clrf      H_DEC

clrf      BARR

;—————————

Principal

clrf      BARR

VerificarPulsadorReset

btfss   REINICIO

call     InicializarRegistros

;——————————————————————————

;Para el botón de incremento de minutos y horas si importan los rebotes

;————————————————————–

VerificarPulsadorMinutos

Btfsc               MINUTO

goto                VerificarPulsadorHoras

call                  Temporizador

btfsc               MINUTO

goto              VerificarPulsadorHoras

goto              SoloMinutosEnUno

;—————————————————————–

VerificarPulsadorHoras

btfsc                HORA      ; ¿Pulsador presionado?, ¿(Pulsador)=0?

goto              SoloSegundosEnUno   ; No vuelve a leerlo

call    Temporizador; Espera a que se estabilicen los niveles de tensión.

btfsc              HORA      ; Comprueba si es un rebote.

goto              SoloSegundosEnUno   ; Era un rebote y sale fuera.

call                            SoloHorasEnUno

;——————————————————————————

SoloSegundosEnUno

Call                 IncrementarSegundosEnUno

Mostrar

Call                ValidarTiempo

Call                Barrido

Fin

Goto              Principal

;——————————————————————————

SoloMinutosEnUno

call                 IncrementarMinutosEnUno

goto                Mostrar

SoloHorasEnUno

Call                 IncrementarHorasEnUno

Goto              Mostrar

;*************************************

; Subrutina de Incremento de Registros

;*************************************

IncrementarSegundosEnUno

Incf                S_UNI,f

Movfw                       S_UNI

sublw              D’10’

btfsc                STATUS, Z     ; Verifica si el resultado fué cero

call      IncrementarSegundosEnDiez ; Si es cero, entonces acarreamos uno

return

;——————————————————————————

IncrementarSegundosEnDiez

clrf                 S_UNI

incf                 S_DEC,f

movfw           S_DEC

sublw              D’6′

btfsc               STATUS, Z     ; Verifica si el resultado fué cero

call      IncrementarMinutosEnUno  ; Si es cero, entonces acarreamos uno

return

;——————————————————————————

IncrementarMinutosEnUno

Clrf                 S_DEC      ; El acarreo implica limpiar el registro anterior

incf                 M_UNI,f      ; Incrementa el valor de M_UNI

movfw           M_UNI      ; Carga W con el valor del regustro M_UNI

sublw                        D’10’      ; Resta 10 para verificar si S_UNI=10?

Btfsc             STATUS, Z     ; Verifica si el resultado fué cero

call     IncrementarMinutosEnDiez ; Si es cero, entonces acarreamos uno

return

;——————————————————————————

IncrementarMinutosEnDiez

clrf      M_UNI      ; El acarreo implica limpiar el registro anterior

incf      M_DEC,f      ; Incrementa el valor de M_DEC

movfw                        M_DEC      ; Carga W con el valor del regustro M_DEC

sublw              D’6′      ; Resta 6 para verificar si S_UNI=6?

btfsc                STATUS, Z     ; Verifica si el resultado fué cero

call      IncrementarHorasEnUno  ; Si es cero, entonces acarreamos uno

return

;——————————————————————————

IncrementarHorasEnUno

clrf                  M_DEC

movfw           H_UNI

sublw              D’10’      ; Resta 6 para verificar si S_UNI=10?

btfsc               STATUS, Z     ; Verifica si el resultado fué cero

call      IncrementarHorasEnDiez  ; Si es cero, entonces acarreamos uno

return

;——————————————————————————

IncrementarHorasEnDiez

clrf                  H_UNI      ; El acarreo implica limpiar el registro anterior

incf                H_DEC,f      ; Incrementa el valor de H_DEC

movfw           H_DEC      ; Carga W con el valor del regustro H_DEC

sublw                         D’10’      ; Resta 6 para verificar si S_UNI=10?

btfsc               STATUS, Z     ; Verifica si el resultado fué cero

clrf                  H_DEC      ; Si es cero, entonces acarreamos uno

return

;——————————————————————————

enciende

call  Temporizador ; Pausa para establecer niveles de tensión correctamente

call  Temporizador

call  Temporizador

call  Temporizador

call  Temporizador

return

;*********************************

; Subrutina de Barrido de Displays

;*********************************

Barrido

Btfss   REINICIO   ; ¿Pulsador reposo?, ¿Pulsador=1?

call InicializarRegistros  ; Al llamar Inicializar_Registros se limpian los contadores

incf     BARR, f    ; Incrementa en 1 el registro de barridos

;Unidades de segundos

;——————–

movlw             b’00001111′  ; Activamos el primer display

movwf            DISPLAY   ; Movemos el dato al puerto B

movf              S_UNI,0   ; Mueve M_UNI al registro W

iorlw              b’00000000′  ; Aplicamos la máscara

movwf            DISPLAY   ; Mostramos en el puerto B

call                 enciende

movlw B’00001111′  ; Cargamos el valor adecuado a W para limpiar los registros

movwf DISPLAY   ; Se Limpia el display

;——————————————————————————

;Decenas de segundos

Movlw           b’00011111′  ; Activamos el segundo display

movwf          DISPLAY   ; Movemos el dato al puerto B

movf                         S_DEC,0   ; Mueve S_DEC al registro W

iorlw             b’00010000′  ; Aplicamos la máscara

movwf          DISPLAY   ; Mostramos en el puerto B

call                enciende

movlw B’00011111′  ; Cargamos el valor adecuado a W para limpiar los registros

movwf DISPLAY   ; Limpiamos el display para evitar que los dígitos se repitan

;——————————————————————————

;Unidades de minutos

movlw           b’00101111′  ; Activamos el tercer display

movwf          DISPLAY   ; Movemos el dato al puerto B

movf                         M_UNI,0   ; Mueve M_UNI al registro W

iorlw             b’00100000′  ; Aplicamos la máscara

movwf          DISPLAY   ; Mostramos en el puerto B

call                enciende

movlw B’00101111′  ; Cargamos el valor adecuado a W para limpiar los registros

movwf DISPLAY   ; Limpiamos el display para evitar que los dígitos se repitan

;——————————————————————————

;Decenas de minutos

movlw             b’00111111′  ; Activamos el cuarto display

movwf                        DISPLAY   ; Movemos el dato al puerto B

movf              M_DEC,0   ; Mueve M_UNI al registro W

iorlw              b’00110000′  ; Aplicamos la máscara

movwf           DISPLAY   ; Mostramos en el puerto B

call                  enciende

movlw B’00111111′  ; Cargamos el valor adecuado a W para limpiar los registros

movwf DISPLAY   ; Limpiamos el display para evitar que los dígitos se repitan

;——————————————————————————

;Unidades de horas

movlw             b’01001111′  ; Activamos el quinto display

movwf            DISPLAY   ; Movemos el dato al puerto B

movf               H_UNI,0   ; Mueve M_UNI al registro W

iorlw               b’01000000′  ; Aplicamos la máscara

movwf            DISPLAY   ; Mostramos en el puerto B

call                  enciende

movlw B’01001111′  ; Cargamos el valor adecuado a W para limpiar los registros

movwf DISPLAY   ; Limpiamos el display para evitar que los dígitos se repitan

;——————————————————————————

;Decenas de horas

movlw             b’01011111′  ; Activamos el sexto display

movwf           DISPLAY   ; Movemos el dato al puerto B

movf              H_DEC,0   ; Mueve M_UNI al registro W

iorlw              b’01010000′  ; Aplicamos la máscara

movwf            DISPLAY   ; Mostramos en el puerto B

call                  enciende

movlw B’01011111′  ; Cargamos el valor adecuado a W para limpiar los registros

movwf DISPLAY   ; Limpiamos el display para evitar que los dígitos se repitan

;——————————————————————————

;Verificar barrido

Movfw                       BARR   ; carga W con el número de barridos

sublw              D’50’   ; Resta 50 para comparar si es igual a 50

btfsc    STATUS, Z  ; Verifica si el resultado fué 0, o sea si BARR=50?

return     ; Se completó el número de barridos

goto    Barrido

;——————————————————————————

ValidarTiempo

movfw H_UNI   ; Carga el registro W con el valor del registro H_UNI

sublw D’4′   ; Resta 4 para verificar si es que el valor de W=4?

btfsc   STATUS, Z  ; Verifica si el resultado fué cero

goto    ValidarHora  ; verificar el siguiente dígito de la hora

return

;——————————————————————————

ValidarHora

movfw H_DEC

sublw             D’2′

btfsc   STATUS, Z    ; Verifica si el resultado fué cero

goto     InicializarRegistros ;

return

;——————————————————————————

InicializarRegistros

clrf      S_UNI

clrf      S_DEC

clrf      M_UNI

clrf      M_DEC

clrf      H_UNI

clrf      H_DEC

return

;——————————————————————————

Temporizador

movlw D’255′  ; w = 50 decimal

movwf PAUSE  ; K = w

Kloop

decfsz PAUSE,f  ; K = K – 1 , salta a la siguiente instrucción si es cero.

goto  Kloop

return

;——————————————————————————
END    ; Fin del programa.

En este programa utilizamos como entrada el Puerto A  del PIC16F84A y como salida el Puerto B el cual va a los display. Por otra parte También se utiliza el circuito 74LS47 el cual tiene el funcionamiento de controlar a los display  para que funcionen correctamente, los pines RB0,RB1, RB2 y RB3 del microcontrolador van conectados a este; los pines del 9-16 de 74LS47 van a cada pin del display. Por otra parte tenemos el Circuito 74LS138 el cual tiene la función de selector de display el cual va a los pines RB4, RB5 y RB6 del microcontrolador. En la programación se establecen espacios de memoria para tener variables donde se almacenen la información de los contadores de tiempo tanto para unidades y decenas de segundos, minutos y horas.

Hasta la próxima.

Gracias a Pedro Soto por el tutorial.

  • hugo

    enviame el archivo en .hex para grabar al pic mi correo es lucas_hd33@hotmail.com

  • alex

    si me puede enviar el archivo .hex para quemarlo al pic… mi correo es early3d@gmail.com .. para probar si en verdad funciona

  • Rogelio

    hola oie me gustarjia saber si me puedes pasar el diagrama para el circuitoes lo uico que me falta mi correo es rojas9515@hotmail.com