// libreria para uso de rtc
unsigned short int bcd2bin(unsigned short int PackedBCDbyte);
unsigned short int bcd2ascii(unsigned short int cadenabcd);
unsigned short int bin2bcd(unsigned short int binaryByte);
unsigned short int bcd2int(unsigned short int PackedBCDbyte);
void initRtcDs1337(unsigned int hour,
unsigned int min,
unsigned int sec,
unsigned int dayOfWeek,
unsigned int date,
unsigned int month,
unsigned int year);
void setSecRtcDs1337(unsigned int setSec);
void setMinRtcDs1337(unsigned int setMin);
void setHourRtcDs1337(unsigned int setHour);
void setDayOfWeekRtcDs1337(unsigned int setDayOfWeek);
void setDateRtcDs1337(unsigned int setDate);
void setMonthRtcDs1337(unsigned int setMonth);
void setYearRtcDs1337(unsigned int setYear);
void setAlarm1RtcDs1337(unsigned int setHour,
unsigned int setMin,
unsigned int setSec,
unsigned int setDate);
void resetAlarm1RtcDs1337(void);
void resetAlarm2RtcDs1337(void);
void setAlarm2RtcDs1337(unsigned int setHour,
unsigned int setMin,
unsigned int setDate);
void setSquareWaveRtcDs1337(unsigned int setEnable,
unsigned int setRate);
void readRtcDs1337(void);
/*declaración de variables*/
struct{
// variables para hora
unsigned short int unidadesSec;
unsigned short int decenasSec;
unsigned short int unidadesMin;
unsigned short int decenasMin;
unsigned short int unidadesHour;
unsigned short int decenasHour;
unsigned formatoAmPm:1;
unsigned formato12_24:1;
// variables para fecha
unsigned short int dayWeek;
unsigned short int unidadesDate;
unsigned short int decenasDate;
unsigned short int unidadesMonth;
unsigned short int decenasMonth;
unsigned centuryOverflow:1;
unsigned short int unidadesYear;
unsigned short int decenasYear;
// variables para alarma1
unsigned short int unidadesSecAlarm1;
unsigned short int decenasSecAlarm1;
unsigned short int unidadesMinAlarm1;
unsigned short int decenasMinAlarm1;
unsigned short int unidadesHourAlarm1;
unsigned short int decenasHourAlarm1;
unsigned formatoAmPmAlarm1:1;
unsigned formato12_24Alarm1:1;
unsigned short int unidadesDayAlarm1;
unsigned short int unidadesDateAlarm1;
unsigned short int decenasDateAlarm1;
unsigned DayOrDateSelectAlarm1:1;
unsigned alarm1Mask1:1;
unsigned alarm1Mask2:1;
unsigned alarm1Mask3:1;
unsigned alarm1Mask4:1;
// variables para alarma2
unsigned short int unidadesMinAlarm2;
unsigned short int decenasMinAlarm2;
unsigned short int unidadesHourAlarm2;
unsigned short int decenasHourAlarm2;
unsigned formatoAmPmAlarm2:1;
unsigned formato12_24Alarm2:1;
unsigned short int unidadesDayAlarm2;
unsigned short int unidadesDateAlarm2;
unsigned short int decenasDateAlarm2;
unsigned DayOrDateSelectAlarm2:1;
unsigned alarm2Mask1:1;
unsigned alarm2Mask2:1;
unsigned alarm2Mask3:1;
unsigned alarm2Mask4:1;
}RTC;
unsigned short int sec;
unsigned short int min;
unsigned short int hour;
unsigned short int dayWeek;
unsigned short int date;
unsigned short int month;
unsigned short int year;
unsigned short int alarm1sec;
unsigned short int alarm1min;
unsigned short int alarm1hour;
unsigned short int alarm1date;
unsigned short int alarm2min;
unsigned short int alarm2hour;
unsigned short int alarm2date;
/***** rutina de inicialización de rtc ***************************************/
void initRtcDs1337(unsigned int hour,
unsigned int min,
unsigned int sec,
unsigned int dayOfWeek,
unsigned int date,
unsigned int month,
unsigned int year)
{
OpenI2C(MASTER,SLEW_OFF); // inicializo el i2c en modo maestro y 100khz
SSPADD = 49; // SSPADD = ( (Fosc/4) / BiteRate )-1
/* When the MSSP is configured in Master mode, the lower seven
bits of SSPADD act as the Baud Rate Generator reload value.*/
/*ejemplo usando cristal de 20mhz
((Fosc/4) / BiteRate )-1
(Fosc/4) =20mhz/4 =5mhz
Entonces nos da:
SSPADD = ( 5MHz / 100KHz ) - 1
SSPADD = ( 50 ) - 1
SSPADD = 49. o su equivalente en hexadecimal = 0x31
*/
IdleI2C();
StartI2C(); // Envia condición de start al bus i2c
IdleI2C();
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
/*
(Write Mode):
The slave address byte is the first byte received after the master generates the START condition.
The slave address byte contains the 7-bit DS1337 address, which is 1101000, followed by the direction bit (R/W),
which, for a write, is 0.
*/
WriteI2C(0b00000000); // pone el puntero del rtc en dirección 00h enviando la dirección del registro 0
IdleI2C();
/*
After the DS1337 acknowledges the slave address + write bit, the master transmits a register address
to the DS1337. This sets the register pointer on the DS1337.
The master may then transmit zero or more bytes of data, with the DS1337 acknowledging each byte received.
The address pointer will increment after each data byte is transferred.
The master generates a STOP condition to terminate the data write.
*/
WriteI2C (bin2bcd(sec)); // (0b00000000); // 'REGISTER 0 =00H - SECONDS 0
IdleI2C();
WriteI2C(bin2bcd(min)); // (0b01000011); // 'REGISTER 1 =01H - MINUTES 43
IdleI2C();
WriteI2C(bin2bcd(hour)); // (0b00100000); // 'REGISTER 2 =02H - HOURS 20
IdleI2C();
WriteI2C(bin2bcd(dayOfWeek)); // (0b00000000); // 'REGISTER 3 =03H - DAY 0
IdleI2C();
WriteI2C(bin2bcd(date)); // (0b00011001); // 'REGISTER 4 =04H - DATE 19
IdleI2C();
WriteI2C(bin2bcd(month)); // (0b00000010); // 'REGISTER 5 =05H - MONTH 02
IdleI2C();
WriteI2C(bin2bcd(year)); // (0b00010001); // 'REGISTER 6 =06H - YEAR 11
IdleI2C();
WriteI2C(bin2bcd(0)); // (0b00000000); // 'REGISTER 7 =07H -ALARM1 SECONDS 0
IdleI2C();
WriteI2C(bin2bcd(0)); // (0b00000000); // 'REGISTER 8 =08H -ALARM1 MINUTES 0
IdleI2C();
WriteI2C(bin2bcd(0)); // (0b00000000); // 'REGISTER 9 =09H -ALARM1 HOURS 0
IdleI2C();
WriteI2C(bin2bcd(1));// (0b00000001); // 'REGISTER 10 =0AH - ALARM1 DAY=NO/DATE=SI DATE 1
IdleI2C();
WriteI2C(bin2bcd(0));// (0b00000010); // 'REGISTER 11 =0BH -ALARM2 MIUNUTES 2
IdleI2C();
WriteI2C(bin2bcd(0));// (0b00000000); // 'REGISTER 12 =0CH -ALARMA2 HOURS 0
IdleI2C();
WriteI2C(bin2bcd(0));// (0b00011001); // 'REGISTER 13 =0DH -ALARMA2 DAY/DATE 19
IdleI2C();
WriteI2C(bin2bcd(0b00000111));// (0b00000000); // 'REGISTER 14 =0EH -CONTROL bit7=0 Enable Oscilator
// bit4=0 Rate select 2
// bit3=0 Rate select 1
// bit2=0 interrupt control
// bit1=0 alarm 2 interrupt
// bit0=0 alarm 1 interrupt
IdleI2C();
WriteI2C(0b00000000); // 'REGISTER 15 =0FH - STATUS bit7=0 pone a cero el oscilator stop flag
// bit1=0 pone a cero el flag de alarm 2
// bit0=0 pone a cero el flag de alarm 1
IdleI2C();
StopI2C();
}
/***** fin de rutina de inicialización de rtc ***************************************/
/***** rutina de seteo de segundos del rtc ***************************************/
void setSecRtcDs1337(unsigned int setSec)
{
OpenI2C(MASTER,SLEW_OFF); // inicializo el i2c en modo maestro y 100khz
SSPADD = 49; // SSPADD = ( (Fosc/4) / BiteRate )-1
/* When the MSSP is configured in Master mode, the lower seven
bits of SSPADD act as the Baud Rate Generator reload value.*/
/*ejemplo usando cristal de 20mhz
((Fosc/4) / BiteRate )-1
(Fosc/4) =20mhz/4 =5mhz
Entonces nos da:
SSPADD = ( 5MHz / 100KHz ) - 1
SSPADD = ( 50 ) - 1
SSPADD = 49. o su equivalente en hexadecimal = 0x31
*/
IdleI2C();
StartI2C(); // Envia condición de start al bus i2c
IdleI2C();
/*
(Write Mode):
The slave address byte is the first byte received after the master generates the START condition.
The slave address byte contains the 7-bit DS1337 address, which is 1101000, followed by the direction bit (R/W),
which, for a write, is 0.
*/
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
WriteI2C(0b00000000); // pone el puntero del rtc en la dirección 00h correspondiente a los segundos
IdleI2C();
/*
After the DS1337 acknowledges the slave address + write bit, the master transmits a register address
to the DS1337. This sets the register pointer on the DS1337.
The master may then transmit zero or more bytes of data, with the DS1337 acknowledging each byte received.
The address pointer will increment after each data byte is transferred.
The master generates a STOP condition to terminate the data write.
*/
WriteI2C (bin2bcd(setSec));
IdleI2C();
StopI2C();
}
/***** fin de rutina de seteo de segundos del rtc ***************************************/
/***** rutina de seteo de minutos del rtc ***************************************/
void setMinRtcDs1337(unsigned int setMin)
{
OpenI2C(MASTER,SLEW_OFF); // inicializo el i2c en modo maestro y 100khz
SSPADD = 49; // SSPADD = ( (Fosc/4) / BiteRate )-1
/* When the MSSP is configured in Master mode, the lower seven
bits of SSPADD act as the Baud Rate Generator reload value.*/
/*ejemplo usando cristal de 20mhz
((Fosc/4) / BiteRate )-1
(Fosc/4) =20mhz/4 =5mhz
Entonces nos da:
SSPADD = ( 5MHz / 100KHz ) - 1
SSPADD = ( 50 ) - 1
SSPADD = 49. o su equivalente en hexadecimal = 0x31
*/
IdleI2C();
StartI2C(); // Envia condición de start al bus i2c
IdleI2C();
/*
(Write Mode):
The slave address byte is the first byte received after the master generates the START condition.
The slave address byte contains the 7-bit DS1337 address, which is 1101000, followed by the direction bit (R/W),
which, for a write, is 0.
*/
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
WriteI2C(0b00000001); // pone el puntero del rtc en la dirección 01h correspondiente a los minutos
IdleI2C();
/*
After the DS1337 acknowledges the slave address + write bit, the master transmits a register address
to the DS1337. This sets the register pointer on the DS1337.
The master may then transmit zero or more bytes of data, with the DS1337 acknowledging each byte received.
The address pointer will increment after each data byte is transferred.
The master generates a STOP condition to terminate the data write.
*/
WriteI2C (bin2bcd(setMin));
IdleI2C();
StopI2C();
}
/***** fin de rutina de seteo de minutos del rtc ***************************************/
/***** rutina de seteo de hora del rtc ***************************************/
void setHourRtcDs1337(unsigned int setHour)
{
OpenI2C(MASTER,SLEW_OFF); // inicializo el i2c en modo maestro y 100khz
SSPADD = 49; // SSPADD = ( (Fosc/4) / BiteRate )-1
/* When the MSSP is configured in Master mode, the lower seven
bits of SSPADD act as the Baud Rate Generator reload value.*/
/*ejemplo usando cristal de 20mhz
((Fosc/4) / BiteRate )-1
(Fosc/4) =20mhz/4 =5mhz
Entonces nos da:
SSPADD = ( 5MHz / 100KHz ) - 1
SSPADD = ( 50 ) - 1
SSPADD = 49. o su equivalente en hexadecimal = 0x31
*/
IdleI2C();
StartI2C(); // Envia condición de start al bus i2c
IdleI2C();
/*
(Write Mode):
The slave address byte is the first byte received after the master generates the START condition.
The slave address byte contains the 7-bit DS1337 address, which is 1101000, followed by the direction bit (R/W),
which, for a write, is 0.
*/
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
WriteI2C(0b00000010); // pone el puntero del rtc en la dirección 02h correspondiente a la hora
IdleI2C();
/*
After the DS1337 acknowledges the slave address + write bit, the master transmits a register address
to the DS1337. This sets the register pointer on the DS1337.
The master may then transmit zero or more bytes of data, with the DS1337 acknowledging each byte received.
The address pointer will increment after each data byte is transferred.
The master generates a STOP condition to terminate the data write.
*/
WriteI2C (bin2bcd(setHour));
IdleI2C();
StopI2C();
}
/***** fin de rutina de seteo de hora del rtc ***************************************/
/***** rutina de seteo de dia de la semana del rtc ***************************************/
void setDayOfWeekRtcDs1337(unsigned int setDayOfWeek)
{
OpenI2C(MASTER,SLEW_OFF); // inicializo el i2c en modo maestro y 100khz
SSPADD = 49; // SSPADD = ( (Fosc/4) / BiteRate )-1
/* When the MSSP is configured in Master mode, the lower seven
bits of SSPADD act as the Baud Rate Generator reload value.*/
/*ejemplo usando cristal de 20mhz
((Fosc/4) / BiteRate )-1
(Fosc/4) =20mhz/4 =5mhz
Entonces nos da:
SSPADD = ( 5MHz / 100KHz ) - 1
SSPADD = ( 50 ) - 1
SSPADD = 49. o su equivalente en hexadecimal = 0x31
*/
IdleI2C();
StartI2C(); // Envia condición de start al bus i2c
IdleI2C();
/*
(Write Mode):
The slave address byte is the first byte received after the master generates the START condition.
The slave address byte contains the 7-bit DS1337 address, which is 1101000, followed by the direction bit (R/W),
which, for a write, is 0.
*/
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
WriteI2C(0b00000011); // pone el puntero del rtc en la dirección 03h correspondiente a DayOfWeek
IdleI2C();
/*
After the DS1337 acknowledges the slave address + write bit, the master transmits a register address
to the DS1337. This sets the register pointer on the DS1337.
The master may then transmit zero or more bytes of data, with the DS1337 acknowledging each byte received.
The address pointer will increment after each data byte is transferred.
The master generates a STOP condition to terminate the data write.
*/
WriteI2C (bin2bcd(setDayOfWeek));
IdleI2C();
StopI2C();
}
/***** fin de rutina de seteo de dia de la semana del rtc ***************************************/
/***** rutina de seteo de dia del mes del rtc ***************************************/
void setDateRtcDs1337(unsigned int setDate)
{
OpenI2C(MASTER,SLEW_OFF); // inicializo el i2c en modo maestro y 100khz
SSPADD = 49; // SSPADD = ( (Fosc/4) / BiteRate )-1
/* When the MSSP is configured in Master mode, the lower seven
bits of SSPADD act as the Baud Rate Generator reload value.*/
/*ejemplo usando cristal de 20mhz
((Fosc/4) / BiteRate )-1
(Fosc/4) =20mhz/4 =5mhz
Entonces nos da:
SSPADD = ( 5MHz / 100KHz ) - 1
SSPADD = ( 50 ) - 1
SSPADD = 49. o su equivalente en hexadecimal = 0x31
*/
IdleI2C();
StartI2C(); // Envia condición de start al bus i2c
IdleI2C();
/*
(Write Mode):
The slave address byte is the first byte received after the master generates the START condition.
The slave address byte contains the 7-bit DS1337 address, which is 1101000, followed by the direction bit (R/W),
which, for a write, is 0.
*/
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
WriteI2C(0b00000100); // pone el puntero del rtc en la dirección 04h correspondiente a día de la semana
IdleI2C();
/*
After the DS1337 acknowledges the slave address + write bit, the master transmits a register address
to the DS1337. This sets the register pointer on the DS1337.
The master may then transmit zero or more bytes of data, with the DS1337 acknowledging each byte received.
The address pointer will increment after each data byte is transferred.
The master generates a STOP condition to terminate the data write.
*/
WriteI2C (bin2bcd(setDate));
IdleI2C();
StopI2C();
}
/***** fin de rutina de seteo de dia del mes del rtc ***************************************/
/***** rutina de seteo del mes del rtc ***************************************/
void setMonthRtcDs1337(unsigned int setMonth)
{
OpenI2C(MASTER,SLEW_OFF); // inicializo el i2c en modo maestro y 100khz
SSPADD = 49; // SSPADD = ( (Fosc/4) / BiteRate )-1
/* When the MSSP is configured in Master mode, the lower seven
bits of SSPADD act as the Baud Rate Generator reload value.*/
/*ejemplo usando cristal de 20mhz
((Fosc/4) / BiteRate )-1
(Fosc/4) =20mhz/4 =5mhz
Entonces nos da:
SSPADD = ( 5MHz / 100KHz ) - 1
SSPADD = ( 50 ) - 1
SSPADD = 49. o su equivalente en hexadecimal = 0x31
*/
IdleI2C();
StartI2C(); // Envia condición de start al bus i2c
IdleI2C();
/*
(Write Mode):
The slave address byte is the first byte received after the master generates the START condition.
The slave address byte contains the 7-bit DS1337 address, which is 1101000, followed by the direction bit (R/W),
which, for a write, is 0.
*/
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
WriteI2C(0b00000101); // pone el puntero del rtc en la dirección 05h correspondiente al mes
IdleI2C();
/*
After the DS1337 acknowledges the slave address + write bit, the master transmits a register address
to the DS1337. This sets the register pointer on the DS1337.
The master may then transmit zero or more bytes of data, with the DS1337 acknowledging each byte received.
The address pointer will increment after each data byte is transferred.
The master generates a STOP condition to terminate the data write.
*/
WriteI2C (bin2bcd(setMonth));
IdleI2C();
StopI2C();
}
/***** fin de rutina de seteo del mes del rtc ***************************************/
// ***** rutina de seteo del año del rtc **************************************
void setYearRtcDs1337(unsigned int setYear)
{
OpenI2C(MASTER,SLEW_OFF); // inicializo el i2c en modo maestro y 100khz
SSPADD = 49; // SSPADD = ( (Fosc/4) / BiteRate )-1
IdleI2C();
StartI2C(); // Envia condición de start al bus i2c
IdleI2C();
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
WriteI2C(0b00000110); // pone el puntero del rtc en la dirección 06h correspondiente al año
IdleI2C();
WriteI2C (bin2bcd(setYear));
IdleI2C();
StopI2C();
}
// ***** fin de rutina de seteo del año del rtc ***************************************
// ***** rutina de seteo de alarma1 del rtc ***************************************
// NOTA: falta implementar la máscara de los registros 07h a 0ah de los bit7 para setear el alarm Rate.
// La función setea la alarma con la opción por defecto todos los bits 7 en cero. (se activa la alarma
// cuando se igualan los segundos, minutos, horas, y dia del mes.
void setAlarm1RtcDs1337(unsigned int setHour,
unsigned int setMin,
unsigned int setSec,
unsigned int setDate)
{
OpenI2C(MASTER,SLEW_OFF); // inicializo el i2c en modo maestro y 100khz
SSPADD = 49; // SSPADD = ( (Fosc/4) / BiteRate )-1
IdleI2C();
StartI2C(); // Envia condición de start al bus i2c
IdleI2C();
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
WriteI2C(0b00000111); // pone el puntero del rtc en la dirección 07h correspondiente a los segundos alarma1
IdleI2C();
WriteI2C (bin2bcd(setSec));
IdleI2C();
WriteI2C(bin2bcd(setMin));
IdleI2C();
WriteI2C(bin2bcd(setHour));
IdleI2C();
WriteI2C(bin2bcd(setDate));
IdleI2C();
StopI2C();
}
/***** fin de rutina de seteo de alarma1 del rtc ********************************/
// ****** rutina de seteo de alarma2 del rtc ***************************************
// NOTA: falta implementar la máscara de los registros 0bh a 0dh de los bit7 para setear el alarm Rate.
// La función setea la alarma con la opción por defecto todos los bits 7 en cero. (se activa la alarma
// cuando se igualan los minutos, horas, y dia del mes.
void setAlarm2RtcDs1337(unsigned int setHour,
unsigned int setMin,
unsigned int setDate)
{
OpenI2C(MASTER,SLEW_OFF); // inicializo el i2c en modo maestro y 100khz
SSPADD = 49; // SSPADD = ( (Fosc/4) / BiteRate )-1
IdleI2C();
StartI2C(); // Envia condición de start al bus i2c
IdleI2C();
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
WriteI2C(0b00001011); // pone el puntero del rtc en la dirección 0bh correspondiente a los minutos alarma2
IdleI2C();
WriteI2C(bin2bcd(setMin));
IdleI2C();
WriteI2C(bin2bcd(setHour));
IdleI2C();
WriteI2C(bin2bcd(setDate));
IdleI2C();
StopI2C();
}
// ***** fin de rutina de seteo de alarma2 del rtc ********************************
// ****** rutina de reseteo de alarma1 del rtc ***************************************
void resetAlarm1RtcDs1337(void)
{
OpenI2C(MASTER,SLEW_OFF); // inicializo el i2c en modo maestro y 100khz
SSPADD = 49; // SSPADD = ( (Fosc/4) / BiteRate )-1
IdleI2C();
StartI2C(); // Envia condición de start al bus i2c
IdleI2C();
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
WriteI2C(0b00001111); // pone el puntero del rtc en la dirección 0fh correspondiente a los flags de alarmas
IdleI2C();
WriteI2C(0b00000010);
IdleI2C();
StopI2C();
}
// ****** final de rutina de reseteo de alarma1 del rtc ***************************************
// ****** rutina de reseteo de alarma2 del rtc ***************************************
void resetAlarm2RtcDs1337(void)
{
OpenI2C(MASTER,SLEW_OFF); // inicializo el i2c en modo maestro y 100khz
SSPADD = 49; // SSPADD = ( (Fosc/4) / BiteRate )-1
IdleI2C();
StartI2C(); // Envia condición de start al bus i2c
IdleI2C();
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
WriteI2C(0b00001111); // pone el puntero del rtc en la dirección 0fh correspondiente a los flags de alarmas
IdleI2C();
WriteI2C(0b00000001);
IdleI2C();
StopI2C();
}
// ****** final de rutina de reseteo de alarma2 del rtc ***************************************
/***** rutina de seteo de salida de onda cuadrada del rtc ***************************************/
void setSquareWaveRtcDs1337(unsigned int setEnable,
unsigned int setRate)
{
OpenI2C(MASTER,SLEW_OFF); // inicializo el i2c en modo maestro y 100khz
SSPADD = 49; // SSPADD = ( (Fosc/4) / BiteRate )-1
IdleI2C();
StartI2C(); // Envia condición de start al bus i2c
IdleI2C();
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
WriteI2C(0b00001110); // pone el puntero del rtc en la dirección 0eh correspondiente al registro de control
IdleI2C();
if (setEnable == 1)
{
// ACA FALTA IMPLEMENTAR UN SWITCH CASE para seleccionar los diferentes rates
WriteI2C(0b00000000);
IdleI2C();
StopI2C();
}
else
{
WriteI2C(0b00000100);
IdleI2C();
StopI2C();
}
}
/***** fin de rutina de seteo de salida de onda cuadrada del rtc ********************************/
/***** rutina de lectura de datos de rtc ***************************************/
void readRtcDs1337(void)
{
/* Para leer los datos del rtc primero debemos enviar la posición del puntero de registro
Para ello se siguen los siguientes pasos:
* verificar que el bus i2c esté desocupado con idleI2C()
* se envía una condición de start con StartI2C()
* verificar que el bus i2c esté desocupado con idleI2C()
* se envía la dirección del rtc (1101000) más el bit 0 para informar que vamos a escribir =0b11010000
* se escribe la dirección del puntero de registro a la que queremos apuntar. pej al registro 0=0b00000000
* luego enviamos nuevamente la condición de start
* se envía la dirección del rtc (1101000) más el bit 1 para informar que vamos a leer =0b11010001
* se lee el registro apuntado con ReadI2C()
* se le dice al slave AckI2C() para informar que se leyó el valor
* verificar que el bus i2c esté desocupado con idleI2C()
* para leer el registro siguiente lo hacemos nuevamente con ReadI2C()
* se le dice al slave AckI2C() para informar que se leyó el valor
* verificar que el bus i2c esté desocupado con idleI2C()
* una vez que no querémos seguir leyendo más registros debemos informar al slave tal circunstancia
terminando la lectura con NotAckI2C()
* verificar que el bus i2c esté desocupado con idleI2C()
* Dejampos libre el bus i2c con StopI2C()
*/
// prepara lo necesario para hacer la lectura
IdleI2C();
StartI2C(); // Envia condición de start al bus i2c
IdleI2C();
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
WriteI2C(0b00000000); // pone el puntero del rtc en dirección 00h enviando la dirección del registro 0
IdleI2C();
RestartI2C(); // Envia condición de restart al bus i2c
IdleI2C();
WriteI2C(0b11010001); // escribe la dirección del rtc (0b1101000) y último bit en 1 = hex D1=0b11010001)
// con este último bit0 en 1 se le dice al rtc que se va a leer
IdleI2C();
// COMIENZA LECTURA
// lee registro 00H **** LECTURA DE SEGUNDOS ****************************************
sec = ReadI2C()& 0x7f; // enmascara el octavo bit que no se usa.
AckI2C();
IdleI2C();
RTC.unidadesSec = sec &0b00001111;// enmascara el nible alto del valor leido para pasar las unidades a la variable
RTC.decenasSec =( sec &0b01110000);// enmascara el nible bajo del valor leido para pasar las decenas a la variable
RTC.decenasSec = RTC.decenasSec >>4;
// lee registro 01H **** LECTURA DE MINUTOS ****************************************
min = ReadI2C()& 0x7f; // enmascara el octavo bit que no se usa.
AckI2C();
IdleI2C();
RTC.unidadesMin = min &0b00001111;// enmascara el nible alto del valor leido para pasar las unidades a la variable
RTC.decenasMin = min &0b01110000;// enmascara el nible bajo del valor leido para pasar las decenas a la variable
RTC.decenasMin = RTC.decenasMin >>4;
// lee registro 02H **** LECTURA DE HORAS ******************************************
hour = ReadI2C()& 0x7f; // enmascara el octavo bit que no se usa.
AckI2C();
IdleI2C();
RTC.unidadesHour = hour &0b00001111;// enmascara el nible alto del valor leido para pasar las unidades a la variable
RTC.decenasHour = hour &0b01110000;// enmascara el nible bajo del valor leido para pasar las decenas a la variable
RTC.decenasHour = RTC.decenasHour >>4;
// lee registro 03H **** LECTURA DEL DIA DE LA SEMANA ******************************************
dayWeek = ReadI2C()& 0b00000111; // enmascara el nibble alto.
AckI2C();
IdleI2C();
RTC.dayWeek = dayWeek; // copio el valor leido
// lee registro 04H **** LECTURA DE DIA DEL MES ******************************************
date = ReadI2C()& 0b00111111; // enmascara el octavo y séptimo bit que no se usan.
AckI2C();
IdleI2C();
RTC.unidadesDate = date &0b00001111;// enmascara el nible alto del valor leido para pasar las unidades a la variable
RTC.decenasDate = date &0b00110000;// enmascara el nible bajo del valor leido para pasar las decenas a la variable
RTC.decenasDate = RTC.decenasDate >>4;
// lee registro 05H **** LECTURA DE MES ******************************************
month = ReadI2C()& 0b00011111; // enmascara el octavo, séptimo, y sexto bit que no se usan.
AckI2C();
IdleI2C();
RTC.unidadesMonth = month &0b00001111;// enmascara el nible alto del valor leido para pasar las unidades a la variable
RTC.decenasMonth = month &0b00010000;// enmascara el nible bajo del valor leido para pasar las decenas a la variable
RTC.decenasMonth = RTC.decenasMonth >>4;
// lee registro 06H **** LECTURA DE AÑO ******************************************
year = ReadI2C();
// Como es la última lectura que en este caso se le pide al bus i2c se finaliza con NotAckI2C() y StopI2C()
NotAckI2C();
IdleI2C();
StopI2C();
RTC.unidadesYear = year &0b00001111;// enmascara el nible alto del valor leido para pasar las unidades a la variable
RTC.decenasYear = year &0b11110000;// enmascara el nible bajo del valor leido para pasar las decenas a la variable
RTC.decenasYear = RTC.decenasYear >>4;
// *********** Convierte los balores leidos en formato bcd a formato binario ********************
sec=bcd2bin(sec);
min=bcd2bin(min);
hour=bcd2bin(hour);
date=bcd2bin(date);
month=bcd2bin(month);
year=bcd2bin(year);
}
/***** final de rutina de lectura de datos de rtc ***************************************/
/***** rutina de lectura de datos de las alarmas del rtc ***************************************/
void readAlarmsRtcDs1337(void)
{
// prepara lo necesario para hacer la lectura
IdleI2C();
StartI2C(); // Envia condición de start al bus i2c
IdleI2C();
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
WriteI2C(0b00000111); // pone el puntero del rtc en dirección 07H enviando la dirección del registro 7
IdleI2C();
RestartI2C(); // Envia condición de restart al bus i2c
IdleI2C();
WriteI2C(0b11010001); // escribe la dirección del rtc (0b1101000) y último bit en 1 = hex D1=0b11010001)
// con este último bit0 en 1 se le dice al rtc que se va a leer
IdleI2C();
// COMIENZA LECTURA
// lee registro 07H **** LECTURA DE SEGUNDOS alarm1 ****************************************
alarm1sec = ReadI2C()& 0x7f; // enmascara el octavo bit que no se usa.
AckI2C();
IdleI2C();
RTC.unidadesSecAlarm1 = alarm1sec &0b00001111;// enmascara el nible alto del valor leido para pasar las unidades a la variable
RTC.decenasSecAlarm1 =( alarm1sec &0b01110000);// enmascara el nible bajo del valor leido para pasar las decenas a la variable
RTC.decenasSecAlarm1 = RTC.decenasSecAlarm1 >>4;
// lee registro 08H **** LECTURA DE MINUTOS alarm1 ****************************************
alarm1min = ReadI2C()& 0x7f; // enmascara el octavo bit que no se usa.
AckI2C();
IdleI2C();
RTC.unidadesMinAlarm1 = alarm1min &0b00001111;// enmascara el nible alto del valor leido para pasar las unidades a la variable
RTC.decenasMinAlarm1 = alarm1min &0b01110000;// enmascara el nible bajo del valor leido para pasar las decenas a la variable
RTC.decenasMinAlarm1 = RTC.decenasMinAlarm1 >>4;
// lee registro 09H **** LECTURA DE HORAS alarm1 ******************************************
alarm1hour = ReadI2C()& 0x7f; // enmascara el octavo bit que no se usa.
AckI2C();
IdleI2C();
RTC.unidadesHourAlarm1 = alarm1hour &0b00001111;// enmascara el nible alto del valor leido para pasar las unidades a la variable
RTC.decenasHourAlarm1 = alarm1hour &0b01110000;// enmascara el nible bajo del valor leido para pasar las decenas a la variable
RTC.decenasHourAlarm1 = RTC.decenasHourAlarm1 >>4;
// lee registro 10H **** LECTURA DEL DIA DEL MES alarm1 ******************************************
alarm1date = ReadI2C()& 0b00111111; // enmascara el octavo y séptimo bit que no se usan.
AckI2C();
IdleI2C();
RTC.unidadesDateAlarm1 = alarm1date &0b00001111;// enmascara el nible alto del valor leido para pasar las unidades a la variable
RTC.decenasDateAlarm1 = alarm1date &0b00110000;// enmascara el nible bajo del valor leido para pasar las decenas a la variable
RTC.decenasDateAlarm1 = RTC.decenasDateAlarm1 >>4;
// lee registro 11H **** LECTURA DE MINUTOS alarm2 ****************************************
alarm2min = ReadI2C()& 0x7f; // enmascara el octavo bit que no se usa.
AckI2C();
IdleI2C();
RTC.unidadesMinAlarm2 = alarm2min &0b00001111;// enmascara el nible alto del valor leido para pasar las unidades a la variable
RTC.decenasMinAlarm2 = alarm2min &0b01110000;// enmascara el nible bajo del valor leido para pasar las decenas a la variable
RTC.decenasMinAlarm2 = RTC.decenasMinAlarm2 >>4;
// lee registro 12H **** LECTURA DE HORAS alarm 2 ******************************************
alarm2hour = ReadI2C()& 0x7f; // enmascara el octavo bit que no se usa.
AckI2C();
IdleI2C();
RTC.unidadesHourAlarm2 = alarm2hour &0b00001111;// enmascara el nible alto del valor leido para pasar las unidades a la variable
RTC.decenasHourAlarm2 = alarm2hour &0b01110000;// enmascara el nible bajo del valor leido para pasar las decenas a la variable
RTC.decenasHourAlarm2 = RTC.decenasHourAlarm2 >>4;
// lee registro 13H **** LECTURA UNIDADES DE DIA DEL MES ALARM2 ******************************************
alarm2date = ReadI2C()& 0b00111111; // enmascara el octavo y séptimo bit que no se usan.
// Como es la última lectura que en este caso se le pide al bus i2c se finaliza con NotAckI2C() y StopI2C()
NotAckI2C();
IdleI2C();
StopI2C();
RTC.unidadesDateAlarm2 = alarm2date &0b00001111;// enmascara el nible alto del valor leido para pasar las unidades a la variable
RTC.decenasDateAlarm2 = alarm2date &0b00110000;// enmascara el nible bajo del valor leido para pasar las decenas a la variable
RTC.decenasDateAlarm2 = RTC.decenasDateAlarm2 >>4;
// *********** Convierte los balores leidos en formato bcd a formato binario ********************
alarm1sec=bcd2bin(alarm1sec);
alarm1min=bcd2bin(alarm1min);
alarm1hour=bcd2bin(alarm1hour);
alarm1date=bcd2bin(alarm1date);
alarm2min=bcd2bin(alarm2min);
alarm2hour=bcd2bin(alarm2hour);
alarm2date=bcd2bin(alarm2date);
}
/***** fin de rutina de lectura de datos de las alarmas del rtc ***************************************/
/****************** función para convertir digito binario a bcd *********************************************/
/* primero compruebo si el número binario es mayor o igual que el número 10.
Si es menor que el 10 directamente asigno a l_digit el valor del número pasado como parámetro ---> l_digit=valor;
Si el número pasado como parámetro es mayor o igual que 10 le voy restando 10 unidades hasta que dicho valor
sea menor que 10 y en cada iteración voy incrementando en una unidad a h_digit.
Una vez que el valor es menor que 10 asigno el valor a l_digit
*/
unsigned short int bin2bcd(unsigned short int binaryByte)
{
unsigned short int temp=0;
unsigned short int l_digit, h_digit;
h_digit=0;
l_digit=0;
temp=binaryByte;
if (temp>=10){
do{
temp-=10;
h_digit++;
}while (temp>=10);
}
l_digit=temp;
h_digit = h_digit <<4; // muevo las decenas al nible alto
return (h_digit | l_digit); // combina nibblealto y nibblebajo para hacer packed bcd
}
/****************** final función para convertir digito binario a bcd ***************************************/
// ******función para pasar de bcd a valor entero ***************************************************
unsigned short int bcd2bin(unsigned short int PackedBCDbyte)
{
unsigned short int temp;
temp = PackedBCDbyte;
temp >>= 1; // saco el bit 8 que no se usa
temp &= 0x78; // hago una máscara con 0b01111000 para dejar pasar sólo los bits 7 a 3
return(temp + // sumo las centenas // 40decimal
(temp >> 2) + // sumo las decenas // 10 decimal
(PackedBCDbyte & 0x0f));// paso las unidades // 9decimal
}
/*
ejemplo de uso:
dato pasado como parámetro a la función: 0b01011001
0101=5 1001=9 BCD = decimal 89 = binario 01011001
temp=0b01011001
>>1 temp=0b00101100
&=0x78 0b01111000 aplica máscara desde el bit7 a bit3
temp=0b00101000 = 40decimal
>>2 temp=0b00001010 = 10 decimal
PackedBCDbyte 0b01011001
& 0x0f 0b00001111
------------------
=0b00001001 = 9 decimal
return (40decimal +(10decimal) + 9decimal = 59 decimal = 0x3b = 0011 1011
*/
// ******final función para pasar de bcd a valor entero ***************************************************