Initial testing of the DS1307 involves determining if a square wave output is generated at the selected frequency from the SQWOUT pin 7. The initial power on state of all registers in the DS1307 is not defined. This means connection and programming of the DS1307 via I2C/microcontroller is required initially.
Importantly, bit 0 of the "seconds" register (0x00), which is the clock halt (CH) bit, must be cleared (set to 0) to enable the DS1307 RTC oscillator. The various routines detailed in the DS1307.c library discussed below enable setting the various DS1307 registers and enabling functions.
The DS1307 was allowed to operate over night (~12 hours), and even with just a breadboard layout, the time was within a few seconds. If greater accuracy (and or DS1307 running "abnormally" fast or slow) is required, the datasheet and application notes show how crystal load capacitance can be altered to improve accuracy. An appropriate oscillator crystal for the DS1307 is the most important factor in achieving accuracy of the timing.
PIC Microcontroller Interface Code
The following code example shows the simple interface required to control the DS1307. The code enables setting and retrieval of the date/time, start/stop of the RTC and control of
square wave output and frequency via a connected PC (RS232 connection). Additionally, data can be written to and read from the non-volatile battery-backed RAM available in the DS1307.
The PIC micrcontroller code is based upon the CCS routines (1). The code has been modified to provide access to all the functions available from the DS1307.
The DS1307.c library file contains various #define's used to specify the DS1307 command set and functions. Various downloads are available in the table below.
Code Snippet 1: Interface to PIC18F248
#include "DS1307RTC.h"
#include "DS1307.c"
#zero_ram //all variables automatically initialised to 0
void main() {
char recChar; //the received character from the serial port via keyboard
BYTE sec; //variables to store date/time data
BYTE min;
BYTE hrs;
BYTE day;
BYTE month;
BYTE year;
BYTE dow;
signed int8 mode=0; //24hour clock mode
BYTE i; //counter/loop variable
BYTE toggleSQR = 0; //toggle square wave output from RTC SWQ/OUT pin
BYTE toggleRTC = 1; //enabled, toggle RTC oscillator (ie RTC on/off)
BYTE toggleMode = 0;//24 hour
printf("start\n\r");
if (DS1307_isRunning()) {
printf("DS1307 running\r\n");
} else {
DS1307_init();
}
while(TRUE){
if (kbhit()) {
recChar = getc();
switch (recChar) {
case 'd': //dump/list contents of DS1307 RAM
case 'D': for (i=8;i<64;i++) {
printf("%02d,",DS1307_readRAMaddr(i));
}
printf("\r\n");
break;
case 'e': //write to each DS1307 RAM register, store integer i
case 'E': for (i=8;i<64;i++) {
DS1307_writeRAMaddr(i,i);
}
printf("RAM write finished\r\n");
break;
case 'i': //re-initialise DS1307 to default 01/01/2000 00:00:00
case 'I': DS1307_init();
printf("DS1307 re-initialised\r\n");
break;
case 'm': //toggle the clock mode 24 versus 12 hour clock display
case 'M': if (toggleMode) {
toggleMode = 0;
DS1307_setClockMode(DS1307_24HOUR);
printf("24 hour mode\r\n");
} else {
toggleMode = 1;
DS1307_setClockMode(DS1307_AMPM);
printf("AM/PM mode\r\n");
}
break;
case 't': //retrieve and display the time and date
case 'T': DS1307_get_date(day,month,year,dow);
DS1307_get_time(hrs,min,sec,mode);
printf( "\%02d/\%02d/\%02d - ",day,month,year);
printf( "\%02d:\%02d:\%02d ", hrs,min,sec);
switch (mode) {
case -1: printf( "AM\r\n");
break;
case 0: printf( "\r\n");
break;
case 1: printf( "PM\r\n");
break;
}
break;
case 'r': //check if the DS1307 clock oscillator running
case 'R': if (DS1307_isRunning()) {
printf("DS1307 running\r\n");
} else {
printf("DS1307 not running\r\n");
}
break;
case 'w': //toggle the output of the squarewave on SWQOUT pin (1Hz freq)
case 'W': if (toggleSQR) {
toggleSQR=0;
DS1307_setSquareWaveOutput(DS1307_SQW_DISABLE | DS1307_SQW_HZ1 | DS1307_SQWOUT_LOW);
printf("SQR Off RTC\n\r");
} else {
toggleSQR=1;
DS1307_setSquareWaveOutput(DS1307_SQW_ENABLE | DS1307_SQW_HZ1 | DS1307_SQWOUT_LOW);
printf("SQR On RTC\n\r");
}
break;
case 's': //toggle start/stop the RTC
case 'S': if (toggleRTC) {
toggleRTC=0;
DS1307_Run(DS1307_DISABLE);
printf("Disable RTC\n\r");
} else {
toggleRTC=1;
DS1307_Run(DS1307_ENABLE);
printf("Enable RTC\n\r");
}
break;
default: printf("Unknown cmd\n\r");
break;
}
}
}
}
Code Snippet 2: Library File Functions
void DS1307_init()
//Enable RTC oscillator, disable squarewave (default 1Hz)
//set default 01/01/2000 00:00:00 DoW=1, 24 hour mode
void DS1307_setDateTime(day,mth,year,dow,hour,min,sec,mode)
//Set the date/time and clock mode (12/24hour)
void DS1307_getDate(day,mth,year,dow)
//Get the date
void DS1307_getTime(hr,min,sec)
//Get the time
Byte DS1307_readRAMaddr(address)
//Returns data from RAM
void DS1307_writeRAMaddr(BYTE address, BYTE value)
//Write data to RAM
void DS1307_setSquareWaveOutput(BYTE ctrlRegValue)
//Set square wave output and frequency
void DS1307_setClockMode(BYTE mode)
//Set 24 hour or AM/PM clock mode
void DS1307_Run(BYTE mode)
//Start/stop RTC
unsigned int DS1307_isRunning()
//Returns 1 if RTC oscillator on
Downloads
Only Logged-In Members can add comments