|
Using the ATMEGA168/Arduino with a DS1307 Real Time Clockby Lewis Loflin Explanation of program: On power up or reset the "setup" is executed once, setting up the hardware and writing the time/date to the DS1307. Then the "loop" section will run over and over. The DS1307 is read and sent via the serial port to a computer running for example Hyper Terminal. This demonstrates the use of the Wire.h library, serial ports, and the DS1307. For the basic structure of an Arduino program see page 7 of Arduino Programming Notebook by Brian Evans
The DS1307 is a low-power clock/calendar with 56 bytes of battery-backed SRAM. The clock/calendar
provides seconds, minutes, hours, day, date, month, and year information. The date at the end of the
month is automatically adjusted for months with fewer than 31 days, including corrections for leap year.
Bit 7 of Register 0 is the clock halt (CH) bit. When this bit is set to 1, the oscillator is disabled. When cleared to 0, the oscillator is enabled. In other words unless this is cleared the clock will not run!
Only the first 8 bytes (0x00 - 0x07) are used by the clock itself while the other 56 bytes can be used a scratchpad RAM. PIN DESCRIPTION Pins 1, 2 Connections for Standard 32.768kHz Quartz Crystal. No capacitor or other parts needed. Pin 3 VBAT Backup Supply Input for Any Standard 3V Lithium Cell Diodes in series between the battery and the VBAT pin may prevent proper operation! Pin 4 GND Ground Pin 5 SDA Serial Data Input/Output. SDA is the data input/output for the I2C serial interface. The SDA pin is open drain and requires an external pull-up resistor. Arduino pin 4. Pin 6 SCL Serial Clock Input. SCL is the clock input for the I2C interface and is used to synchronize data movement on the serial interface. Arduino pin 5. 7 SWQ/OUT Square Wave/Output Driver. When enabled, the SQWE bit set to 1, the SQW/OUT pin outputs one of four square-wave frequencies (1Hz, 4kHz, 8kHz, 32kHz). The SQW/OUT pin is open drain and requires an external pull-up resistor. SQW/OUT operates with either VCC or VBAT applied. An LED and 220 ohm resistor in series tied to VCC will produce a 1 HZ blink. This is a good way to tell if the clock chip is working. 8 VCC (5 volts) For more information on the DS1307 see Dallas DS1307 Real Time Clock I2C plus RAM
#include <Wire.h> // specify use of Wire.h library. byte blinkPin = 13; byte SW0 = 4; byte SW1 = 5; byte SW2 = 6; void setup() { Wire.begin(); // join i2c bus (address optional for master) Serial.begin(9600); pinMode(blinkPin, OUTPUT); digitalWrite(blinkPin, 0); pinMode(SW0, INPUT); // for this use a slide switch pinMode(SW1, INPUT); // N.O. push button switch pinMode(SW2, INPUT); // N.O. push button switch digitalWrite(SW0, HIGH); // pull-ups on digitalWrite(SW1, HIGH); digitalWrite(SW2, HIGH); } void loop() { Wire.beginTransmission(0x68); Wire.send(0); Wire.endTransmission(); Wire.requestFrom(0x68, 7); byte secs = Wire.receive(); byte mins = Wire.receive(); byte hrs = Wire.receive(); byte day = Wire.receive(); byte date = Wire.receive(); byte month = Wire.receive(); byte year = Wire.receive(); // hours, minutes, seconds Serial.print("The time is "); if (hrs < 10) Serial.print("0"); Serial.print(hrs,HEX); Serial.print(":"); if (mins < 10) Serial.print("0"); Serial.print(mins, HEX); Serial.print(":"); if (secs < 10) Serial.print("0"); Serial.println(secs, HEX); // use MM-DD-YYYY Serial.print("The date is "); if (month < 10) Serial.print("0"); Serial.print(month,HEX); Serial.print("-"); if (date < 10) Serial.print("0"); Serial.print(date, HEX); Serial.print("-"); Serial.print("20"); if (year < 10) Serial.print("0"); Serial.println(year, HEX); Serial.println(); if (!(digitalRead(SW0))) set_time(); // hold the switch to set time delay(1000); //wait a second before next output toggle(blinkPin); } // toggle the state on a pin void toggle(int pinNum) { int pinState = digitalRead(pinNum); pinState = !pinState; digitalWrite(pinNum, pinState); } void set_time() { byte minutes = 0; byte hours = 0; while (!digitalRead(SW0)) // set time switch must be released to exit { while (!digitalRead(SW1)) // set minutes { minutes++; if ((minutes & 0x0f) > 9) minutes = minutes + 6; if (minutes > 0x59) minutes = 0; Serial.print("Minutes = "); if (minutes >= 9) Serial.print("0"); Serial.println(minutes, HEX); delay(750); } while (!digitalRead(SW2)) // set hours { hours++; if ((hours & 0x0f) > 9) hours = hours + 6; if (hours > 0x23) hours = 0; Serial.print("Hours = "); if (hours <= 9) Serial.print("0"); Serial.println(hours, HEX); delay(750); } Wire.beginTransmission(0x68); // activate DS1307 Wire.send(0); // where to begin Wire.send(0x00); //seconds Wire.send(minutes); //minutes Wire.send(0x80 | hours); //hours (24hr time) Wire.send(0x06); // Day 01-07 Wire.send(0x01); // Date 0-31 Wire.send(0x05); // month 0-12 Wire.send(0x09); // Year 00-99 Wire.send(0x10); // Control 0x10 produces a 1 HZ square wave on pin 7. Wire.endTransmission(); } } Setting Hours and MinutesAssuming the switches are wired as shown above, close SW0 and while closed SW1 and SW2 will increment the hours and minutes as shown on the terminal. Release/open SW0 and new time will be written to the DS1307. You Tube Arduino Microcontroller Video Series March 2012:
Arduino demos:
» About me » Bristol VA/TN » E-Mail » Hobby Electronics » Arduino Microcontroller
General Electronics
Added January 2012: PICAXE Micro-controller Projects!The PICAXE series of micro-controllers rank as the easiest and most cost effective way to use Microchip processors. I wanted an easier and less expensive way to introduce my students to the "PIC" micro-controller. Here I hope to get those starting out past poorly written literature and lack of simple working code examples.
|