#include <16F873A.h>
#use i2c(master, sda=PIN_C1, scl=PIN_C0,force_hw)
#use delay(clock=4000000)
#fuses XT,NOWDT
#byte porta=5 //Definicion de variables del pic
#byte portb=6
#byte portc=7
#byte t1con=0x10
#define e porta,0 //Definicion de bits
#define rs porta,1
#define salida porta,5
int dec_hora,uni_hora,dec_minu,uni_minu,dec_seg,uni_seg;//Definicion de variables
int dia_sem, dec_dia, uni_dia, dec_mes, uni_mes, dec_ano, uni_ano;
int respaldo; //Variable de 8 bit
int i;
int direcc_i2c,dato_i2c;
int con_menu;
int ban_osc;
short ban_05seg;
short ban_tec1;
short ban_tec2;
short ban_tec3;
short ban_tec4;
short ban_osc_seg;
short ban_osc_min;
short ban_osc_hor;
short ban_osc_sem;
short ban_osc_dia;
short ban_osc_mes;
short ban_osc_ano;
byte const dom[5]={"Dom-"}; //Tablas de los dias
byte const lun[5]={"Lun-"};
byte const mar[5]={"Mar-"};
byte const mie[5]={"Mie-"};
byte const jue[5]={"Jue-"};
byte const vie[5]={"Vie-"};
byte const sab[5]={"Sab-"};
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#int_timer1 //Vector de interrupcion por desbordamiento del
void interrupcion_tmr1() //timer 1
{
set_timer1(3036); //Se carga el timer 1 con valor
///////////////////////////////////////
ban_05seg=1;
}
///////////////////////////////////////////////////////////////////////////////
void c_display_8b() //Rutina que envia al LCD una palabra de control o dirección
{
set_tris_b(0b00000000); //Configuracion de entradas y salidas del puerto B
bit_clear(rs);
portb=respaldo;
bit_set(e);
delay_cycles(10);
bit_clear(e);
delay_ms(1);
set_tris_b(0b11110000); //Configuracion de entradas y salidas del puerto B
}
///////////////////////////////////////////////////////////////////////////////
void d_display_8b() //Rutina que envía al LCD un caracter
{
set_tris_b(0b00000000); //Configuracion de entradas y salidas del puerto B
bit_set(rs);
portb=respaldo;
bit_set(e);
delay_cycles(10);
bit_clear(e);
delay_ms(1);
set_tris_b(0b11110000); //Configuracion de entradas y salidas del puerto B
}
///////////////////////////////////////////////////////////////////////////////
void disp_dia() //Rutina que presenta el texto del dia
{
if(ban_osc_sem==1) //Si esta la bandera de oscilacion activa presenta espacios
{
for(i=0;i<=3;i++)
{respaldo=' ';
d_display_8b();}
return;
}
switch(dia_sem) //Seleccion del dia
{
case 1:
for(i=0;i<=3;i++)
{respaldo=dom[i];
d_display_8b();}
break;
case 2:
for(i=0;i<=3;i++)
{respaldo=lun[i];
d_display_8b();}
break;
case 3:
for(i=0;i<=3;i++)
{respaldo=mar[i];
d_display_8b();}
break;
case 4:
for(i=0;i<=3;i++)
{respaldo=mie[i];
d_display_8b();}
break;
case 5:
for(i=0;i<=3;i++)
{respaldo=jue[i];
d_display_8b();}
break;
case 6:
for(i=0;i<=3;i++)
{respaldo=vie[i];
d_display_8b();}
break;
case 7:
for(i=0;i<=3;i++)
{respaldo=sab[i];
d_display_8b();}
break;
}
}
///////////////////////////////////////////////////////////////////////////////
void display()
{
respaldo=0x84; //Dirección donde se escribirá el mensaje
c_display_8b();
respaldo=(dec_hora+48); //Se convierte el decimal a ascii
if(ban_osc_hor==1)
{respaldo=' ';}
d_display_8b();
respaldo=(uni_hora+48); //Se convierte el decimal a ascii
if(ban_osc_hor==1)
{respaldo=' ';}
d_display_8b();
respaldo=':';
d_display_8b();
respaldo=(dec_minu+48); //Se convierte el decimal a ascii
if(ban_osc_min==1)
{respaldo=' ';}
d_display_8b();
respaldo=(uni_minu+48); //Se convierte el decimal a ascii
if(ban_osc_min==1)
{respaldo=' ';}
d_display_8b();
respaldo=':';
d_display_8b();
respaldo=(dec_seg+48); //Se convierte el decimal a ascii
if(ban_osc_seg==1)
{respaldo=' ';}
d_display_8b();
respaldo=(uni_seg+48); //Se convierte el decimal a ascii
if(ban_osc_seg==1)
{respaldo=' ';}
d_display_8b();
///////////////////////////////////////
respaldo=0xc2; //Dirección donde se escribirá el mensaje
c_display_8b();
//respaldo=(dia_sem+48); //Se convierte el decimal a ascii
//d_display_8b();
disp_dia();
respaldo=(dec_dia+48); //Se convierte el decimal a ascii
if(ban_osc_dia==1)
{respaldo=' ';}
d_display_8b();
respaldo=(uni_dia+48); //Se convierte el decimal a ascii
if(ban_osc_dia==1)
{respaldo=' ';}
d_display_8b();
respaldo='/';
d_display_8b();
respaldo=(dec_mes+48); //Se convierte el decimal a ascii
if(ban_osc_mes==1)
{respaldo=' ';}
d_display_8b();
respaldo=(uni_mes+48); //Se convierte el decimal a ascii
if(ban_osc_mes==1)
{respaldo=' ';}
d_display_8b();
respaldo='/';
d_display_8b();
respaldo=(dec_ano+48); //Se convierte el decimal a ascii
if(ban_osc_ano==1)
{respaldo=' ';}
d_display_8b();
respaldo=(uni_ano+48); //Se convierte el decimal a ascii
if(ban_osc_ano==1)
{respaldo=' ';}
d_display_8b();
}
///////////////////////////////////////////////////////////////////////////////
void ini_lcd()
{
//respaldo=0b00101000; //Codigo para display a 4 bits
//call c_display_8b;
respaldo=0b00111000; //Codigo para display a 8 bits
c_display_8b();
respaldo=0b00001100; //Codigo que activa el display
c_display_8b();
respaldo=0b00000110; //Codigo que define el cursor para
c_display_8b(); //Que se desplace hacia la derecha
//respaldo=0b00000111; //Codigo que define el cursor para
//call c_display_8b; //que desplace hacia la izquierda
//todo el mensaje
respaldo=1; //Limpia el display
c_display_8b();
delay_ms(2);
}
///////////////////////////////////////////////////////////////////////////////
void leer_ds1307()
{
if(con_menu!=0)
{return;}
i2c_start(); //Start
i2c_write(0b11010000); //Control
i2c_write(0b00000000); //Direccion
i2c_stop(); //Stop
i2c_start(); //Start
i2c_write(0b11010001); //Control para lectura
respaldo=i2c_read(); //Se lee los segundos
uni_seg=respaldo;
dec_seg=swap(respaldo);
uni_seg=(uni_seg & 0x0f);
dec_seg=(dec_seg & 0x0f);
respaldo=i2c_read(); //Se lee los minutos
uni_minu=respaldo;
dec_minu=swap(respaldo);
uni_minu=(uni_minu & 0x0f);
dec_minu=(dec_minu & 0x0f);
respaldo=i2c_read(); //Se lee las horas
uni_hora=respaldo;
dec_hora=swap(respaldo);
uni_hora=(uni_hora & 0x0f);
dec_hora=(dec_hora & 0x0f);
respaldo=i2c_read(); //Se lee el dia de la semana
dia_sem=respaldo;
respaldo=i2c_read(); //Se lee el dia del mes
uni_dia=respaldo;
dec_dia=swap(respaldo);
uni_dia=(uni_dia & 0x0f);
dec_dia=(dec_dia & 0x0f);
respaldo=i2c_read(); //Se lee el mes
uni_mes=respaldo;
dec_mes=swap(respaldo);
uni_mes=(uni_mes & 0x0f);
dec_mes=(dec_mes & 0x0f);
respaldo=i2c_read(); //Se lee los años
uni_ano=respaldo;
dec_ano=swap(respaldo);
uni_ano=(uni_ano & 0x0f);
dec_ano=(dec_ano & 0x0f);
respaldo=i2c_read();
i2c_stop(); //Stop
}
///////////////////////////////////////////////////////////////////////////////
void conf_ds1307()
{
i2c_start(); //Start
i2c_write(0b11010000); //Control
i2c_write(0b00000000); //Direccion
respaldo=(uni_seg | (swap(dec_seg))); //Se escriben los segundos
i2c_write(respaldo);
respaldo=(uni_minu | (swap(dec_minu))); //Se escriben los minutos
i2c_write(respaldo);
respaldo=(uni_hora | (swap(dec_hora))); //Se escriben las horas
i2c_write(respaldo);
i2c_write(dia_sem);
respaldo=(uni_dia | (swap(dec_dia))); //Se escriben los dias del mes
i2c_write(respaldo);
respaldo=(uni_mes | (swap(dec_mes))); //Se escribe el mes
i2c_write(respaldo);
respaldo=(uni_ano | (swap(dec_ano))); //Se escribe el año
i2c_write(respaldo);
i2c_write(0); //Control de pulsos
i2c_stop(); //Stop
}
///////////////////////////////////////////////////////////////////////////////
void osc_ban_hor() //Rutina de la bandera que hace oscilar las horas
{
if(con_menu==1)
{ban_osc_hor=!ban_osc_hor;}
else
{ban_osc_hor=0;}
}
///////////////////////////////////////////////////////////////////////////////
void osc_ban_min() //Rutina de la bandera que hace oscilar los minutos
{
if(con_menu==2)
{ban_osc_min=!ban_osc_min;}
else
{ban_osc_min=0;}
}
///////////////////////////////////////////////////////////////////////////////
void osc_ban_seg() //Rutina de la bandera que hace oscilar los segundos
{
if(con_menu==3)
{ban_osc_seg=!ban_osc_seg;}
else
{ban_osc_seg=0;}
}
///////////////////////////////////////////////////////////////////////////////
void osc_ban_sem() //Rutina de la bandera que hace oscilar los segundos
{
if(con_menu==4)
{ban_osc_sem=!ban_osc_sem;}
else
{ban_osc_sem=0;}
}
///////////////////////////////////////////////////////////////////////////////
void osc_ban_dia() //Rutina de la bandera que hace oscilar los segundos
{
if(con_menu==5)
{ban_osc_dia=!ban_osc_dia;}
else
{ban_osc_dia=0;}
}
///////////////////////////////////////////////////////////////////////////////
void osc_ban_mes() //Rutina de la bandera que hace oscilar los segundos
{
if(con_menu==6)
{ban_osc_mes=!ban_osc_mes;}
else
{ban_osc_mes=0;}
}
///////////////////////////////////////////////////////////////////////////////
void osc_ban_ano() //Rutina de la bandera que hace oscilar los segundos
{
if(con_menu==7)
{ban_osc_ano=!ban_osc_ano;}
else
{ban_osc_ano=0;}
}
///////////////////////////////////////////////////////////////////////////////
void menu_limpiar() //Menu de la tecla limpiar, dependiendo del contador
{ //menu limpia los registros correspondientes
switch(con_menu)
{
case 1:
uni_hora=0;
dec_hora=0;
break;
case 2:
uni_minu=0;
dec_minu=0;
break;
case 3:
uni_seg=0;
dec_seg=0;
break;
case 4:
dia_sem=1;
break;
case 5:
uni_dia=1;
dec_dia=0;
break;
case 6:
uni_mes=1;
dec_mes=0;
break;
case 7:
uni_ano=0;
dec_ano=0;
break;
}
}
///////////////////////////////////////////////////////////////////////////////
void menu_incre() //Menu de la tecla incre, dependiendo del contador
{ //menu limpia los registros correspondientes
switch(con_menu)
{
case 1:
respaldo=(dec_hora*10)+uni_hora; //Se pasa los decimales a entero
respaldo++; //Se incrementa
if(respaldo==24) //Si horas llego a 24 reinicia
{respaldo=0;}
dec_hora=respaldo/10; //Se pasa nuevamente a BCD
uni_hora=respaldo%10;
break;
case 2:
respaldo=(dec_minu*10)+uni_minu;
respaldo++;
if(respaldo==60)
{respaldo=0;}
dec_minu=respaldo/10;
uni_minu=respaldo%10;
break;
case 3:
respaldo=(dec_seg*10)+uni_seg;
respaldo++;
if(respaldo==60)
{respaldo=0;}
dec_seg=respaldo/10;
uni_seg=respaldo%10;
break;
case 4:
dia_sem++;
if(dia_sem==8)
{dia_sem=1;}10;
break;
case 5:
respaldo=(dec_dia*10)+uni_dia;
respaldo++;
if(respaldo==32)
{respaldo=1;}
dec_dia=respaldo/10;
uni_dia=respaldo%10;
break;
case 6:
respaldo=(dec_mes*10)+uni_mes;
respaldo++;
if(respaldo==13)
{respaldo=1;}
dec_mes=respaldo/10;
uni_mes=respaldo%10;
break;
case 7:
respaldo=(dec_ano*10)+uni_ano;
respaldo++;
if(respaldo==99)
{respaldo=0;}
dec_ano=respaldo/10;
uni_ano=respaldo%10;
break;
}
}
///////////////////////////////////////////////////////////////////////////////
void menu_decre() //Menu de la tecla decre, dependiendo del contador
{ //menu limpia los registros correspondientes
switch(con_menu)
{
case 1:
respaldo=(dec_hora*10)+uni_hora; //Se pasa los decimales a entero
respaldo--; //Se decrementa
if(respaldo==255) //Si horas llego a 00 pasa a 23
{respaldo=23;}
dec_hora=respaldo/10; //Se pasa nuevamente a BCD
uni_hora=respaldo%10;
break;
case 2:
respaldo=(dec_minu*10)+uni_minu;
respaldo--;
if(respaldo==255)
{respaldo=59;}
dec_minu=respaldo/10;
uni_minu=respaldo%10;
break;
case 3:
respaldo=(dec_seg*10)+uni_seg;
respaldo--;
if(respaldo==255)
{respaldo=59;}
dec_seg=respaldo/10;
uni_seg=respaldo%10;
break;
case 4:
dia_sem--;
if(dia_sem==0)
{dia_sem=7;}
break;
case 5:
respaldo=(dec_dia*10)+uni_dia;
respaldo--;
if(respaldo==255)
{respaldo=31;}
dec_dia=respaldo/10;
uni_dia=respaldo%10;
break;
case 6:
respaldo=(dec_mes*10)+uni_mes;
respaldo--;
if(respaldo==255)
{respaldo=12;}
dec_mes=respaldo/10;
uni_mes=respaldo%10;
break;
case 7:
respaldo=(dec_ano*10)+uni_ano;
respaldo--;
if(respaldo==255)
{respaldo=99;}
dec_ano=respaldo/10;
uni_ano=respaldo%10;
break;
}
}
///////////////////////////////////////////////////////////////////////////////
void teclado() //Rutina general de teclado
{
portb=(0xff);
bit_clear(portb,0);
delay_us(100);
//////////////////
if((bit_test(portb,7)==0)&&(ban_tec1==0))
{
ban_tec1=1;
menu_incre();
}
if(bit_test(portb,7)==1)
{
ban_tec1=0;
}
//////////////////
if((bit_test(portb,6)==0)&&(ban_tec2==0))
{
ban_tec2=1;
menu_decre();
}
if(bit_test(portb,6)==1)
{
ban_tec2=0;
}
//////////////////
if((bit_test(portb,5)==0)&&(ban_tec3==0))
{
ban_tec3=1;
menu_limpiar();
}
if(bit_test(portb,5)==1)
{
ban_tec3=0;
}
//////////////////
if((bit_test(portb,4)==0)&&(ban_tec4==0))
{
ban_tec4=1;
con_menu++;
if(con_menu==8)
{
con_menu=0;
respaldo=1;
c_display_8b();
delay_ms(10);
conf_ds1307();
portb=0xfe;
}
}
if(bit_test(portb,4)==1)
{
ban_tec4=0;
}
bit_set(portb,0);
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#zero_ram //Borrado de la memoria ram
#rom 0x2100={4,3,2,1} //Datos pre cargados en la rom
void main() //Rutina principal
{
set_tris_a(0b010000); //Configuracion de entradas y salidas del puerto A
set_tris_b(0b11110000); //Configuracion de entradas y salidas del puerto B
set_tris_c(0b11111111); //Configuracion de entradas y salidas del puerto C
//port_b_pullups(true); //Habilitación de las resistencias pull-ups
t1con=(0b00010101); //Configuracion del tmr1
enable_interrupts(global); //Habilitación de todas las interrupciones
enable_interrupts(int_timer1); //Habilitación de la interrupción del Tmr1
porta=0; //Porta inicia en 0
portb=0; //Portb inicia en 0
portc=0; //Portc inicia en 0
delay_ms(2);
ini_lcd();
leer_ds1307();
display();
while(true) //Rutina general
{
teclado();
if(ban_05seg==1) //Bandera que seactiva cada 0,5 seg
{
ban_05seg=0;
leer_ds1307();
display();
osc_ban_seg();
osc_ban_min();
osc_ban_hor();
osc_ban_sem();
osc_ban_dia();
osc_ban_mes();
osc_ban_ano();
}
}
}
///////////////////////////////////////////////////////////////////////////////