///////////////////////////////////////////////////////////////////////////////////////
/// DS1307.C ///
/// Driver for Real Time Clock ///
/// modified by Redpic 08/2006 ///
/// http://picmania.garcia-cuervo.net ///
/// ///
/// void ds1307_init(val) ///
/// - Enable oscillator without clearing the seconds register ///
/// used when PIC loses power and DS1307 run from 3V BAT ///
/// - Config Control Register with next parameters: ///
/// DS1307_ALL_DISABLED All disabled ///
/// DS1307_OUT_ON_DISABLED_HIHG Out to Hight on Disable Out ///
/// DS1307_OUT_ENABLED Out Enabled ///
/// DS1307_OUT_1_HZ Freq. Out to 1 Hz ///
/// DS1307_OUT_4_KHZ Freq. Out to 4.096 Khz ///
/// DS1307_OUT_8_KHZ Freq. Out to 8.192 Khz ///
/// DS1307_OUT_32_KHZ Freq. Out to 32.768 Khz ///
/// ///
/// Example init: ///
/// ds1307_init(DS1307_ALL_DISABLED); ///
/// ds1307_init(DS1307_OUT_ENABLED | DS1307_OUT_1_HZ); ///
/// ///
/// void ds1307_set_date_time(day,mth,year,dow,hour,min,sec) - Set the date/time ///
/// ///
/// void ds1307_get_date(day,mth,year,dow) - Get the date ///
/// ///
/// void ds1307_get_time(hr,min,sec) - Get the time ///
/// ///
/// char ds1307_read_nvram_byte(char addr) - Read byte in address ///
/// ///
/// void ds1307_write_nvram_byte(char addr, char value) - Write byte in address ///
/// ///
/// void ds1307_get_day_of_week(char* ptr) - Get string Day Of Week///
/// ///
/// If defined USE_INTERRUPTS all functions disable Global Interrupts on starts and ///
/// enable Global on ends else usar can do it hiself ///
/// ++ : Configuracion AM/PM by MLO ///
///////////////////////////////////////////////////////////////////////////////////////
#ifndef RTC_SDA
#define RTC_SDA PIN_C4
#define RTC_SCL PIN_C3
#endif
#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)
#define DS1307_ALL_DISABLED 0b00000000 // All disabled
#define DS1307_OUT_ON_DISABLED_HIHG 0b10000000 // Out to Hight on Disable Out
#define DS1307_OUT_ENABLED 0b00010000 // Out Enabled
#define DS1307_OUT_1_HZ 0b00000000 // Freq. Out to 1 Hz
#define DS1307_OUT_4_KHZ 0b00000001 // Freq. Out to 4.096 Khz
#define DS1307_OUT_8_KHZ 0b00000010 // Freq. Out to 8.192 Khz
#define DS1307_OUT_32_KHZ 0b00000011 // Freq. Out to 32.768 Khz
#define Start_user_address_nvram 0x08
#define End_user_address_nvram 0x3f
byte ds1307_bin2bcd(byte binary_value, int1 hora);
byte ds1307_bcd2bin(byte bcd_value, int1 hora);
void ds1307_init(int val)
{
i2c_start();
i2c_write(0xD0); //Direccion del DS1307 Modo Escritura
i2c_write(0x00); //Pongo a [0] para garantizar el CH=0
i2c_stop();
i2c_start();
i2c_write(0xD0); //Direccion del DS1307 Modo Escritura
i2c_write(0x07); //Selecciono el Byte de Ctrl
i2c_write(val); //Envio el dato segun configuracion
i2c_stop();
}
void ds1307_set_date_time(byte day, byte mth, byte year, byte dow, byte hr, byte min, byte sec)
{
sec &= 0x7F;
hr &= 0x7F;//0x3F
i2c_start();
i2c_write(0xD0);
i2c_write(0x00);
i2c_write(ds1307_bin2bcd(sec,0));
i2c_write(ds1307_bin2bcd(min,0));
i2c_write(ds1307_bin2bcd(hr,1));
i2c_write(ds1307_bin2bcd(dow,0));
i2c_write(ds1307_bin2bcd(day,0));
i2c_write(ds1307_bin2bcd(mth,0));
i2c_write(ds1307_bin2bcd(year,0));
i2c_stop();
}
void ds1307_get_date(byte &day, byte &mth, byte &year, byte &dow)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x03);
i2c_start();
i2c_write(0xD1);
dow = ds1307_bcd2bin(i2c_read() & 0x7f,0);
day = ds1307_bcd2bin(i2c_read() & 0x3f,0);
mth = ds1307_bcd2bin(i2c_read() & 0x1f,0);
year = ds1307_bcd2bin(i2c_read(0),0);
i2c_stop();
}
void ds1307_get_time(byte &hr, byte &min, byte &sec)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x00);
i2c_start();
i2c_write(0xD1);
sec = ds1307_bcd2bin(i2c_read() & 0x7f,0);
min = ds1307_bcd2bin(i2c_read() & 0x7f,0);
hr = ds1307_bcd2bin(i2c_read(0) & 0x7f,1);//0x3f
i2c_stop();
}
/*
char ds1307_read_nvram_byte(char addr)
{
char retval;
i2c_start();
i2c_write(0xD0);
i2c_write(addr);
i2c_start();
i2c_write(0xD1);
retval = i2c_read(0);
i2c_stop();
return(retval);
}
void ds1307_write_nvram_byte(char addr, char value)
{
i2c_start();
i2c_write(0xD0);
i2c_write(addr);
i2c_write(value);
i2c_stop();
}
/*
void ds1307_get_day_of_week(char* ptr){
byte lday;
byte lmonth;
byte lyr;
byte ldow;
ds1307_get_date(lday,lmonth,lyr,ldow);
sprintf(ptr,"%s",days_of_week[ldow]);
}
*/
///////////////////////////////////////////////////////////////////////////////
byte ds1307_bin2bcd(byte binary_value, int1 hora){
byte temp;
byte retval;
int1 FlagAmPm;
temp = binary_value;
if(hora)
{
FlagAmPm = bit_test(temp,5);
temp &=0x0f;
}
retval = 0;
while(true){
if(temp >= 10){
temp -= 10;
retval += 0x10;
}else{
retval += temp;
break;
}
}
if(hora)
{
bit_set(retval,6); //Para configurar la hora modo AM/PM
if(FlagAmPm)
bit_set(retval,5);
}
return(retval);
}
byte ds1307_bcd2bin(byte bcd_value,int1 hora){
byte temp;
int1 FlagAmPm;
byte Salida;
temp = bcd_value;
if(hora)
{
FlagAmPm = bit_test(temp,5);
temp &=0x1f;
}
temp >>= 1;
temp &= 0x78;
if(Hora)
{
Salida = temp + (temp >> 2) + (bcd_value & 0x0f);
if(FlagAmPm)
bit_set(Salida,5);
return(Salida);
}
else
return(temp + (temp >> 2) + (bcd_value & 0x0f));
}