Subversion Repositories Code-Repo

Compare Revisions

Ignore whitespace Rev 280 → Rev 281

/PIC Stuff/PICX_12F1840_Clock/DS3231.c
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
}