Since my ChronoDot has arrived, I have been able to test the DS3231's extra functions. Until I can get all of them working, I'll be offering them "loose" for those that also want to help test or just want the working ones. They can be dropped into the DS1307 library as public members.
EDIT: All functions are working! A patch for the DS1307 library will come soon; alternatively, I can offer these as part of their own library. The functions below are merely for reference.
NOTE: During testing, with the 32K and SQW pins connected to digital pins 2 and 3 respectively, I've found that the SQW pin will interfere with the 32K one, causing pin 3 to read the SQW signals. After testing as many software combinations as I could think of, and even after attaching a stronger pull-up resistor to the 32K line, my thinking is that it has to do with EMI between the two pins. If you want a clear signal from either pin, your best bet is to disable one and enable the other in software.
Temperature readout, working. Returns a float representing the temperature measured since the last temperature conversion, in degrees celsius (temperatures below zero will be reported incorrectly because of a known bug):
float getTemperature(void)
{
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x11);
Wire.endTransmission();
// Just the two this time (temperature int, frac)
Wire.requestFrom(DS1307_CTRL_ID, 2);
int8_t fint = Wire.receive();
uint8_t ffrac = ((Wire.receive() >> 6));
return (float)fint + ((float)ffrac * 0.25);
}
Force temperature conversion, also working. Argument determines whether or not the function should block until the conversion is complete. I tested it briefly; on my chip, it blocks for approximately 150ms.
void tempConv(uint8_t block)
{
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.endTransmission();
// control register
Wire.requestFrom(DS1307_CTRL_ID, 1);
uint8_t creg = Wire.receive();
creg |= 0b00100000; // Write CONV bit
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.send(creg);
Wire.endTransmission();
do
{
// Block until CONV is 0
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.endTransmission();
Wire.requestFrom(DS1307_CTRL_ID, 1);
} while ((block && (Wire.receive() & 0b00100000) != 0));
}
Battery-backed square-wave enableworking. When enabled, this disables the alarm function.
void SQWEnable(uint8_t enable)
{
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.endTransmission();
// control register
Wire.requestFrom(DS1307_CTRL_ID, 1);
uint8_t creg = Wire.receive();
creg &= ~0b01000000; // Set to 0
if (enable == true) {
creg |= 0b01000000; // Enable if required.
creg &= ~0b00000100; // Clear INTCN bit
}
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.send(creg);
Wire.endTransmission();
}
Battery-backed square-wave frequency setting, working. Make sure the pin it's connected to is pulled up (this can be accomplished on an input pin by writing HIGH to it). Argument MUST be one of the four #defined below.
#define DS3231_SQW_FREQ_1 0b00000000 // 1Hz
#define DS3231_SQW_FREQ_1024 0b00001000 // 1024Hz
#define DS3231_SQW_FREQ_4096 0b00010000 // 4096Hz
#define DS3231_SQW_FREQ_8192 0b00011000 // 8192Hz
void SQWFrequency(uint8_t freq)
{
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.endTransmission();
// control register
Wire.requestFrom(DS1307_CTRL_ID, 1);
uint8_t creg = Wire.receive();
creg &= ~0b00011000; // Set to 0
creg |= freq; // Set freq bits
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.send(creg);
Wire.endTransmission();
}
Enable 32KHz pin, partially working. Needs to be pulled up if connected like the SQW pin.
void enable32Khz(uint8_t enable)
{
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0F);
Wire.endTransmission();
// status register
Wire.requestFrom(DS1307_CTRL_ID, 1);
uint8_t sreg = Wire.receive();
sreg &= ~0b00001000; // Set to 0
if (enable == true)
sreg |= 0b00001000; // Enable if required.
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0F);
Wire.send(sreg);
Wire.endTransmission();
}
Enable internal oscillator, UNKNOWN if working. NOTE that this function differs from the actual bit value given in the datasheet, as the name it uses for this bit is misleading. Calling this with "true" will ENABLE the oscillator as the name implies.
void enableOSC(uint8_t enable)
{
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.endTransmission();
// status register
Wire.requestFrom(DS1307_CTRL_ID, 1);
uint8_t sreg = Wire.receive();
sreg |= 0b10000000; // Set to 1 (disabled)
if (enable == true)
sreg &= ~0b10000000; // Enable if required.
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.send(sreg);
Wire.endTransmission();
}
The battery-backed square wave feature is present in the DS1307, but it uses a different address to enable/configure it. If anyone could make the necessary changes and see if they can debug it on the DS1307, I would be grateful, as having an accurate external timer would be handy!