reloj de 12 horas

36
;************************************** *********************** ; RELOJ DE 12 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

Upload: irving-martinez

Post on 12-Apr-2017

51 views

Category:

Engineering


0 download

TRANSCRIPT

Page 1: Reloj de 12 horas

;*************************************************************; RELOJ DE 12 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

Page 2: Reloj de 12 horas

;**************************************************************;; Valores de constantes ***************************************FRAC_INI equ D'12' ; Constante para inicio cuenta de fracciones de segundoSEGS_INI equ D'196' ; Constante para inicio cuenta de segundosMINS_INI equ D'196' ; Constante para inicio cuenta de minutosHORS_INI equ D'244' ; Constante para cuenta de horasHORS_12H equ D'243' ; Constante para cuenta de horasADJMIN equ D'9' ; Número de "frac_sec" que se necesita sumar cada minuto ; para ajustar el tiempo

Page 3: Reloj de 12 horas

ADJHOR equ D'34' ; Número de "frac_sec" que se necesita restar cada hora ; para ajustar el tiempoADJDIA equ D'3' ; Número de "frac_sec" que se necesita sumar cada 12 horas ; para ajustar el tiempo; Activación de RB1-3 para las entradas de los pulsadoresPULSADOR 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

Page 4: Reloj de 12 horas

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 activadoDSPOFF equ B'11111111' ; Displays apagados (PORTA) ; gfedcbapCERO equ H'7E' ; 01111110UNO equ H'0C' ; 00001100DOS equ H'B6' ; 10110110TRES equ H'9E' ; 10011110CUATRO equ H'CC' ; 11001100

Page 5: Reloj de 12 horas

CINCO equ H'DA' ; 11011010SEIS equ H'FA' ; 11111010SIETE equ H'0E' ; 00001110OCHO equ H'FE' ; 11111110NUEVE equ H'DE' ; 11011110SEGM_OFF equ H'00' ; Todos los segmentos apagados. Separador entre horas ; y minutos apagado (RB0).; Posición de memoria de variables ************************************frac_sec equ H'0C' ; Fracciones de segundo (1/244)segundos equ H'0D' ; Segundos

Page 6: Reloj de 12 horas

minutos equ H'0E' ; Minutoshoras equ H'0F' ; Horasconta1 equ H'10' ; Variable 1 para bucle contador

display equ H'11' ; Indicador de display que debe actualizarsedigito1 equ H'12' ; Display unidad de minuto / unidad de segundodigito2 equ H'13' ; Display decena de minuto / decena de segundodigito3 equ H'14' ; Display unidad de horadigito4 equ H'15' ; Display decena de horabanderas equ H'16' ; Banderas; 3-CHG, 4-PSEG, 5-PMIN, 6-PHOR, 7-P_ON

Page 7: Reloj de 12 horas

;************************************************************** 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

Page 8: Reloj de 12 horas

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

Page 9: Reloj de 12 horas

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'

Page 10: Reloj de 12 horas

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 movlw DOS movwf digito3 ; Aparecerá un "2" en el display unidad de hora movlw UNO movwf digito4 ; Aparecerá un "1" en el display decena de hora movlw B'00000000'

Page 11: Reloj de 12 horas

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 D'255' movwf horas ; Las horas comienzan con 12 por lo que "horas" ha de ser 255

;**************************************************************PRINCIPAL ; Rutina principal cíclica;**************************************************************;; Esperar al desbordamiento de TMR0

Page 12: Reloj de 12 horas

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

Page 13: Reloj de 12 horas

; 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

Page 14: Reloj de 12 horas

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

Page 15: Reloj de 12 horas

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

Page 16: Reloj de 12 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

Page 17: Reloj de 12 horas

; Ajustes cada minuto, hora y 12 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

Page 18: Reloj de 12 horas

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

Page 19: Reloj de 12 horas

movwf horas ; de "horas" para la próxima vuelta movlw ADJDIA ; Se resta 3 a "frac_sec" cada 12 horas para los ajustes de tiempo subwf frac_sec,F ; Cada 12 horas se añadirán 3 "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

Page 20: Reloj de 12 horas

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

Page 21: Reloj de 12 horas

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_12H 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

Page 22: Reloj de 12 horas

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)

Page 23: Reloj de 12 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

Page 24: Reloj de 12 horas

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

Page 25: Reloj de 12 horas

; 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

Page 26: Reloj de 12 horas

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)

Page 27: Reloj de 12 horas

; movlw CERO; subwf digito4,W; btfss STATUS,Z; goto BORRAR_CERO_SEG; movlw SEGM_OFF; 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 movwf digito3 ; mostrarán los segundos. movwf digito4

DISPLAY_PUL ; Se borran los bits de flag para actualizar su estado

Page 28: Reloj de 12 horas

; 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

Page 29: Reloj de 12 horas

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.

Page 30: Reloj de 12 horas

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

Page 31: Reloj de 12 horas

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'

Page 32: Reloj de 12 horas

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

Page 33: Reloj de 12 horas

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)

Page 34: Reloj de 12 horas

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

Page 35: Reloj de 12 horas

; 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

Page 36: Reloj de 12 horas

goto PRINCIPAL ; Volver a realizar todo el proceso

END