[COLOR=#666666][I]; Este programa lo único que hace es contar desde 20 minutos hasta 0,[/I][/COLOR]
[COLOR=#666666][I]; es decir, no puede ajustarse, a menos que se edite el programa.[/I][/COLOR]
[B]LIST[/B] P=16F84A
[B]INCLUDE[/B] [COLOR=#7F007F]"P16F84A.INC"[/COLOR]
CBLOCK [COLOR=#0000FF]0CH[/COLOR]
Reg_50ms[COLOR=#339933],[/COLOR] Tiempo_H[COLOR=#339933],[/COLOR] Tiempo_L
ENDC
[COLOR=#666666][I]; Ojo: En vez de usar una variable llamada TIEMPO debes usar dos:[/I][/COLOR]
[COLOR=#666666][I]; - Una para almacenar el byte alto de la cantidad de segundos,[/I][/COLOR]
[COLOR=#666666][I]; llamada Tiempo_H.[/I][/COLOR]
[COLOR=#666666][I]; - Una para almacenar el byte bajo de la cantidad de segundos,[/I][/COLOR]
[COLOR=#666666][I]; llamada Tiempo_L.[/I][/COLOR]
[COLOR=#666666][I];[/I][/COLOR]
[COLOR=#666666][I]; ¿Por qué 2 bytes? Pues porque para temporizar hasta 20 minutos se[/I][/COLOR]
[COLOR=#666666][I]; requieren hasta 20 x 60 = 1200 segundos. La cantidad 1200 se representa[/I][/COLOR]
[COLOR=#666666][I]; con mínimo 2 bytes.[/I][/COLOR]
#DEFINE Alarma PORTB[COLOR=#339933],[/COLOR][COLOR=#0000FF]0[/COLOR]
[B]ORG[/B] [COLOR=#0000FF]00H[/COLOR]
[B]goto[/B] Inicio
[B]ORG[/B] [COLOR=#0000FF]04H[/COLOR]
[B]goto[/B] Interrupcion
Inicio
bcf Alarma
[COLOR=#00007F][B]bsf[/B][/COLOR] STATUS[COLOR=#339933],[/COLOR]RP0
movlw b[COLOR=#7F007F]'11000111'[/COLOR]
movwf OPTION_REG
bcf Alarma
bcf STATUS[COLOR=#339933],[/COLOR]RP0
[COLOR=#00007F][B]call[/B][/COLOR] LCD_Inicializa
movlw [B]high[/B][COLOR=#009900][B]([/B][/COLOR][COLOR=#0000FF].1200[/COLOR][COLOR=#009900][B])[/B][/COLOR] [COLOR=#666666][I]; Carga el byte alto del tiempo en la variable[/I][/COLOR]
movwf Tiempo_H [COLOR=#666666][I]; Tiempo_H.[/I][/COLOR]
movlw [B]low[/B][COLOR=#009900][B]([/B][/COLOR][COLOR=#0000FF].1200[/COLOR][COLOR=#009900][B])[/B][/COLOR] [COLOR=#666666][I]; Carga el byte bajo del tiempo en la variable[/I][/COLOR]
movwf Tiempo_L [COLOR=#666666][I]; Tiempo_L.[/I][/COLOR]
[COLOR=#00007F][B]call[/B][/COLOR] Visualiza_Tiempo [COLOR=#666666][I]; Visualiza el tiempo en la pantalla.[/I][/COLOR]
movlw [COLOR=#0000FF].20[/COLOR] [COLOR=#666666][I]; Se prepara para temporizar.[/I][/COLOR]
movwf Reg_50ms
movlw [COLOR=#0000FF].60[/COLOR]
movwf TMR0
bcf INTCON[COLOR=#339933],[/COLOR]T0IF
[COLOR=#00007F][B]bsf[/B][/COLOR] INTCON[COLOR=#339933],[/COLOR]T0IE
[COLOR=#00007F][B]bsf[/B][/COLOR] INTCON[COLOR=#339933],[/COLOR]GIE [COLOR=#666666][I]; Habilita interrupciones.[/I][/COLOR]
Ciclo
[B]goto[/B] Ciclo
[COLOR=#666666][I]; Rutina de servicio a la interrupción.[/I][/COLOR]
Interrupcion
movlw [COLOR=#0000FF].60[/COLOR]
movwf TMR0 [COLOR=#666666][I]; Recarga el TMR0.[/I][/COLOR]
decfsz Reg_50ms [COLOR=#666666][I]; ¿Ya pasó 1 segundo?[/I][/COLOR]
[B]goto[/B] Fin_Interrupcion
movlw [COLOR=#0000FF].20[/COLOR] [COLOR=#666666][I]; Sí, entonces recarga el registro.[/I][/COLOR]
movwf Reg_50ms
[COLOR=#666666][I]; Ojo: Aquí se va a realizar el decremento del tiempo, pero[/I][/COLOR]
[COLOR=#666666][I]; es un decremento de 16 bits.[/I][/COLOR]
decf Tiempo_L[COLOR=#339933],[/COLOR]F [COLOR=#666666][I]; Decrementa en 1 el byte bajo.[/I][/COLOR]
movlw [COLOR=#0000FF]0xFF[/COLOR]
subwf Tiempo_L[COLOR=#339933],[/COLOR]W
btfsc STATUS[COLOR=#339933],[/COLOR]Z [COLOR=#666666][I]; ¿El resultado es negativo?[/I][/COLOR]
decf Tiempo_H[COLOR=#339933],[/COLOR]F [COLOR=#666666][I]; Sí, entonces decrementa en 1 el byte alto.[/I][/COLOR]
[COLOR=#00007F][B]call[/B][/COLOR] Visualiza_Tiempo [COLOR=#666666][I]; Visualiza el tiempo en la pantalla.[/I][/COLOR]
[COLOR=#666666][I]; Atención: Anteriormente sólo decrementamos el tiempo, pero NO[/I][/COLOR]
[COLOR=#666666][I]; verificamos si llegó al valor 0. Aquí se realiza esto. Si los[/I][/COLOR]
[COLOR=#666666][I]; dos bytes del tiempo valen 0 significa que el tiempo terminó.[/I][/COLOR]
movf Tiempo_H[COLOR=#339933],[/COLOR]F
btfss STATUS[COLOR=#339933],[/COLOR]Z [COLOR=#666666][I]; ¿Vale 0 el byte alto?[/I][/COLOR]
[B]goto[/B] Fin_Interrupcion [COLOR=#666666][I]; No, pues sale de la interrupción.[/I][/COLOR]
movf Tiempo_L[COLOR=#339933],[/COLOR]F
btfss STATUS[COLOR=#339933],[/COLOR]Z [COLOR=#666666][I]; ¿Vale 0 el byte bajo?[/I][/COLOR]
[B]goto[/B] Fin_Interrupcion [COLOR=#666666][I]; No, pues sale de la interrupción.[/I][/COLOR]
[COLOR=#666666][I]; Llegamos aquí porque los dos bytes valen 0, es decir, el tiempo terminó.[/I][/COLOR]
[COLOR=#00007F][B]bsf[/B][/COLOR] Alarma [COLOR=#666666][I]; Activa la alarma[/I][/COLOR]
[COLOR=#00007F][B]call[/B][/COLOR] Retardo_2s [COLOR=#666666][I]; durante un corto tiempo.[/I][/COLOR]
bcf Alarma
bcf INTCON[COLOR=#339933],[/COLOR]T0IE [COLOR=#666666][I]; Prohibe la interrupción del TMR0[/I][/COLOR]
[COLOR=#666666][I]; Para que detener el conteo.[/I][/COLOR]
Fin_Interrupcion
bcf INTCON[COLOR=#339933],[/COLOR]T0IF [COLOR=#666666][I]; Borra la bandera de interrupción[/I][/COLOR]
retfie [COLOR=#666666][I]; y retorna.[/I][/COLOR]
[COLOR=#666666][I]; Subrutina Visualiza_Tiempo.[/I][/COLOR]
[COLOR=#666666][I];[/I][/COLOR]
[COLOR=#666666][I]; Observa que antes sólo se hacía:[/I][/COLOR]
[COLOR=#666666][I];[/I][/COLOR]
[COLOR=#666666][I]; movf TIEMPO,W[/I][/COLOR]
[COLOR=#666666][I]; call MinutosSegundos[/I][/COLOR]
[COLOR=#666666][I];[/I][/COLOR]
[COLOR=#666666][I]; Pues ahora el tiempo es de dos bytes y debe hacerse como sigue.[/I][/COLOR]
Visualiza_Tiempo
[COLOR=#00007F][B]call[/B][/COLOR] LCD_Borra
[COLOR=#666666][I]; Debes hacerlo así para que funcione. La rutina MinutosSegundos[/I][/COLOR]
[COLOR=#666666][I]; modificada maneja los registros MinutosSegundos_TiempoH y[/I][/COLOR]
[COLOR=#666666][I]; MinutosSegundos_TiempoL.[/I][/COLOR]
movf Tiempo_H[COLOR=#339933],[/COLOR]W
movwf MinutosSegundos_TiempoH
movf Tiempo_L[COLOR=#339933],[/COLOR]W
movwf MinutosSegundos_TiempoL
[COLOR=#00007F][B]call[/B][/COLOR] MinutosSegundos [COLOR=#666666][I]; Convierte de segundos a minutos y[/I][/COLOR]
[COLOR=#666666][I]; segundos.[/I][/COLOR]
movf Minutos[COLOR=#339933],[/COLOR]W
[COLOR=#00007F][B]call[/B][/COLOR] BIN_BCD
[COLOR=#00007F][B]call[/B][/COLOR] LCD_ByteCompleto
movlw [COLOR=#7F007F]':'[/COLOR]
[COLOR=#00007F][B]call[/B][/COLOR] LCD_Caracter
movf Segundos[COLOR=#339933],[/COLOR]W
[COLOR=#00007F][B]call[/B][/COLOR] BIN_BCD
[COLOR=#00007F][B]call[/B][/COLOR] LCD_ByteCompleto
return
[COLOR=#666666][I]; La rutina BIN_BCD yo la hice, pero puedes usar la que tú tienes.[/I][/COLOR]
[COLOR=#666666][I]; Lo que pasa es que la hice porque no la tengo.[/I][/COLOR]
[COLOR=#666666][I]; Insisto, puedes usar la que tú tienes.[/I][/COLOR]
BIN_BCD
CBLOCK
Unidades[COLOR=#339933],[/COLOR] Decenas[COLOR=#339933],[/COLOR] Centenas
ENDC
movwf Unidades
clrf Decenas
clrf Centenas
BIN_BCD_Resta10
movlw [COLOR=#0000FF].10[/COLOR]
subwf Unidades[COLOR=#339933],[/COLOR]F
btfss STATUS[COLOR=#339933],[/COLOR][B]C[/B]
[B]goto[/B] Fin_BIN_BCD
incf Decenas[COLOR=#339933],[/COLOR]F
movlw [COLOR=#0000FF].10[/COLOR]
subwf Decenas[COLOR=#339933],[/COLOR]W
btfss STATUS[COLOR=#339933],[/COLOR][B]C[/B]
[B]goto[/B] BIN_BCD_Resta10
clrf Decenas
incf Centenas[COLOR=#339933],[/COLOR]F
[B]goto[/B] BIN_BCD_Resta10
Fin_BIN_BCD
movlw [COLOR=#0000FF].10[/COLOR]
addwf Unidades[COLOR=#339933],[/COLOR]F
movf Unidades[COLOR=#339933],[/COLOR]W
swapf Decenas[COLOR=#339933],[/COLOR]F
iorwf Decenas[COLOR=#339933],[/COLOR]W
swapf Decenas[COLOR=#339933],[/COLOR]F
return
[COLOR=#666666][I]; Aquí está la subrutina MinutosSegundos modificada para manejar[/I][/COLOR]
[COLOR=#666666][I]; números de 2 bytes. Ésta sí úsala en lugar de la otra.[/I][/COLOR]
MinutosSegundos
CBLOCK
Segundos[COLOR=#339933],[/COLOR] Minutos
MinutosSegundos_TiempoH
MinutosSegundos_TiempoL
ENDC
clrf Minutos [COLOR=#666666][I]; Borra los minutos.[/I][/COLOR]
[COLOR=#666666][I]; Le resta 60 al tiempo que está almacenado en las variables[/I][/COLOR]
[COLOR=#666666][I]; MinutosSegundos_TiempoH y MinutosSegundos_TiempoL.[/I][/COLOR]
MinutosSegundos_Resta60
movlw [COLOR=#0000FF].60[/COLOR]
subwf MinutosSegundos_TiempoL[COLOR=#339933],[/COLOR]F [COLOR=#666666][I]; Resta 60 del byte bajo.[/I][/COLOR]
btfss STATUS[COLOR=#339933],[/COLOR][B]C[/B] [COLOR=#666666][I]; ¿Es negativo?[/I][/COLOR]
decf MinutosSegundos_TiempoH[COLOR=#339933],[/COLOR]F [COLOR=#666666][I]; Sí, entonces decrementa en[/I][/COLOR]
[COLOR=#666666][I]; 1 el byte alto.[/I][/COLOR]
btfsc MinutosSegundos_TiempoH[COLOR=#339933],[/COLOR][COLOR=#0000FF]7[/COLOR] [COLOR=#666666][I]; ¿El resultado es negativo?[/I][/COLOR]
[B]goto[/B] Fin_MinutosSegundos [COLOR=#666666][I]; Sí, pues ya terminamos de convertir.[/I][/COLOR]
incf Minutos[COLOR=#339933],[/COLOR]F [COLOR=#666666][I]; Incrementa en 1 la cantidad de minutos.[/I][/COLOR]
[B]goto[/B] MinutosSegundos_Resta60 [COLOR=#666666][I]; Sigue revisando si hay más minutos.[/I][/COLOR]
Fin_MinutosSegundos
movlw [COLOR=#0000FF].60[/COLOR] [COLOR=#666666][I]; Le suma 60 a la cantidad de tiempo ya que [/I][/COLOR]
[COLOR=#666666][I]; previamente se le restó 60 y el resultado[/I][/COLOR]
[COLOR=#666666][I]; fue negativo.[/I][/COLOR]
addwf MinutosSegundos_TiempoL[COLOR=#339933],[/COLOR]W
movwf Segundos
return
[B]INCLUDE[/B] [COLOR=#7F007F]"LCD_4BIT.INC"[/COLOR]
[B]INCLUDE[/B] [COLOR=#7F007F]"RETARDOS.INC"[/COLOR]
[B]END[/B]