Codigo:
//*******************************************************************
//* Temporizador para insoladora, 4 displays 7 segmentos mux
//* *****************************************************************
//* Por Daniel González, Dic 2005
//********************************************************************
#include <16F876.h>
#fuses XT,NOWDT,PUT,NODEBUG, NOPROTECT,NOBROWNOUT,NOLVP
#use delay (clock=4000000) // 1uS/instrucción
#include <TONES.C> // Zumbador
#include <internal_eeprom.c>
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#byte port_a = 5
#byte port_b = 6
#byte port_c = 7
#define Rele_On output_high(PIN_A5)
#define Rele_Off output_low(PIN_A5)
#define Fan_On output_high(PIN_B1)
#define Fan_Off output_low(PIN_B1)
#define Disp1_On output_high(PIN_A0) // Disp izq
#define Disp1_Off output_low(PIN_A0)
#define Disp2_On output_high(PIN_A1)
#define Disp2_Off output_low(PIN_A1)
#define Disp3_On output_high(PIN_A2)
#define Disp3_Off output_low(PIN_A2)
#define Disp4_On output_high(PIN_A3)
#define Disp4_Off output_low(PIN_A3) // Disp drcha
#define Puls_Amarillo PIN_B7 //+1
#define Puls_Blanco PIN_B6 //-1
#define Puls_Verde PIN_B5 // OK, Aceptar
#define Puls_Rojo PIN_B4 // Siguiente
#define antirebotes 50 // para los delays antirebotes en ms
// Código para los displays 7-segmentos **************************************
#define cero 0x3F
#define uno 0x06
#define dos 0x5B
#define tres 0x4F
#define cuatro 0x66
#define cinco 0x6D
#define seis 0x7D
#define siete 0x07
#define ocho 0x7F
#define nueve 0x6F
#define a7 0x77
#define b7 0x7C
#define c7 0x39
#define d7 0x5E
#define e7 0x79
#define f7 0x71
#define g7 0x3D
#define h7 0x76
#define i7 0x06
#define j7 0x1F
#define l7 0x38
#define n7 0x54
#define o7 0x5C
#define p7 0x73
#define q7 0x67
#define r7 0x50
#define s7 0x6D
#define t7 0x78
#define u7 0x3E
#define punto 0x80
#define espacio 0x00
#define fin_mensaje 0xFF
//****************************************************************************
int1 fin_cuenta;
unsigned int16 i;
unsigned int8 min_x10=0, min=0, seg_x10=0, seg=0;
unsigned int8 contador=125, display=1, caras=1;
//*** carácteres y digitos 7-segmentos ***
// Para el correcto funcionamiento de las librerías, los vectores de mensajes
// deben acabar por "fin_mensaje" (0xFF)
int mensaje[35];
const int numeros[]={cero,uno,dos,tres,cuatro,cinco,seis,siete,ocho,nueve};
const int bienvenida[]={i7,n7,s7,o7,l7,a7,d7,o7,r7,a7,espacio,p7,o7,r7,espacio,
d7,a7,n7,i7,e7,l7,espacio,g7+punto,espacio,espacio,fin_mensaje};
const int calentar[]={c7,a7,l7,e7,n7,t7,a7,n7,d7,o7+punto,espacio,a7,c7,c7,e7,p7,t7,a7,r7,
espacio,p7,a7,r7,a7,espacio,a7,c7,a7,b7,a7,r7+punto,espacio,
espacio,fin_mensaje};
const int una_cara[]={uno,espacio,c7,a7,r7,a7+punto,espacio,espacio,fin_mensaje};
const int dos_caras[]={dos,espacio,c7,a7,r7,a7,s7+punto,espacio,espacio,fin_mensaje};
const int msj_listo[]={l7,i7,s7,t7,o7+punto,punto,punto,espacio,espacio,fin_mensaje};
const int msj_segunda_cara[]={s7,e7,g7,u7,n7,d7,a7,espacio,c7,a7,r7,a7+punto,espacio,espacio,fin_mensaje};
#INT_RTCC
void control_rtcc(void)
{
set_timer0(131);
if(contador == 0)
{
contador = 125;
if(seg > 0)
{
--seg;
}
else
{
if(seg_x10 > 0)
{
--seg_x10;
seg = 9;
}
else
{
if(min > 0)
{
--min;
seg_x10 = 5;
seg = 9;
}
else
{
if(min_x10 > 0)
{
--min_x10;
min = 9;
seg_x10 = 5;
seg = 9;
}
else
{
fin_cuenta = 1;
}
}
}
}
}
--contador;
}
#INT_RB
void control_rb(void)
{
if(!input(Puls_Amarillo)) // +1
{
switch(display)
{
case 1: if(min_x10 < 9) ++min_x10;
else min_x10 = 0;
break;
case 2: if(min < 9) ++min;
else min = 0;
break;
case 3: if(seg_x10 < 5) ++seg_x10;
else seg_x10 = 0;
break;
case 4: if(seg < 9) ++seg;
else seg = 0;
break;
}
while(!input(Puls_Amarillo));
delay_ms(antirebotes);
}
if(!input(Puls_Blanco)) // -1
{
switch(display)
{
case 1: if(min_x10 > 0) --min_x10;
else min_x10 = 9;
break;
case 2: if(min > 0) --min;
else min = 9;
break;
case 3: if(seg_x10 > 0) --seg_x10;
else seg_x10 = 5;
break;
case 4: if(seg > 0) --seg;
else seg = 9;
break;
}
while(!input(Puls_Blanco));
delay_ms(antirebotes);
}
if(!input(Puls_Verde))
{
if(display < 4) ++display;
else display = 1;
while(!input(Puls_Verde))
delay_ms(antirebotes);
}
}
void alarma(void)
{
int1 sw=0;
while(1)
{
generate_tone(3000,100);
if(!input(Puls_Verde) || !input(Puls_Rojo))
{
while(!input(Puls_Verde) || !input(Puls_Rojo))
delay_ms(antirebotes);
return;
}
generate_tone(4000,100);
if(!input(Puls_Verde) || !input(Puls_Rojo))
{
while(!input(Puls_Verde) || !input(Puls_Rojo))
delay_ms(antirebotes);
return;
}
delay_ms(100);
if(!input(Puls_Verde) || !input(Puls_Rojo))
{
while(!input(Puls_Verde) || !input(Puls_Rojo))
delay_ms(antirebotes);
return;
}
}
}
void pinta_disp1(int x)
{
port_c = x;
Disp1_On;
delay_ms(2);
Disp1_Off;
}
void pinta_disp2(int x)
{
port_c = x;
Disp2_On;
delay_ms(2);
Disp2_Off;
}
void pinta_disp3(int x)
{
port_c = x;
Disp3_On;
delay_ms(2);
Disp3_Off;
}
void pinta_disp4(int x)
{
port_c = x;
Disp4_On;
delay_ms(2);
Disp4_Off;
}
// Esta función rota un mensaje en los displays 7 segmentos, el último
// elemento del array deberá ser 0xFF (siendo estos los valores para los displays),
// acepta:
// el 1º un entero, como retardo de la rotacion (recomendado 35)
// 2º si puede devolver el boton amarillo
// 3º si puede devolver el boton blanco
// 4º si puede devolver el boton ver
// y 5º si puede devolver el boton rojo
// y retorna cuando se presiona un pulsador:
// "0" amarillo, "1" blanco, "2" verde y "3" rojo
int rotar_mensaje(int retardo, int1 amarillo, int1 blanco, int1 verde, int1 rojo)
{
//int1 sw_rotar_mensaje=1;
unsigned int8 no_caracteres=0;
unsigned int8 letra1=0, letra2=1, letra3=2, letra4=3; //4 displays, 4 letras mux simultaneamente
while(mensaje[no_caracteres] != 0xFF)
{
++no_caracteres; // cuenta el nº de carácteres a rotar
}
while(1)
{
for(i=0;i<=retardo;++i)
{
pinta_disp1(mensaje[letra1]);
pinta_disp2(mensaje[letra2]);
pinta_disp3(mensaje[letra3]);
pinta_disp4(mensaje[letra4]);
if(!input(Puls_Amarillo) || !input(Puls_Blanco) || !input(Puls_Verde) || !input(Puls_Rojo)) // si pulso algo
{
if(!input(Puls_Amarillo) && amarillo == 1)
{
while(!input(Puls_Amarillo) && blanco == 1); // espera que suelte el pulsador
delay_ms(antirebotes); // antirebote
return 0;
}
if(!input(Puls_Blanco) && blanco == 1)
{
while(!input(Puls_Blanco));
delay_ms(antirebotes);
return 1;
}
if(!input(Puls_Verde) && verde == 1)
{
while(!input(Puls_Verde));
delay_ms(antirebotes);
return 2;
}
if(!input(Puls_Rojo) && rojo == 1)
{
while(!input(Puls_Rojo));
delay_ms(antirebotes);
return 3;
}
}
}
if(letra1 < no_caracteres-1) ++letra1; // (-1) en el array el "0" es el primer elemento
else letra1 = 0;
if(letra2 < no_caracteres-1) ++letra2;
else letra2 = 0;
if(letra3 < no_caracteres-1) ++letra3;
else letra3 = 0;
if(letra4 < no_caracteres-1) ++letra4;
else letra4 = 0;
}
}
void mensaje_inicio(void)
{
unsigned int no_caracteres = 0;
while(bienvenida[no_caracteres] != 0xFF)
{
++no_caracteres; // cuenta el nº de carácteres del array "una_cara"
}
for(i=0;i<=no_caracteres;++i) // Copiamos el array "una_cara" a "mensaje"
// 1er elemento
- --> copiamos inclusive 0xFF (marca final)
{
mensaje = bienvenida;
}
rotar_mensaje(35,0,0,0,1); // Solo acaba al pulsar rojo (GO)
}
void calentar_bombillas(void)
{
unsigned int no_caracteres = 0;
Fan_On;
Rele_On;
while(calentar[no_caracteres] != 0xFF)
{
++no_caracteres; // cuenta el nº de carácteres del array "calentar"
}
for(i=0;i<=no_caracteres;++i) // Copiamos el array "calentar" a "mensaje"
// 1er elemento - --> copiamos inclusive 0xFF (marca final)
{
mensaje = calentar;
}
rotar_mensaje(35,0,0,1,0);
Rele_Off;
}
void selec_tiempo(void)
{
int1 sw = 0;
if(read_eeprom(0) >=0 && read_eeprom(0) <= 9) min_x10 = read_eeprom(0); //comprueba la ultima temporizacion
if(read_eeprom(1) >=0 && read_eeprom(0) <= 9) min = read_eeprom(1);
if(read_eeprom(2) >=0 && read_eeprom(0) <= 5) seg_x10 = read_eeprom(2);
if(read_eeprom(3) >=0 && read_eeprom(0) <= 9) seg = read_eeprom(3);
enable_interrupts(INT_RB);
do
{
for(i=0; i<20;++i)
{
if(display == 1 && sw == 0) pinta_disp1(0);
else pinta_disp1(numeros[min_x10]);
if(display == 2 && sw == 0) pinta_disp2(punto);
else pinta_disp2(numeros[min]+punto);
if(display == 3 && sw == 0) pinta_disp3(0);
else pinta_disp3(numeros[seg_x10]);
if(display == 4 && sw == 0) pinta_disp4(0);
else pinta_disp4(numeros[seg]);
if(!input(Puls_Rojo)) break; // si pulsa rojo, sale sin esperar a terminar el for
}
if(sw == 1) sw = 0;
else sw = 1;
} while(input(Puls_Rojo));
while(!input(Puls_Rojo)); // espera a que suelte
delay_ms(antirebotes); //antirebotes
disable_interrupts(INT_RB);
write_eeprom(0,min_x10); //guarda la temporización en la eeprom
write_eeprom(1,min); //para recuperarla la próxima vez
write_eeprom(2,seg_x10);
write_eeprom(3,seg);
}
void selec_caras(void)
{
int8 pulsador = 0;
unsigned int no_caracteres = 0;
do
{
if(caras == 1)
{
while(una_cara[no_caracteres] != 0xFF)
{
++no_caracteres; // cuenta el nº de carácteres del array "una_cara"
}
for(i=0;i<=no_caracteres;++i) // Copiamos el array "una_cara" a "mensaje"
// 1er elemento - --> copiamos inclusive 0xFF (marca final)
{
mensaje = una_cara;
}
}
if(caras == 2)
{
while(dos_caras[no_caracteres] != 0xFF)
{
++no_caracteres; // cuenta el nº de carácteres del array "dos_caras"
}
for(i=0;i<=no_caracteres;++i) // Copiamos el array "dos_caras" a "mensaje"
// 1er elemento - --> copiamos inclusive 0xFF (marca final)
{
mensaje = dos_caras;
}
}
pulsador = rotar_mensaje(35,1,1,1,0);
if(pulsador == 0 || pulsador == 1)
{
if(caras == 1) caras = 2;
else caras = 1;
}
} while(pulsador != 2 && pulsador != 3); // Al pulsar verde o rojo y devolver un 3 o 4 acepta el nº de caras
}
void listo(void)
{
unsigned int no_caracteres = 0;
while(msj_listo[no_caracteres] != 0xFF)
{
++no_caracteres; // cuenta el nº de carácteres del array "msj_listo"
}
for(i=0;i<=no_caracteres;++i) // Copiamos el array "msj_listo" a "mensaje"
// 1er elemento - --> copiamos inclusive 0xFF (marca final)
{
mensaje = msj_listo;
}
rotar_mensaje(35,0,0,1,0);
}
void segunda_cara(void)
{
unsigned int no_caracteres = 0;
while(msj_segunda_cara[no_caracteres] != 0xFF)
{
++no_caracteres; // cuenta el nº de carácteres del array "msj_segunda_cara"
}
for(i=0;i<=no_caracteres;++i) // Copiamos el array "msj_segunda_cara" a "mensaje"
// 1er elemento - --> copiamos inclusive 0xFF (marca final)
{
mensaje = msj_segunda_cara;
}
rotar_mensaje(35,0,0,1,0);
}
void cuenta(void)
{
fin_cuenta = 0;
min_x10 = read_eeprom(0);
min = read_eeprom(1);
seg_x10 = read_eeprom(2);
seg = read_eeprom(3);
Rele_On;
set_rtcc(131);
enable_interrupts(INT_RTCC);
do
{
if(min_x10 != 0) pinta_disp1(numeros[min_x10]);
if(min_x10 == 0 && min == 0) pinta_disp2(punto);
else pinta_disp2(numeros[min]+punto);
pinta_disp3(numeros[seg_x10]);
pinta_disp4(numeros[seg]);
} while(fin_cuenta == 0);
disable_interrupts(INT_RTCC);
Rele_Off;
}
void main(void)
{
set_tris_a(0x00); // Puerto A todo salidas
port_b_pullups(TRUE); // Resistencias de polarización
set_tris_b(0xFC); // Todo entradas excepto RB0 (zumbador) y RB1, FAN
set_tris_c(0x00); // Puerto C todo salidas
port_a=0;
port_b=0;
port_c=0;
setup_counters(RTCC_INTERNAL, RTCC_DIV_64);
setup_timer_2(T2_DIV_BY_16, 0xFF, 16);
enable_interrupts(GLOBAL);
mensaje_inicio();
calentar_bombillas();
selec_tiempo();
selec_caras();
listo();
cuenta();
if(caras == 2)
{
alarma();
segunda_cara();
cuenta();
Fan_off;
alarma();
}
else // cara == 1
{
Fan_off;
alarma();
}
reset_cpu();
}