Hi OldPrinter, here is de code. It's written in melabs PicBasic3. I think in melabs website must be an online compiler.
'****************************************************************
'* Name : MultiTimer2.BAS *
'* Author : pepona *
'* Notice : Copyright (c) 2014 *
'* : All Rights Reserved *
'* Date : 18/08/2014 *
'* Version : 2.0 *
'* Notes : PIC12F629 / PIC12F675 *
'* : OK-Final *
'****************************************************************
#CONFIG
__CONFIG _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _BODEN_ON & _CP_ON & _CPD_OFF
#ENDCONFIG
DATA @0, "MultiTimer v2.0 - (c) 2014 pepona"
' Datos en eeprom al grabar el micro ( 1 Minuto )
DATA @$70, 1 ' Bandera: 0 = Horas, 1 = Minutos
DATA @$71, 0 ' Minutos programados (HighByte)
DATA @$72, 1 ' Minutos programados (LowByte)
' Calibracion del reloj interno - 4Mhz
DEFINE OSCCAL_1K 1
' Defino retardo para antirrebote = 50ms
DEFINE BUTTON_PAUSE 50
' Defino rutina para el servicio de interrupcion
DEFINE INTHAND Int_TMR1
' Defino variables y constantes
wsave VAR BYTE $20 system ' las variables deben estar en el banco 0 si son
ssave VAR BYTE bank0 system ' usadas en la rutina de interrupcion
psave VAR BYTE bank0 system
Tick VAR BYTE bank0
Bandera_Hor_Min VAR BYTE ' Bandera Horas ó Minutos
Horas CON 0 ' 0 = Horas,
Minutos CON 1 ' 1 = minutos
Retardo_Prog VAR WORD ' Valor del retardo programado (en minutos)
Retardo VAR WORD ' Valor del retardo a temporizar
Conta_Seg VAR BYTE ' Contador de segundos
Conta_Min VAR WORD ' Contador de minutos
X VAR WORD ' Variable de uso general
ButVar VAR BYTE ' Contador para antirrebotes de BUTTON
' Defino puetos
Libre VAR GPIO.0 ' piezzo
Salida VAR GPIO.1
Pulsador VAR GPIO.2
Led_Verde VAR GPIO.4
Led_Rojo VAR GPIO.5
GOTO Inicializar ' Salto la RSI
' Rutina para el servicio de interrupcion en assembler
' El Timer1 genera una interrupcion cada 500ms
' Prescaler 1:8 - Precarga 3036 - Clock 4Mhz.
Asm
Int_TMR1
movwf wsave ; Save W
swapf STATUS,W ; Swap STATUS to W (swap avoids changing STATUS)
clrf STATUS ; Clear STATUS
movwf ssave ; Save swapped STATUS
movf PCLATH,W ; Move PCLATH to W
movwf psave ; Save PCLATH
movlw d'11' ; Precargo el Timer 1 con 3036
movwf TMR1H ; para mantener la interrupcion cada 500ms
movlw d'220' ; (TMR1-highbyte = 11 y TMR1-lowbyte = 220)
movwf TMR1L ;
incf _Tick,F ; Incremento el contador
bcf PIR1,0 ; Limpio bandera de interrupcion
movf psave,W ; restore the state of everything
movwf PCLATH
swapf ssave,W
movwf STATUS
swapf wsave,F
swapf wsave,W
retfie ; Return from interrupt
EndAsm
' -------------------
' --- Inicializar ---
' -------------------
Inicializar:
' Inicializo puertos y registros
GPIO = 0
TRISIO = %00001100 ' GPIO2 y 3 = entradas. el resto salidas
#IF __PROCESSOR__ = "12F675"
ANSEL = %00110000 ' Seteo GPIO todo digital. Solo PIC12F675
#ENDIF
CMCON = 7 ' Apago el comparador analogico
PAUSE 500 ' Espero que todo se estabilice
IF Pulsador = 0 THEN ' Si al encender, el pulsador esta presionado
SOUND GPIO.0,[123,80] ' Genero un "sonidito"
GOTO Programar ' y voy a programar tiempos
ENDIF
READ $70, bandera_hor_min ' Recupero de la eeprom el indicador de horas / minutos programados
READ $71, Retardo_Prog.highbyte ' Recupero el valor del retardo programado (HighByte) en minutos
Read $72, Retardo_Prog.lowbyte ' Recupero el valor del retardo programado (LowByte) en minutos
' -----------------------
' --- Bucle principal ---
' -----------------------
Apagar:
Salida = 0 ' Apago la salida
Led_Verde = 0
Led_Rojo = 0
Retardo = 0
INTCON = $80 ' Apago las interrupciones
SOUND GPIO.0,[123,15,0,35,123,40] ' Hago un "sonidito"
Flash_Led:
IF Bandera_Hor_Min = Horas THEN ' Si se programaron horas -> Flash led rojo
TOGGLE Led_Rojo
ELSE
TOGGLE Led_Verde ' Si se programaron minutos -> Flash led verde
ENDIF
FOR X = 0 TO 9 ' Pruebo el pulsador
BUTTON Pulsador,0,255,0,ButVar,1,Encender ' cada 100ms
PAUSE 100 ' El led destella cada 1000ms
NEXT X ' 10 loops de 100ms c/u
GOTO Flash_Led
GOTO Apagar ' Nunca deberia llegar hasta acá !
Encender:
Salida = 1 ' Activo la salida
IF Bandera_Hor_Min = Horas THEN ' Si se programaron horas
Led_Rojo = 1 ' prendo led rojo
Led_Verde = 0 ' y multiplico el retardo programado * 60
Retardo = Retardo_Prog * 60 ' para convertirlo en horas
ELSE
Led_Verde = 1 ' Si se programaron minutos
Led_Rojo = 0 ' prendo led verde
Retardo = Retardo_Prog ' y cargo el valor a temporizar
ENDIF
SOUND GPIO.0,[123,5] ' Genero un "sonidito"
T1CON = %00110001 ' Enciendo el Timer1, prescaler = 1:8
INTCON = %11000000 ' Habilito todas las interrupciones, y las por perifericos
PIE1 = %00000001 ' Habilita interrupcion por desborde del Timer1
TMR1 = 3036 ' Precargo el Timer1
Tick = 0 ' Limpio contadores
Conta_Seg = 0 '
Conta_Min = 0 '
Comparar:
IF Conta_Min = Retardo THEN Apagar ' Comparo tiempos. Un Tick es generado cada 500ms por Timer1
IF Tick = 2 THEN ' Si los tiempos coinciden apago la salida
Tick = 0 ' Dos Tick = 1 segundo (obvio)
Conta_Seg = Conta_Seg + 1 ' Incremento contador
IF Conta_Seg = 60 THEN ' Cada 60 segundos incremento
conta_Seg = 0 ' el contador de minutos
Conta_Min = Conta_Min + 1
ENDIF
ENDIF
BUTTON Pulsador,0,255,0,ButVar,1,Apagar
GOTO Comparar
' ---------------------------
' --- Fin Bucle principal ---
' ---------------------------
' -------------------------
' --- Programar tiempos ---
' -------------------------
Programar:
INTCON = $80 ' No permito interrupciones
Led_Rojo = 1 : Led_Verde = 1 ' Enciendo led (ambar) = Programacion
IF Pulsador = 0 THEN Programar ' Espero hasta que se libere el pulsador
PAUSE 500
Led_Rojo = 0 : Led_Verde = 0 ' Apago led (ambar)
PAUSE 1000
Retardo_Prog = 0 ' Limpio contador
Prog_Hor_Min:
Led_Verde = 1 : Led_Rojo = 0
FOR X = 0 TO 9
BUTTON Pulsador,0,255,0,ButVar,1,Prog_minutos
PAUSE 100
NEXT X
Led_Rojo = 1 : Led_vERDE = 0
FOR X = 0 TO 9
BUTTON Pulsador,0,255,0,ButVar,1,Prog_Horas
PAUSE 100
NEXT X
GOTO Prog_Hor_Min
Prog_Minutos:
FOR X = 0 TO 6
TOGGLE Led_Verde
PAUSE 100
NEXT X
Prog_Min:
Led_Verde = 1
BUTTON Pulsador,0,255,0,ButVar,0,Prog_min ' Si presiono el pulsador
Led_Verde = 0 ' apago led
SOUND GPIO.0,[123,5] ' Genero un "sonidito"
Retardo_Prog = Retardo_Prog + 1 ' incremento el contador
WRITE $70, Minutos ' marco bandera minutos
WRITE $71, Retardo_Prog.highbyte ' y guardo el valor en la eeprom
WRITE $72, Retardo_prog.lowbyte ' (16 bit)
PAUSE 300 ' Espero para que se libere el pulsador
GOTO Prog_Min ' loop
Prog_Horas:
FOR X = 0 TO 6
TOGGLE Led_Rojo
Pause 100
NEXT X
Prog_Hor:
Led_Rojo = 1
BUTTON Pulsador,0,255,0,ButVar,0,Prog_Hor ' Si presiono el pulsador
Led_Rojo = 0 ' apago led
SOUND GPIO.0,[123,5] ' Genero un "sonidito"
Retardo_Prog = Retardo_Prog + 1 ' incremento contador
WRITE $70, Horas ' Marco bandera horas
WRITE $71, Retardo_Prog.highbyte ' y guardo el valor en la eeprom
WRITE $72, Retardo_prog.lowbyte ' (16 bit)
PAUSE 300
GOTO Prog_Hor
END