espero que esto te ayude...
*********************************************
----------------------------------------------
// ds1307.c -- Functions for the Dallas Semiconductor DS1307
// real time clock and NVRAM chip.
//
// The DS1307 uses BCD as its internal format, but we use it
// in binary format, outside of this module. So we have code
// to convert to/from BCD to binary in the functions below.
//----------------------------------------------------------------------
// Set the date and time.
/*
The registers inside the ds1307 are in this format. The values are in BCD.
DS1307_SECONDS_REG 0
DS1307_MINUTES_REG 1
DS1307_HOURS_REG 2
DS1307_DAY_OF_WEEK_REG 3 // We don"t use this register. Set it to 0.
DS1307_DATE_REG 4
DS1307_MONTH_REG 5
DS1307_YEAR_REG 6
*/
void ds1307_set_date_time(void)
{
char i;
// Convert the binary ds1307 data, which is passed in a global array,
// into bcd data. Store it in the same array.
for(i = 0; i "less than" 7; i++)
{
gca_ds1307_regs
= bin2bcd(gca_ds1307_regs);
}
// There are two control bits embedded in the following data.
// The Clock Halt bit is in bit 7 of the DS1307 Seconds register.
// We need to make sure that it"s = 0, to make the clock run.
// The other bit is the 24/12 hour clock format bit, in bit 6 of
// the DS1307 Hours register. We need 24 hour mode, so set it = 0.
gca_ds1307_regs[DS1307_SECONDS_REG] &= 0x7f;
gca_ds1307_regs[DS1307_HOURS_REG] &= 0x3f;
// Now write the 7 bytes of BCD data to the ds1307, using inline code for speed.
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(DS1307_I2C_WRITE_ADDR);
i2c_write(DS1307_SECONDS_REG); // Start writing at the seconds reg
// Write 7 bytes, to registers 0 to 6.
for(i = 0; i "less than" 7; i++)
{
i2c_write(gca_ds1307_regs);
}
// After setting the time in registers 0-6, also set the Control register. (index = 7)
// This just turns off the squarewave output pin. Doing it here, every time
// we set the clock registers, seems less risky than setting it near the
// start of the program, every time the unit powers-up.
i2c_write(DS1307_CONTROL_REG_INIT_VALUE);
i2c_stop();
enable_interrupts(GLOBAL);
}
//----------------------------------------------------------------------
// Read the date and time.
// The registers inside the ds1307 are in this order. The values inside the
// registers are in BCD.
// DS1307_SECONDS_REG_ADDR 0
// DS1307_MINUTES_REG_ADDR 1
// DS1307_HOURS_REG_ADDR 2
// DS1307_DAY_OF_WEEK_REG_ADDR 3
// DS1307_DATE_REG_ADDR 4
// DS1307_MONTH_REG_ADDR 5
// DS1307_YEAR_REG_ADDR 6
// We return the data in a global array. The data in is binary.
// seconds // 0-59 seconds
// minutes // 0-59 minutes
// hours // 0-23 hours
// day_of_week // 1-7
// date // 1-31 date
// month // 1-12 month
// year // 00-99 year (based on year 2000)
void ds1307_read_date_time(void)
{
char i;
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(DS1307_I2C_WRITE_ADDR);
i2c_write(DS1307_SECONDS_REG); // Start reading at the Seconds reg
i2c_start();
i2c_write(DS1307_I2C_READ_ADDR);
// Read the 7 bytes from the ds1307. Mask off unused bits.
gca_ds1307_regs[DS1307_SECONDS_REG] = i2c_read() & 0x7f;
gca_ds1307_regs[DS1307_MINUTES_REG] = i2c_read() & 0x7f;
gca_ds1307_regs[DS1307_HOURS_REG] = i2c_read() & 0x3f;
gca_ds1307_regs[DS1307_DAY_OF_WEEK_REG] = i2c_read() & 0x07;
gca_ds1307_regs[DS1307_DATE_REG] = i2c_read() & 0x3f;
gca_ds1307_regs[DS1307_MONTH_REG] = i2c_read() & 0x1f;
gca_ds1307_regs[DS1307_YEAR_REG] = i2c_read(0); // No ACK on last byte
i2c_stop();
enable_interrupts(GLOBAL);
// Now convert the data from BCD to binary. Do it after reading the bytes,
// so that the i2c reads can be done quickly.
for(i = 0; i "less than" 7; i++)
{
gca_ds1307_regs = bcd2bin(gca_ds1307_regs);
}
}
//------------------------------------------------------------------------
// Read one byte at the specified address.
//
// This function is used to access the control byte or the NVRAM bytes.
char ds1307_read_byte(char addr)
{
char retval;
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(DS1307_I2C_WRITE_ADDR);
i2c_write(addr);
i2c_start();
i2c_write(DS1307_I2C_READ_ADDR);
retval = i2c_read(0); // We"re only reading a single byte, so no ACK on it.
i2c_stop();
enable_interrupts(GLOBAL);
return(retval);
}
//----------------------------------------------------------------------
// Write one byte to the DS1307.
//
// This function is used to access the control byte or the NVRAM bytes.
void ds1307_write_byte(char addr, char value)
{
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(DS1307_I2C_WRITE_ADDR);
i2c_write(addr);
i2c_write(value);
i2c_stop();
enable_interrupts(GLOBAL);
}
//--------------------------------------------------------------------------
// This function converts an 8 bit binary value to an 8 bit BCD value.
// The input range must be from 0 to 99.
char bin2bcd(char binary_value)
{
char temp;
char retval;
temp = binary_value;
retval = 0;
while(1)
{
// Get the tens digit by doing multiple subtraction of 10 from the binary value
if(temp "greater than or equal to" 10)
{
temp -= 10;
retval += 0x10;
}
else // Get the ones digit by adding the remainder.
{
retval += temp;
break;
}
}
return(retval);
}
//--------------------------------------------------------------------------
// This function converts an 8 bit BCD value to an 8 bit binary value.
// The input range must be from 00 to 99.
char bcd2bin(char bcd_value)
{
char temp;
temp = bcd_value;
temp "shift right"= 1; // Shifting upper digit right by 1 is same as mult. by 8
temp &= 0x78; // Isolate the bits for the upper digit
// Now return: (Tens *
+ (Tens *2) + Ones
return(temp + (temp "shift right" 2) + (bcd_value & 0x0f));
}
============================================================================
This is the "include" file that goes with the above C file.
// ds1307.h
//--------------------------------------------------------------------------
// i2c addresses
#define DS1307_I2C_WRITE_ADDR 0xd0
#define DS1307_I2C_READ_ADDR 0xd1
// DS1307 register offsets
#define DS1307_SECONDS_REG 0
#define DS1307_MINUTES_REG 1
#define DS1307_HOURS_REG 2
#define DS1307_DAY_OF_WEEK_REG 3
#define DS1307_DATE_REG 4
#define DS1307_MONTH_REG 5
#define DS1307_YEAR_REG 6
#define DS1307_CONTROL_REG 7
#define DS1307_DATE_TIME_BYTE_COUNT 7 // includes bytes 0-6
#define DS1307_NVRAM_START_ADDR 8
// We disable the SQWV output, because it uses a lot of battery current
// when it"s enabled.
#define DS1307_CONTROL_REG_INIT_VALUE 0x80 // Disable SQWV, set Out = O.C.
//#define DS1307_CONTROL_REG_INIT_VALUE 0x13 // 32.768 KHz output
//--------------------------------------------------------------------------
// GLOBAL VARIABLES
// This is a global array to hold data which is passed to/from the
// functions that set the ds1307 date and time.
char gca_ds1307_regs[DS1307_DATE_TIME_BYTE_COUNT];
//-----------------------------------------------------------------------
// FUNCTION PROTOTYPES
void ds1307_set_date_time(void);
void ds1307_read_date_time(void);
void ds1307_write_byte(char addr, char value);
char ds1307_read_byte(char addr);
char bin2bcd(char binary_value);
char bcd2bin(char bcd_value);
======================================================