#include <16F628A.h>
#FUSES WDT //Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //Reset when brownout detected
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#use delay(clock=4000000,RESTART_WDT)
#use I2C(master, sda=PIN_B3, scl=PIN_A4)
#rom 0x2100={0,185,1}
#include <LCD.C>
// Pinout
#byte PORTA=5
#bit CARA_SUPERIOR=PORTA.0
#bit CARA_INFERIOR=PORTA.1
#bit BUZZER=PORTA.2
#bit SW_ARRIBA=PORTA.7
#bit SW_ABAJO=PORTA.6
#bit SW_INTRO=PORTA.3
// Mensajes
#define STOP 0
#define PAUSA 1
#define MUESTRACARAS 2
#define MSG_MINUTOS 3
#define MSG_SEGUNDOS 4
// Control estado entrada datos
#define ENTRADAMINUTOS 1
#define ENTRADASEGUNDOS 2
// Control tecla pulsada
#define ARRIBA 1
#define ABAJO 2
#define INTRO 3
const char car[32] = {17,17,0,0,0,0,17,17,31,31,0,0,0,0,31,31,31,31,0,0,0,0,17,17,17,17,0,0,0,0,31,31};
int8 OpcionMenu=1, ConfCaras, HayMensaje;
int1 Estado=0, EnPausa=0;
int16 Tiempo, Ticks, TiempoPredefinido;
int8 MinutosPre, SegundosPre,TicksMensaje, EstadoEntradaTiempo;
void CargaConfiguracion() {
TiempoPredefinido = ((int16)read_eeprom(0) * (int16)256) + (int16)read_eeprom(1);
MinutosPre=TiempoPredefinido/60;
SegundosPre=TiempoPredefinido - MinutosPre*60;
ConfCaras=read_eeprom(2);
TicksMensaje=0;
Tiempo=TiempoPredefinido;
EstadoEntradaTiempo=0;
CARA_INFERIOR=0;
CARA_SUPERIOR=0;
HayMensaje=0;
}
void GrabaConfigEeprom() {
Write_Eeprom (0,TiempoPredefinido >> 8); // graba el byte alto
Write_eeprom (1,TiempoPredefinido & 0xFF); // graba el byte bajo
Write_Eeprom (2,ConfCaras);
}
void LCD_DefineCaracter () {
char i;
lcd_send_byte (0,0x40);
for (i=0;i<32;i++) {
lcd_send_byte (1,car[i]);
}
}
void menu() {
lcd_gotoxy(1,2);
switch (OpcionMenu) {
case 1:
if (Estado || EnPausa)
lcd_putc (" Parar ");
else
lcd_putc (" Arrancar ");
break;
case 2:
lcd_putc ("Cfg tiempo ");
break;
case 3:
lcd_putc ("Cfg caras ");
break;
case 4:
if (EnPausa)
lcd_putc (" Continuar ");
else
lcd_putc (" Pausar ");
break;
}
}
void Pitido (int16 Duracion) {
Duracion*=3;
while (Duracion>0) {
BUZZER=1;
delay_us(162);
Duracion--;
BUZZER=0;
delay_us(162);
}
}
void PitidoGrave (int16 Duracion) {
Duracion/=2;
while (Duracion>0) {
BUZZER=1;
delay_us(1000);
Duracion--;
BUZZER=0;
delay_us(1000);
}
}
void ArrancaInsolado() {
Estado=1; // la encendemos
EnPausa=0;
CARA_SUPERIOR=(ConfCaras<3);
CARA_INFERIOR=(ConfCaras!=2);
Ticks = Tiempo * 2;
set_timer1(3036); // hasta 65536 son 62500 ciclos
// 62500 con prescaler de 8 y a 1MHz es medio segundo
// 62500*8/1000000=0,5s.
enable_interrupts(GLOBAL);
OpcionMenu=4;
}
void FinalizaInsolado(int Modo) {
char i;
Estado=0; // la paramos
CARA_SUPERIOR=0;
CARA_INFERIOR=0;
disable_interrupts(GLOBAL);
if (Modo==STOP){
Tiempo=TiempoPredefinido;
EnPausa=0;
if (OpcionMenu==4) // si está parado no puede entrar en la opción 4
OpcionMenu=1;
}
else {
EnPausa=1;
HayMensaje=PAUSA;
}
for (i=0;i<3;i++) {
Pitido (100);
PitidoGrave (200);
}
}
void MuestraTiempo() {
int Minutos, Segundos;
if (EstadoEntradaTiempo) {
lcd_gotoxy(12,2);
Minutos=MinutosPre;
Segundos=SegundosPre;
} else {
lcd_gotoxy(12,1);
Minutos = Tiempo / 60;
Segundos = Tiempo - Minutos*60;
}
printf (lcd_putc,"%2u:%02u",Minutos,Segundos);
}
void MuestraEstado() {
char i;
lcd_gotoxy(1,1);
switch (HayMensaje) {
case 0: // no hay mensaje
for (i=0;i<11;i++)
printf (lcd_putc,"%c",ConfCaras*Estado);
break;
case MUESTRACARAS:
lcd_gotoxy(12,2);
for (i=6;i<11;i++)
printf (lcd_putc,"%c",ConfCaras);
break;
case PAUSA:
printf(lcd_putc," Pausado ");
break;
case MSG_MINUTOS:
printf(lcd_putc,"Minutos....");
lcd_send_byte (0,0x0F);
break;
case MSG_SEGUNDOS:
printf(lcd_putc,"Segundos...");
//lcd_gotoxy(15,1);
break;
}
if (HayMensaje)
TicksMensaje++;
if (TicksMensaje==4) {
HayMensaje=0;
TicksMensaje=0;
}
MuestraTiempo ();
}
void EjecutaOpcion() {
switch (OpcionMenu) {
case 1:
if (Estado || EnPausa) // estaba encendida
FinalizaInsolado(STOP);
else // estaba apagada
ArrancaInsolado();
break;
case 2:
EstadoEntradaTiempo++;
HayMensaje=MSG_MINUTOS;
// lcd_send_byte(0,0xC); // parpadeo
// lcd_gotoxy(1,12);
break;
case 3:
ConfCaras++;
if (ConfCaras==4)
ConfCaras=1;
if (Estado) {
CARA_SUPERIOR=(ConfCaras<3);
CARA_INFERIOR=(ConfCaras!=2);
}
lcd_gotoxy(1,1);
HayMensaje=MUESTRACARAS;
break;
case 4:
if (EnPausa)
ArrancaInsolado();
else
FinalizaInsolado (PAUSA);
break;
}
}
#int_TIMER1
TIMER1_isr()
{
set_timer1(3036); // hasta 65536 son 62500 ciclos
// 62500 con prescaler de 8 y a 1MHz es medio segundo
// 62500*8/1000000=0,5s.
Ticks--;
if (!Ticks) // se acabó
FinalizaInsolado(STOP);
else {
Tiempo=Ticks/2;
}
menu();
MuestraEstado();
}
void ConfiguraTiempo(int Modo) {
switch (EstadoEntradaTiempo) {
case ENTRADAMINUTOS:
switch (Modo) {
case ARRIBA:
MinutosPre++;
if (MinutosPre>99)
MinutosPre=0;
break;
case ABAJO:
if (MinutosPre==0)
MinutosPre=100;
MinutosPre--;
break;
case INTRO:
EstadoEntradaTiempo++;
HayMensaje=MSG_SEGUNDOS;
TicksMensaje=0;
};
break;
case ENTRADASEGUNDOS:
switch (Modo) {
case ARRIBA:
SegundosPre++;
if (SegundosPre>59)
SegundosPre=0;
break;
case ABAJO:
if (SegundosPre==0)
SegundosPre=60;
SegundosPre--;
break;
case INTRO:
EstadoEntradaTiempo=0;
TiempoPredefinido = (int16)MinutosPre*(int16)60+(int16)SegundosPre;
HayMensaje=0;
if (!Estado && !EnPausa)
Tiempo=TiempoPredefinido;
GrabaConfigEeprom();
}
}
//MuestraEstado();
MuestraTiempo();
}
void main()
{
set_tris_a(0b11001000);
setup_timer_0(RTCC_INTERNAL);setup_wdt(WDT_2304MS);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
lcd_init();
enable_interrupts(INT_TIMER1);
disable_interrupts (GLOBAL);
setup_oscillator(OSC_4MHZ);
printf(lcd_putc,"Temporizador v.1\n");
lcd_putc("Nocturno -- 2007");
LCD_DefineCaracter ();
CargaConfiguracion();
delay_ms(500);
pitido(50);
CARA_INFERIOR=0;
CARA_SUPERIOR=0;
menu();
MuestraEstado();
while(1){
// pitido(50);
restart_wdt();
if (!SW_ARRIBA) {// sube en el menú
pitido(20); // antirrebotes
while (!SW_ARRIBA); // esperamos que suelte tecla
if (EstadoEntradaTiempo)
ConfiguraTiempo(ARRIBA);
else {
OpcionMenu--;
if (!OpcionMenu)
OpcionMenu=(3+Estado+EnPausa);
if (OpcionMenu==3)
HayMensaje=MUESTRACARAS;
else
HayMensaje=0;
TicksMensaje=0;
menu();
MuestraEstado();
}
}
if (!SW_ABAJO) {// baja en el menú
pitido(20); // antirrebotes
while (!SW_ABAJO); // esperamos que suelte tecla
if (EstadoEntradaTiempo)
ConfiguraTiempo(ABAJO);
else {
OpcionMenu++;
if (OpcionMenu==(4+Estado+EnPausa))
OpcionMenu=1;
if (OpcionMenu==3)
HayMensaje=MUESTRACARAS;
else
HayMensaje=0;
TicksMensaje=0;
menu();
MuestraEstado();
}
}
if (!SW_INTRO) {// acepta opción
pitido(20); // antirrebotes
while (!SW_INTRO); // esperamos que suelte tecla
if (EstadoEntradaTiempo) {
ConfiguraTiempo(INTRO);
} else {
HayMensaje=0;
TicksMensaje=0;
EjecutaOpcion();
}
menu();
MuestraEstado();
}
}
}