The 3 volt battery is necessary for time keeping when the 5V power supply is off. A CR battery will be sufficient to keep time for many many years.
The PWM pin is not really necessary, but it can be used to output a pulse of e.g. 1Hz that can be used to drive a LED that will be pulsing 1x per second. For this one must write a 0x10 (10 in HEX format, 16 in digital format, 00010000 in binary format) to register 07 (HEX).
//-----------
/*
reading and writing to the Maxim DS1307 real time clock IC
based on code by Maurice Ribble
17-4-2008 - http://www.glacialwanderer.com/hobbyrobotics
---------------------------------------
CONTROL REGISTER
The DS1307 control register is used to control
the operation of the SQW/OUT pin.
BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
OUT 0 0 SQWE 0 0 RS1 RS0
Bit 4: Square-Wave Enable (SQWE): This bit, when set to logic 1,
enables the oscillator output.
---------------------------------------
Pin 5 (SDA) naar analoog4
Pin 6 (SCL) naar analoog5
*/
#include "Wire.h" // available in the Arduino files
#define DS1307_I2C_ADDRESS 0x68
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(decToBcd(second)); // 0 to bit 7 starts the clock
Wire.send(decToBcd(minute));
Wire.send(decToBcd(hour));
Wire.send(decToBcd(dayOfWeek));
Wire.send(decToBcd(dayOfMonth));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.endTransmission();
}
// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// A few of these need masks because certain bits are control bits
*second = bcdToDec(Wire.receive() & 0x7f);
*minute = bcdToDec(Wire.receive());
*hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
*dayOfWeek = bcdToDec(Wire.receive());
*dayOfMonth = bcdToDec(Wire.receive());
*month = bcdToDec(Wire.receive());
*year = bcdToDec(Wire.receive());
}
// sqw is set here
void sqw1() // set to 1Hz
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0x07); // move pointer to SQW address
Wire.send(0x10); // sends 0x10 (hex) 00010000 (binary)
Wire.endTransmission();
}
//-------------------
void setup()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
Wire.begin();
Serial.begin(9600);
// Change these values to what you want to set your clock to.
// You probably only want to set your clock once and then remove
// the setDateDs1307 call.
second = 0;
minute = 52;
hour = 9;
dayOfWeek = 7;
dayOfMonth = 7;
month = 1;
year = 12;
// uncomment instruction below to set the time
// setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
//----------------------------
sqw1(); //switch on 1Hz SQW
//-----------------------------
}
void loop()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
Serial.print(hour, DEC);// convert the byte variable to a decimal number when being displayed
Serial.print(":");
if (minute<10)
{
Serial.print("0");
}
Serial.print(minute, DEC);
Serial.print(":");
if (second<10)
{
Serial.print("0");
}
Serial.print(second, DEC);
Serial.print(" ");
Serial.print(dayOfMonth, DEC);
Serial.print("/");
Serial.print(month, DEC);
Serial.print("/");
Serial.print(year, DEC);
//Serial.print(" Day of week:");
switch(dayOfWeek){
case 1:
Serial.println(" Sunday");
break;
case 2:
Serial.println(" Monday");
break;
case 3:
Serial.println(" Tuesday");
break;
case 4:
Serial.println(" Wednesday");
break;
case 5:
Serial.println(" Thursday");
break;
case 6:
Serial.println(" Friday");
break;
case 7:
Serial.println(" Saturday");
break;
}
// Serial.println(dayOfWeek, DEC);
delay(1000);
}
/* To access the RAM (65 bytes)
void WriteRam(int address,byte data){
Wire.beginTransmission(0x68); // Select DS1307
Wire.send(address+8); // address location starts at 8, 0-6 are date, 7 is control
Wire.send(data); // send data
Wire.endTransmission();
}
*/
/*
//12 hours:
void setDateDs1307
….
Wire.send(decToBcd(hour) | _BV(6)); // set bit 6 for 12 hour mode
void getDateDs1307:
….
*hour = bcdToDec(Wire.receive() & 0x1f); // mask output for 12 hour mode
*/
//----------
Below a program that will make the SQW/PWM pin flash at several frequencies (but your eyes won't see it at the higher frequencies) /*
DS1307 Square-wave machine
Used to demonstrate the four different square-wave outputs from Maxim DS1307
See page nine of data sheet for more information
John Boxall - tronixstuff.wordpress.com
Register:
OUT 0 0 SQWE 0 0 RS1 RS2
*/
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68 // each I2C object has a unique bus address, the DS1307 is 0x68
void setup()
{
Wire.begin();
}
void sqw1() // set to 1Hz
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0x07); // move pointer to SQW address
Wire.send(0x10); // sends 0x10 (hex) 00010000 (binary)
Wire.endTransmission();
}
void sqw2() // set to 4.096 kHz
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0x07); // move pointer to SQW address
Wire.send(0x11); // sends 0x11 (hex) 00010001 (binary)
Wire.endTransmission();
}
void sqw3() // set to 8.192 kHz
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0x07); // move pointer to SQW address
Wire.send(0x12); // sends 0x12 (hex) 00010010 (binary)
Wire.endTransmission();
}
void sqw4() // set to 32.768 kHz (the crystal frequency)
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0x07); // move pointer to SQW address
Wire.send(0x13); // sends 0x13 (hex) 00010011 (binary)
Wire.endTransmission();
}
void sqwOff()
// turns the SQW off
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0x07); // move pointer to SQW address
Wire.send(0x00); // turns the SQW pin off
Wire.endTransmission();
}
void loop()
{
sqw1();
delay(5000);
sqw2();
delay(5000);
sqw3();
delay(5000);
sqw4();
delay(5000);
sqwOff();
delay(5000);
}
No comments:
Post a Comment