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 10-Dec-2015

239 views

Category:

Documents


2 download

DESCRIPTION

electronica

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 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'244' ;

Constante para cuenta de horas

HORS_12H equ D'243' ;

Constante para cuenta de horas

ADJMIN 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 tiempo

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

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

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

Page 5: Reloj de 12 Horas

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

************************************fra

c_sec equ H'0C' ;

Fracciones de segundo (1/244)

segundos equ H'0D' ;

Segundos

Page 6: Reloj de 12 Horas

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

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