#include <p18f4550.h>
#include <delays.h>
#include <adc.h> //Librería para conversor ADC
#include <stdio.h>
#include <delays.h>
#include <i2c.h>
#include <portb.h>
#include "lcd_c18.h"
#pragma config FOSC=HS, PWRT=ON, MCLRE=ON, LVP=OFF, WDT=OFF
#define Pulsador1 PORTBbits.RB3
#define Pulsador2 PORTBbits.RB5
#define Pulsador3 PORTBbits.RB6
#define Pulsador4 PORTBbits.RB4
#define Alterna1 PORTCbits.RC0 //Salida de 220v nº1
#define Alterna2 PORTCbits.RC1 //Salida de 220v nº2
#define Alterna3 PORTCbits.RC2 //Salida de 220v nº3
#define PinA PORTDbits.RD2 //Pines de salida
#define PinB PORTDbits.RD3 //para manejo
#define PinC PORTCbits.RC6 //de motor
#define PinD PORTCbits.RC7 //paso a paso
#define LUCES PORTDbits.RD1 //Pin de salida para luces
#define uint8 unsigned char
void leer_conversor(void); // Prototipo de función que mide la temperatura en el channel 4
void leer_conversor2(void); //Prototipo de funcion que mide la temperatura en el channel 2
void Mostrar_Conversor(void); // Prototipo de la función que muestra la lectura.
void Motor(void); //Prototipo de funcion que mueve el motor paso a paso unipolar
void Configuracion_inicial(int Cont_config); //Prototipo de la funcion que muestra la configuracion inicial en pantalla
void Limpiar_Pantalla(void); //Prototipo de la funcion que limpia la pantalla del display
void ByteWriteI2C( unsigned char ByteControl, unsigned char Direccion, unsigned char Dato);
unsigned char ByteReadI2C( unsigned char ByteControl, unsigned char Direccion );
void Ajustar_Dato(unsigned char dato); // Ajusta datos del DS1307
void Un_Segundo(void); // Prototipo de la Interrupción
void ConfigHoraFecha(void);
uint8 DecimaltoBCD(uint8 DecimalByte);
uint8 BCDtoDecimal(uint8 BCDByte);
char Nada[16]={0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20};
char Luces=0;
int Cont_config=1;
int VAlterna1=0;
int VAlterna2=0;
int VAlterna3=0;
unsigned char HoraLuz, MinLuz, HoraLuzBCD, MinLuzBCD, HoraALuz, MinALuz, HoraALuzBCD, MinALuzBCD, HoraBCD, MinBCD; //Variable de la hora de encendido de las luces
unsigned char HoraConfig, MinConfig, DiaConfig, MesConfig, AnioConfig;
unsigned char HoraConfigBCD, MinConfigBCD, DiaConfigBCD, MesConfigBCD, AnioConfigBCD;
unsigned char unidad=0, decena=0, centena=0;
unsigned int conversion=0;
unsigned char muestras =0;
unsigned int M0=0;
unsigned char unidad2=0, decena2=0, centena2=0;
unsigned int conversion2=0;
unsigned char muestras2 =0;
unsigned int M02=0;
unsigned int TempReg = 25;
volatile bandera =0; // Variable usada en la Interrupción
unsigned char Unidadrtc, Decenartc; // Variables del Programa
#define chip 0xD0 // Valor de Chip para el DS1307
//**** Vector de Inte 0x0008 modo compatibilidad de interrupciones 18FXXXX ****
////////////////////////////////////////////////////////////////////////////////
#pragma code prioridad_nomal = 0X0008
void interrupcion_normal (void)
{
_asm goto Un_Segundo _endasm // Salta al servicio de Inte.
}
#pragma code // Fin de la interrupción
//Rutina de Interrupción
#pragma interrupt Un_Segundo
void Un_Segundo(void)
{
if(INTCON3bits.INT2IF) // Pregunta por bandera de INT2
{
bandera =1; // Marca para actualizar el calendario
INTCON3bits.INT2IF = 0; // Limpia bandera
}
}
/************* FUNCIÓN QUE MUESTRA LOS DATOS EN EL DISPLAY ********************/
void Mostrar_Conversor(void){
lcd_gotoxy(1,1);
lcd_putrs(" Temp. ");
Delay10TCYx(150);
lcd_gotoxy(2,2);
printf("%u",decena);
Delay10TCYx(150);
lcd_gotoxy(3,2);
printf("%u",unidad);
Delay10TCYx(150);
lcd_gotoxy(4,2);
lcd_putrs("ºc ");
Delay10TCYx(150);
}
/*************** FUNCIÓN QUE LEE EL CONVERSOR A/D *****************************/
void leer_conversor(void){
unsigned resto=0;
ConvertADC(); // Comienza la conversión
while (BusyADC()); // Espera que finalice la conversión
M0 += ReadADC()>>2; // Convierte a 8 Bit ?s y acumula en M0
if(muestras++ == 49){
conversion = M0/50; // Se busca el promedio de las 50 muestras
centena = conversion / 100; // Se define la centena (No se usa)
resto = conversion % 100; // Recupera el resto de la div.
decena = resto /10; // Se define la decena
unidad = resto % 10; // El resto es la unidad
M0 = 0;
muestras =0;
}
}
void leer_conversor2(void){
unsigned resto2=0;
ConvertADC(); // Comienza la conversión
while (BusyADC()); // Espera que finalice la conversión
M02 += ReadADC()>>2; // Convierte a 8 Bit ?s y acumula en M02
if(muestras2++ == 49){
conversion2 = M02/50; // Se busca el promedio de las 50 muestras
centena2 = conversion2 / 100; // Se define la centena (No se usa)
resto2 = conversion2 % 100; // Recupera el resto de la div.
decena2 = resto2 /10; // Se define la decena
unidad2 = resto2 % 10; // El resto es la unidad
M02 = 0;
muestras2 =0;
}
}
void main(void){
int Cont_config=0;
TRISB=0X7F;
TRISC=0x00;
TRISD=0x08;
LATBbits.LATB7=0;
LATDbits.LATD0=0;
LATDbits.LATD1=0;
OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_2_TAD, ADC_CH4 &
ADC_REF_VREFPLUS_VSS & ADC_INT_OFF,ADC_5ANA);
Delay10TCYx(20);
lcd_init();
OpenI2C(MASTER,SLEW_OFF); // Master
SSPADD = 49; // 100KHz para 20MHz
Delay10KTCYx(250);
MinConfig=BCDtoDecimal(ByteReadI2C(chip,1)); // Ajusta Minutos
HoraConfig=BCDtoDecimal(ByteReadI2C(chip,2));
DiaConfig=BCDtoDecimal(ByteReadI2C(chip,4));
MesConfig=BCDtoDecimal(ByteReadI2C(chip,5));
AnioConfig=BCDtoDecimal(ByteReadI2C(chip,6));
ByteWriteI2C(chip,0,0x50); // Ajusta Segundos
OpenRB2INT(PORTB_CHANGE_INT_ON & FALLING_EDGE_INT & PORTB_PULLUPS_OFF);
RCONbits.IPEN=0; // No hay prioridades de interrupciónes
INTCONbits.GIEH = 1; // Habilitador general de interrupciónes activo
ByteWriteI2C(chip,0x07,0X90); // Registro de Control (1Hz pin 7)
stdout = _H_USER;
lcd_gotoxy(2,1);
lcd_putrs("Controlador");
Delay10TCYx(150);
lcd_gotoxy(3,2);
lcd_putrs("Pecera");
Delay10KTCYx(255);
Delay10KTCYx(255);
while(1){
if(bandera){ // Bandera puesta en la interrupción
lcd_gotoxy(9,1); // Coloca el cursor en la primera línea
Ajustar_Dato(ByteReadI2C(chip,4)); // Lee el Día
lcd_putrs("/"); // Barra separadora xx/xx/xx
Ajustar_Dato(ByteReadI2C(chip,5)); // Lee el Mes
lcd_putrs("/");
Ajustar_Dato(ByteReadI2C(chip,6)); // Lee el Año
lcd_gotoxy(9,2); // Cambia la línea en el LCD
Ajustar_Dato(ByteReadI2C(chip,2)); // Lee Hora
lcd_putrs(":"); // Puntos separadores xx:xx:xx
Ajustar_Dato(ByteReadI2C(chip,1)); // Lee Minutos
MinBCD=ByteReadI2C(chip,1);
HoraBCD=ByteReadI2C(chip,2);
bandera =0; // Borra la bandera para el próximo segundo
}
if(Pulsador3==1){
Delay10KTCYx(25);
if(Pulsador3==1){
while(Cont_config<6){
Configuracion_inicial(Cont_config);
Delay10KTCYx(255);
Limpiar_Pantalla();
++Cont_config;
}
}
Cont_config=1;
Delay10TCYx(150);
}
if(Pulsador1==1){
Delay10KTCYx(150);
if(Pulsador1==1){
ConfigHoraFecha();
}
}
Mostrar_Conversor();
Delay10TCYx(150);
if(conversion > TempReg){ //Si la temperatura leida es mayor a la referencia se enciende el RB7 y apaga RB6
LATBbits.LATB7=1;
LATDbits.LATD0=0;
}else if(conversion == TempReg){ //Si la temperatura leida es igual a la referencia se apagan las dos salidas
LATBbits.LATB7=0;
LATDbits.LATD0=0;
}else if(conversion < TempReg){ //Si la temperatura es menor a la referencia, se enciende RB6 y se apaga RB7
LATBbits.LATB7=0;
LATDbits.LATD0=1;
}
if(HoraBCD==HoraLuzBCD && MinBCD>=MinLuzBCD && HoraBCD<=HoraALuzBCD && MinBCD<MinALuzBCD && LUCES==0){
LUCES=1;
}else if(HoraBCD>=HoraLuzBCD && MinBCD>=MinLuzBCD && HoraBCD<HoraALuzBCD && MinBCD<MinALuzBCD && LUCES==1){
LUCES=1;
}else if(HoraBCD==HoraALuzBCD && MinBCD>=MinALuzBCD && LUCES==1){
LUCES=0;
}else if(HoraBCD>=HoraALuzBCD && MinBCD>=MinALuzBCD && LUCES==0){
LUCES=0;
}
SetChanADC(ADC_CH4); //Elijo el canal 4 para el primer sensor, sumergido en la pecera
leer_conversor();
SetChanADC(ADC_CH2); //Cambio al canal 2 para leer el segundo sensor, sumergido en el circuito cerrado de refrigeracion
leer_conversor2();
Alterna1=VAlterna1;
Alterna2=VAlterna2;
Alterna3=VAlterna3;
}
}
void Motor(void){
int Cpasos=0;
for(Cpasos==0;Cpasos<10;Cpasos++){
PinA=1;
PinB=0;
PinC=0;
PinD=0;
Delay10KTCYx(30);
PinA=0;
PinB=1;
PinC=0;
PinD=0;
Delay10KTCYx(30);
PinA=0;
PinB=0;
PinC=1;
PinD=0;
Delay10KTCYx(30);
PinA=0;
PinB=0;
PinC=0;
PinD=1;
Delay10KTCYx(20);
}
}
void Limpiar_Pantalla(void){
lcd_gotoxy(1,1);
lcd_puts(Nada);
Delay10TCYx(150);
lcd_gotoxy(1,2);
lcd_puts(Nada);
Delay10TCYx(150);
}
void Configuracion_inicial(int Cont_config){
switch(Cont_config){
case 1:
Limpiar_Pantalla();
Delay10KTCYx(50);
lcd_gotoxy(3,1);
lcd_putrs("Temperatura ");
Delay10TCYx(150);
while(Pulsador4==0){
if(Pulsador1==1){
Delay10KTCYx(20);
if(Pulsador1==1){
if(TempReg<32){
TempReg ++;
}
}
}
if(Pulsador2==1){
Delay10KTCYx(20);
if(Pulsador2==1){
if(TempReg>20){
TempReg --;
}
}
}
if(Pulsador3==1){
break;
}
Delay10TCYx(150);
lcd_gotoxy(6,2);
printf("%u",TempReg);
lcd_gotoxy(8,2);
lcd_putrs("ºc");
Delay10TCYx(150);
}
break;
case 2:
Limpiar_Pantalla();
Delay10KTCYx(50);
lcd_gotoxy(1,1);
lcd_putrs("Habilitar Luz?");
Delay10TCYx(150);
while(Pulsador4==0){
if(Pulsador1==1){
Delay10KTCYx(20);
if(Pulsador1==1){
if(TempReg<32){
Luces=1;
}
}
}
if(Pulsador2==1){
Delay10KTCYx(20);
if(Pulsador2==1){
if(TempReg>20){
Luces=0;
}
}
}
if(Pulsador3==1){
break;
}
if(Luces==0){
lcd_gotoxy(7,2);
lcd_putrs("No");
Delay10TCYx(150);
LATDbits.LATD1=0;
}else{
lcd_gotoxy(7,2);
lcd_putrs("Si");
Delay10TCYx(150);
}
}
Delay10KTCYx(200);
if(Luces==1){
lcd_gotoxy(1,1);
lcd_putrs(" Hora Encendido ");
HoraLuz=HoraConfig;
while(Pulsador4 == 0){
if(Pulsador1==1){
Delay10KTCYx(20);
if(Pulsador1==1){
if(HoraLuz<23){
HoraLuz++;
}
}
}
if(Pulsador2==1){
Delay10KTCYx(20);
if(Pulsador2==1){
if(HoraLuz>=0){
HoraLuz--;
}
}
}
if(HoraLuz<10){
lcd_gotoxy(7,2);
lcd_putrs("0");
lcd_gotoxy(8,2);
printf("%u",HoraLuz);
Delay10TCYx(150);
}else{
lcd_gotoxy(7,2);
printf("%u",HoraLuz);
}
}
lcd_putrs(":");
Delay10KTCYx(100);
MinLuz=MinConfig;
while(Pulsador4==0){
if(Pulsador1==1){
Delay10KTCYx(20);
if(Pulsador1==1){
if(MinLuz<60){
MinLuz++;
}
}
}
if(Pulsador2==1){
Delay10KTCYx(20);
if(Pulsador2==1){
if(MinLuz>=0){
MinLuz--;
}
}
}
if(MinLuz<10){
lcd_gotoxy(10,2);
lcd_putrs("0");
lcd_gotoxy(11,2);
printf("%u",MinLuz);
}else{
lcd_gotoxy(10,2);
printf("%u",MinLuz);
}
}
Limpiar_Pantalla();
lcd_gotoxy(1,1);
lcd_putrs(" Hora Apagado ");
Delay10KTCYx(75);
while(Pulsador4 == 0){
if(Pulsador1==1){
Delay10KTCYx(20);
if(Pulsador1==1){
if(HoraALuz<23){
HoraALuz++;
}
}
}
if(Pulsador2==1){
Delay10KTCYx(20);
if(Pulsador2==1){
if(HoraALuz>=0){
HoraALuz--;
}
}
}
if(HoraALuz<10){
lcd_gotoxy(7,2);
lcd_putrs("0");
lcd_gotoxy(8,2);
printf("%u",HoraALuz);
Delay10TCYx(150);
}else{
lcd_gotoxy(7,2);
printf("%u",HoraALuz);
Delay10TCYx(150);
}
}
lcd_putrs(":");
Delay10KTCYx(100);
while(Pulsador4==0){
if(Pulsador1==1){
Delay10KTCYx(20);
if(Pulsador1==1){
if(MinALuz<60){
MinALuz++;
}
}
}
if(Pulsador2==1){
Delay10KTCYx(20);
if(Pulsador2==1){
if(MinALuz>=0){
MinALuz--;
}
}
}
if(MinALuz<10){
lcd_gotoxy(10,2);
lcd_putrs("0");
lcd_gotoxy(11,2);
printf("%u",MinALuz);
Delay10TCYx(150);
}else{
lcd_gotoxy(10,2);
printf("%u",MinALuz);
Delay10TCYx(150);
}
}
}
HoraLuzBCD=DecimaltoBCD(HoraLuz);
MinLuzBCD=DecimaltoBCD(MinLuz);
HoraALuzBCD=DecimaltoBCD(HoraALuz);
MinALuzBCD=DecimaltoBCD(MinALuz);
break;
case 3:
Limpiar_Pantalla();
Delay10KTCYx(50);
lcd_gotoxy(1,1);
lcd_putrs(" Salida 220v 1 ");
Delay10TCYx(150);
while(Pulsador4==0){
if(Pulsador1==1){
Delay10KTCYx(20);
if(Pulsador1==1){
VAlterna1=1;
}
}
if(Pulsador2==1){
Delay10KTCYx(20);
if(Pulsador2==1){
VAlterna1=0;
}
}
if(Pulsador3==1){
break;
}
if(VAlterna1==0){
lcd_gotoxy(7,2);
lcd_putrs("No");
Delay10TCYx(150);
}else{
lcd_gotoxy(7,2);
lcd_putrs("Si");
Delay10TCYx(150);
}
}
break;
case 4:
Limpiar_Pantalla();
Delay10KTCYx(50);
lcd_gotoxy(1,1);
lcd_putrs(" Salida 220v 2 ");
Delay10TCYx(150);
while(Pulsador4==0){
if(Pulsador1==1){
Delay10KTCYx(20);
if(Pulsador1==1){
VAlterna2=1;
}
}
if(Pulsador2==1){
Delay10KTCYx(20);
if(Pulsador2==1){
VAlterna2=0;
}
}
if(Pulsador3==1){
break;
}
if(VAlterna2==0){
lcd_gotoxy(7,2);
lcd_putrs("No");
Delay10TCYx(150);
}else{
lcd_gotoxy(7,2);
lcd_putrs("Si");
Delay10TCYx(150);
}
}
break;
case 5:
Limpiar_Pantalla();
Delay10KTCYx(50);
lcd_gotoxy(1,1);
lcd_putrs(" Salida 220v 3 ");
Delay10TCYx(150);
while(Pulsador4==0){
if(Pulsador1==1){
Delay10KTCYx(20);
if(Pulsador1==1){
VAlterna3=1;
}
}
if(Pulsador2==1){
Delay10KTCYx(20);
if(Pulsador2==1){
VAlterna3=0;
}
}
if(Pulsador3==1){
break;
}
if(VAlterna3==0){
lcd_gotoxy(7,2);
lcd_putrs("No");
Delay10TCYx(150);
}else{
lcd_gotoxy(7,2);
lcd_putrs("Si");
Delay10TCYx(150);
}
}
break;
}
}
void ConfigHoraFecha(void){
Limpiar_Pantalla();
Delay10KTCYx(200);
lcd_gotoxy(1,1);
lcd_putrs(" Config. Hora ");
Delay10TCYx(150);
while(Pulsador4==0){
if(Pulsador1==1){
Delay10KTCYx(20);
if(Pulsador1==1){
if(HoraConfig<23){
HoraConfig++;
}
}
}
if(Pulsador2==1){
Delay10KTCYx(20);
if(Pulsador2==1){
if(HoraConfig>=0){
HoraConfig--;
}
}
}
lcd_gotoxy(6,2);
printf("%u",HoraConfig);
lcd_gotoxy(8,2);
}
lcd_putrs(":");
Delay10KTCYx(100);
while(Pulsador4==0){
if(Pulsador1==1){
Delay10KTCYx(20);
if(Pulsador1==1){
if(MinConfig<60){
MinConfig++;
}
}
}
if(Pulsador2==1){
Delay10KTCYx(20);
if(Pulsador2==1){
if(MinConfig>=0){
MinConfig--;
}
}
}
lcd_gotoxy(10,2);
printf("%u",MinConfig);
}
Delay10KTCYx(100);
Limpiar_Pantalla();
lcd_gotoxy(1,1);
lcd_putrs(" Config. Fecha ");
Delay10TCYx(50);
while(Pulsador4==0){
if(Pulsador1==1){
Delay10KTCYx(20);
if(Pulsador1==1){
if(AnioConfig<=99){
AnioConfig++;
}
}
}
if(Pulsador2==1){
Delay10KTCYx(20);
if(Pulsador2==1){
if(AnioConfig>=14){
AnioConfig--;
}
}
}
lcd_gotoxy(11,2);
printf("%u",AnioConfig);
lcd_gotoxy(10,2);
lcd_putrs("/");
}
Delay10KTCYx(100);
while(Pulsador4==0){
if(Pulsador1==1){
Delay10KTCYx(20);
if(Pulsador1==1){
if(MesConfig<=12){
MesConfig++;
}
}
}
if(Pulsador2==1){
Delay10KTCYx(20);
if(Pulsador2==1){
if(MesConfig>=0){
MesConfig--;
}
}
}
lcd_gotoxy(9,2);
printf("%u",MesConfig);
lcd_gotoxy(8,2);
lcd_putrs("/");
}
Delay10KTCYx(100);
while(Pulsador4==0){
if(Pulsador1==1){
Delay10KTCYx(20);
if(Pulsador1==1){
if(DiaConfig<=31 && MesConfig!=2){
DiaConfig++;
}
else if(DiaConfig<=28 && MesConfig==2){
DiaConfig++;
}
}
}
if(Pulsador2==1){
Delay10KTCYx(20);
if(Pulsador2==1){
if(DiaConfig>=0){
DiaConfig--;
}
}
}
lcd_gotoxy(7,2);
printf("%u",DiaConfig);
}
HoraConfigBCD=DecimaltoBCD(HoraConfig);
MinConfigBCD=DecimaltoBCD(MinConfig);
DiaConfigBCD=DecimaltoBCD(DiaConfig);
MesConfigBCD=DecimaltoBCD(MesConfig);
AnioConfigBCD=DecimaltoBCD(AnioConfig);
ByteWriteI2C(chip,0,128); // Reloj detenido!!!
ByteWriteI2C(chip,1,MinConfigBCD); // Ajusta Minutos
ByteWriteI2C(chip,2,HoraConfigBCD); // Ajusta Hora
ByteWriteI2C(chip,4,DiaConfigBCD); // Ajusta el Día
ByteWriteI2C(chip,5,MesConfigBCD); // Ajusta Mes
ByteWriteI2C(chip,6,AnioConfigBCD); // Ajusta Año
ByteWriteI2C(chip,0,0x00); // Ajusta Segundos
}
void ByteWriteI2C(unsigned char ByteControl, unsigned char Direccion,
unsigned char Dato)
{
IdleI2C(); // El modulo esta libre?
StartI2C(); // Condición de START
while ( SSPCON2bits.SEN ); // Espera a que la condición de inicio termine
WriteI2C( ByteControl ); // Envía Byte de control
WriteI2C( Direccion );
WriteI2C ( Dato ); // Guarda Dato en la dirección establecida.
StopI2C(); // Condición de STOP
while ( SSPCON2bits.PEN ); // Espera a que la condición de stop termine
}
//DEFINE LA FUNCIÓN DE LECTURA
unsigned char ByteReadI2C( unsigned char ByteControl, unsigned char Direccion )
{
unsigned char Valor;
IdleI2C(); // El modulo esta activo?
StartI2C(); // Condición de START
while ( SSPCON2bits.SEN ); // Espera a que la condición de inicio termine
WriteI2C( ByteControl );
WriteI2C( Direccion );
RestartI2C();
while ( SSPCON2bits.RSEN ); // Si se ha recibido el byte sigue
WriteI2C( ByteControl | 0x01 ); // Cambia bit0 de ByteControl a 1
Valor=ReadI2C(); // Realiza lectura.
NotAckI2C(); // Envía NACK
while ( SSPCON2bits.ACKEN ); // Espera que ASK termine
StopI2C(); // Condición de STOP
while ( SSPCON2bits.PEN ); // Espera a que la condición de stop termine
return ( Valor ); // Retorna Lectura
}
//Ajusta los datos del RTC
void Ajustar_Dato(unsigned char dato){
Unidadrtc = (dato & 0x0F) + 0x30; // Mascara y convirte en ASCII
Decenartc = ((dato/16) & 0x0F) + 0x30; // Intercambia nibles en dato,
stdout =_H_USER; // aplica mascara y convierte en ASCII
printf("%c",Decenartc); // Muestra Decena y Unidad
printf("%c",Unidadrtc);
}
uint8 DecimaltoBCD(uint8 DecimalByte){
return (((DecimalByte/10)<<4)|(DecimalByte%10));
}
uint8 BCDtoDecimal(uint8 BCDByte){
return (((BCDByte&0xF0)>>4)*10)+(BCDByte%0x0F);
}