0,0 → 1,113 |
#include "defines.h" |
#include "DS3231.h" |
#include "I2C1.h" |
|
void DS3231_Init() { |
uint8_t reg[3]; |
reg[0] = DS3231_CONTROL; |
|
/* Control Register (0x0E) |
* Bit 7 - !EOSC |
* Bit 6 - BBSQW |
* Bit 5 - CONV |
* Bit 4 - RS2 |
* Bit 3 - RS1 |
* Bit 2 - INTCN |
* Bit 1 - A2IE |
* Bit 0 - A1IE |
*/ |
reg[1] = 0x04; |
|
/* Control Register 2 (0x0F) |
* Bit 3 = EN32kHZ |
*/ |
reg[2] = 0x00; |
|
// Set the configuration registers |
I2C1_Master_Send(DS3231_ADDRESS, 3, reg); |
while (!I2C1_Get_Status()); |
} |
|
uint8_t DS3231_Get_Status(void) { |
/* Status Register (0x0F) |
* Bit 7 - OSF |
* Bit 3 - EN32kHz |
* Bit 2 - BSY |
* Bit 1 - A2F |
* Bit 0 - A1F |
*/ |
uint8_t value; |
I2C1_Master_Restart(DS3231_ADDRESS, 0x0F, 1); |
while (!I2C1_Get_Status()); |
I2C1_Read_Buffer(&value); |
return value; |
} |
|
void DS3231_Set_Time(DS3231_TIME *time) { |
|
// Format the data in a way that the chip expects |
#ifndef DS3231_TIME_ONLY |
uint8_t output[8]; |
#else |
uint8_t output[4]; |
#endif |
output[0] = DS3231_SECONDS; |
output[1] = ((time->sec / 10) << 4) | (time->sec % 10); |
output[2] = ((time->min / 10) << 4) | (time->min % 10); |
output[3] = ((time->hour / 10) << 4) | (time->hour % 10); |
#ifndef DS3231_TIME_ONLY |
if (!time->h_mil) { |
output[3] |= (time->h_am_pm) ? 0x60 : 0x40; |
} |
output[4] = time->day; |
output[5] = ((time->date / 10) << 4) | (time->date % 10); |
output[6] = ((time->month / 10) << 4) | (time->month % 10); |
output[7] = ((time->year / 10) << 4) | (time->year % 10); |
#endif |
|
// Check the status to make sure that it isnt currently busy |
while (DS3231_Get_Status() & 0x04); |
|
// Write the data to the chip |
#ifndef DS3231_TIME_ONLY |
I2C1_Master_Send(DS3231_ADDRESS, 8, output); |
#else |
I2C1_Master_Send(DS3231_ADDRESS, 4, output); |
#endif |
while (!I2C1_Get_Status()); |
} |
|
void DS3231_Get_Time(DS3231_TIME *time) { |
|
// Check the status to make sure that it isnt currently busy |
while (DS3231_Get_Status() & 0x04); |
|
// Request time data from the chip |
#ifndef DS3231_TIME_ONLY |
uint8_t input[7]; |
I2C1_Master_Restart(DS3231_ADDRESS, 0x00, 7); |
#else |
uint8_t input[3]; |
I2C1_Master_Restart(DS3231_ADDRESS, 0x00, 3); |
#endif |
while (!I2C1_Get_Status()); |
I2C1_Read_Buffer(input); |
|
// Parse BCD format into decimal and return |
time->sec = ((input[0] >> 4) * 10) + (input[0] & 0x0F); |
time->min = ((input[1] >> 4) * 10) + (input[1] & 0x0F); |
if (input[2] & 0x40) { |
time->h_mil = 0; |
time->h_am_pm = (input[2] & 0x20) ? 1 : 0; |
time->hour = (((input[2] >> 4) & 0x01) * 10) + (input[2] & 0x0F); |
} else { |
time->h_mil = 1; |
time->hour = ((input[2] >> 4) * 10) + (input[2] & 0x0F); |
} |
#ifndef DS3231_TIME_ONLY |
time->day = input[3]; |
time->date = ((input[4] >> 4) * 10) + (input[4] & 0x0F); |
time->month = ((input[5] >> 4) * 10) + (input[5] & 0x0F); |
time->year = ((input[6] >> 4) * 10) + (input[6] & 0x0F); |
#endif |
} |