Woohoo, I2C & RTC Work, as does Square Wave Output (demonstrated via flashing LED).
/*
Test of RTC DS1307 via I2C.
Counts
Seconds,
Minutes,
Hours,
Date of the Month,
Month,
Day of the week, and
Year with Leap-Year
56 bytes battery backed RAM
Square Wave Output, can connect to INT2/D6 or PD7
*/
#include <Wire.h>
//variables
byte seconds_address = 0x00;
byte seconds; // bit 7 = Clock Halt, Enabled = 0, Halt = 1
// bits 6-5-3 = tens of seconds 0-6, bits 3-2-1-0 = units of seconds, 0-9
byte minutes_address = 0x01;
byte minutes; // bits 6-5-4 = tens of minutes, bits 3-2-1-0 = units of minutes
byte hours_address = 0x02;
byte hours; // 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
// bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
// bit 4 = lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)
byte day_week_address = 0x03;
byte day_week = 0; // range 01-07
byte date_month_address = 0x04;
byte date_month = 0; // range 01-31
byte month_address = 0x05;
byte month = 0; // range 01-12
byte year_address = 0x06;
int year = 0; // upper byte 0-9, lower byte 0-9
byte square_address = 0x07;
byte sqwe = 0; // square wave enable
// Out-0-0-Sqwe-0-0-RS1-RS0
// Out, Sqwe = 0/0 - Square wave output = 0
// Out, Sqwe = 1/0 - Square wave output = 1
// Out, Sqwe = 0/1 or 1/1 - Square wave output per RS1/RS0
// RS1/RS0 = 00 = 1 Hz
// RS1/RSo = 01 = 4 KHz
// RS1/RS0 = 10 = 8 KHz
// RS1/RS0 = 11 = 32 KHz
byte RTC_ram_address = 0x08; //range = 08-63, 0x08-0x3F
int RTC_address = 0x68; // 1101 000
byte incomingCommand = 0;
byte RTC_write_command = 0;
byte RTC_read_command = 0;
byte RTC_ram_command = 0;
// use F0xx, F1xx,F2xx, F3xx, F4xx, F5xx, F6xx, F7xx
// to send one register write commands
// use E0xx to read registers back
// use C0xx to read RAM back
byte incomingRegister = 0;
byte RTC_register = 0;
byte incomingData = 0;
byte new_data = 0;
byte outgoingData = 0;
int delay_time = 100;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long duration = 5000;
void setup() {
Wire.begin(); // no address, we are master
Serial1.begin (57600);
Serial1.flush();
currentMillis = millis();
}
void loop() {
if (Serial1.available() >1){
incomingCommand = Serial1.read();
//incomingRegister = Serial.read();
incomingData = Serial1.read();
Serial1.print ("command ");
Serial1.println (incomingCommand & 0xF0, HEX);
Serial1.print ("register ");
Serial1.println(incomingCommand & 0x0F, HEX);
Serial1.print ("data ");
Serial1.println (incomingData, HEX);
}
// *******************************************
RTC_write_command = incomingCommand & 0xF0; // mask off high byte
if (RTC_write_command == 0xF0){ // e033check for Write command
RTC_register = incomingCommand & 0x0F; // mask off low btye
incomingCommand = 0;
new_data = incomingData;
Serial1.print (" Sending a command ");
switch (RTC_register){
case 0: // write seconds
Serial1.println ("Seconds ");
Wire.beginTransmission(RTC_address); // select device
Wire.send(seconds_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 1: // write minutes
Serial1.print ("Minutes ");
Wire.beginTransmission(RTC_address); // select device
Wire.send(minutes_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 2: // write hours
Serial1.print ("Hours ");
Wire.beginTransmission(RTC_address); // select device
Wire.send(hours_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 3: // write day
Serial1.print ("Day ");
Wire.beginTransmission(RTC_address); // select device
Wire.send(day_week_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 4: // write date of month
Serial1.print ("Day of Month ");
Wire.beginTransmission(RTC_address); // select device
Wire.send(date_month_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 5: // write month
Serial1.print ("Month ");
Wire.beginTransmission(RTC_address); // select device
Wire.send(month_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 6: // write year
Serial1.print ("Year ");
Wire.beginTransmission(RTC_address); // select device
Wire.send(year_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 7: // write square wave
Serial1.print ("Square Wave ");
Serial1.println (RTC_register, HEX);
Wire.beginTransmission(RTC_address); // select device
Wire.send(square_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
case 8: // write RAM
Serial1.print ("RAM ");
Serial1.println (RTC_register, HEX);
Wire.beginTransmission(RTC_address); // select device
Wire.send(RTC_ram_address); // queue the register
Wire.send(new_data); // queue data
Wire.endTransmission(); // send it
delay (delay_time);
break;
// all others,do nothing
Serial.println ("Invalid command ");
} // end Switch
} // end if command == F
// ************************************
currentMillis = millis();
if ( (currentMillis - previousMillis) >= duration){
previousMillis = currentMillis;
// Reset the register pointer
Wire.beginTransmission(RTC_address);
Wire.send(0x00);
Wire.endTransmission();
Wire.requestFrom(RTC_address, 8 );
seconds = Wire.receive();
minutes = Wire.receive();
hours = Wire.receive();
day_week = Wire.receive();
date_month = Wire.receive();
month = Wire.receive();
year = Wire.receive();
sqwe = Wire.receive();
// Seconds
// bit 7 = Clock Halt, Enabled = 0, Halt = 1
// bits 6-5-3 = tens of seconds 0-6, bits 3-2-1-0 = units of seconds, 0-9
// Hours
// 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
// bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
// bit 4 = lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)
Serial1.print ("Hrs " );
Serial1.print (hours, HEX);
Serial1.print (" Mins ");
Serial1.print (minutes, HEX);
Serial1.print (" Secs ");
Serial1.print (seconds, HEX);
Serial1.print (" Day ");
Serial1.print (day_week, HEX);
Serial1.print (" Date ");
Serial1.print (date_month, HEX);
Serial1.print (" Month ");
Serial1.print (month, HEX);
Serial1.print (" Year 20");
Serial1.print (year, HEX);
Serial1.print (" Square Wave ");
Serial1.println (sqwe, HEX);
}
}
Moniter output:
Hrs 1 Mins 54 Secs 27 Day 4 Date 27 Month 7 Year 2011 Square Wave 10
Hrs 1 Mins 54 Secs 32 Day 4 Date 27 Month 7 Year 2011 Square Wave 10
Hrs 1 Mins 54 Secs 37 Day 4 Date 27 Month 7 Year 2011 Square Wave 10
Hrs 1 Mins 54 Secs 42 Day 4 Date 27 Month 7 Year 2011 Square Wave 10
Hrs 1 Mins 54 Secs 47 Day 4 Date 27 Month 7 Year 2011 Square Wave 10
Tomorrow, SPI ... And see if the clock is running fast ...