Fads to Obsessions and Beyond...




Free domain for life, exceptional technical support, website transfer

DS1307 Real Time Clock (RTC)

A DS1307 Real Time Clock (RTC) is interfaced with a PIC18F248 microcontroller to demonstrate RTC timing functions via RS232 connection to a PC. The programmable square wave output of the DS1307 is used to flash a LED/output waveform on oscilloscope.

A wide variety of projects require maintaining the date/time in order to perform regular functions at pre-determined intervals and or timestamp recorded data. If a microcontroller (e.g., PIC16 or PIC18 etc) is part of the circuit design, the on-chip timers can often be used to perform such functions. However, if such on-chip "peripherals" are required for other purposes, RAM/ROM resources are insufficient and or the date/time is required to be maintained in the event of power down, an external real time clock (RTC) IC is convenient.

The DS1307 RTC is a widely available part and can be sourced very economically even in small quantities. RTC functions include counting seconds, minutes, hours, day of month, month and year with leap-year compensation valid up to 2100. With readily available crystals and standard temperatures, the DS1307 should provide accuracy in the order of 1 minute per month (which can be improved with careful crystal selection, board layout etc if necessary).

Other features of the DS1307 from the datasheet:

    • 56-byte, battery-backed, nonvolatile RAM for data storage
    • I2C interface
    • Programmable squarewave output signal
    • Automatic power-fail detect and switch circuitry - 3v coin cell battery backup
    • Consumes less than 500nA in battery backup mode with oscillator running

See the various sections below for circuit details, schematic diagrams, software/firmware and other details

The schematic for the DS1307 with connections to the PIC18F248 is given in the Schematics Section below. The ancillary circuitry for the PIC18F248 also includes connection via RS232 to a PC (enables PC control of the DS1307 to set parameters and retrieve data).

Power Supply

A typical "wall-wart" power-supply is used (a surplus laptop charger in this case) in conjunction with a voltage regulator (LM317T) to provide the regulated 5V required by the PIC microcontroller.

The DS1307 also requires a 5V supply, which is the same supply as for the PIC microcontroller in this case. Additionally, the DS1307 requires a 3V battery (or equivalent) supply for connection to the DS1307 Vbat pin. This is provided via a 3V "coin" cell.

Firmware/Software

The DS1307 provides simple digital control and a serial interface for retrieval of data using the I2C protocol.

The Testing/Experimental Results Section details the firmware (written in CSS C code) required to enable control of the DS1307 for setting/retreiving the date/time and utilising the square wave output function.


Note: Image loading can be slow depending on server load.

  • DS1307 Basic SchematicDS1307 Basic Schematic

    Silver Membership registration gives access to full resolution schematic diagrams.

    DS1307 Basic Schematic

This project did not require a PCB.

The construction was done using prototyping board. See the photographs and schematic diagram sections.

Qty Schematic Part-Reference Value Notes/Datasheet
Resistors
3R1-R310K1/4W, 10% 
1R43301/4W, 10% 
Diodes
1D1LED
1D21N4002
Integrated Circuits
1U1PIC18F248PIC microcontroller datasheet
1U27805Linear Voltage Regulator  datasheet
1U3DS1307DS1307 RTC datasheet
1U4MAX232ERS232 Driver/Receiver datasheet
Capacitors
2C1,C222pFceramic disk
1C30.33uFaluminium or tantalum electrolytic
1C40.1uFaluminium or tantalum electrolytic
5C6-C101uFaluminium or tantalum electrolytic
Miscellaneous
1J1CONN-H55-pin connector for ICSP
1P1CONN9-pin connector for RS232
1SW1SW-SPDT 
1X110MHzCrystal Oscillator
1X232.678kHzCrystal Oscillator
1BAT13V Battery3V "coin" battery holder
Description Downloads
DS1307 - Bill of Materials Text File Download

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

Description Downloads
DS1307 header and library files: CCS C Code Header File
CCS C Code Library File
Example PIC code with PIC18F248/PC serial interface: CCS C Source Code Download
Hex Code Download

The DS1307 itself is relatively 'forgiving' of mistakes, but double check polarity of power connections etc before powering up the IC.

One important factor in trouble shooting a "misbehaving" DS1307 circuit is to ensure a 3V battery (or similar voltage supply) is connected to the DS1307 Vbat pin. When a 3V battery is connected to the DS1307 and Vcc is below 1.25 x Vbat, reads and writes are inhibited. However, the timekeeping function continues unaffected by the lower input voltage.

As Vcc falls below Vbat the DS1307 RAM and timekeeper are switched over to the external power supply (nominal 3.0V DC) at Vbat. This means without 3V connected to Vbat the DS1307 will not appear to operate even if 5V is connected to Vcc.

The couple of other potential "gotcha's" include:

  • 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. However, the DS1307 registers at power on are undefined (if no battery connected to Vbat). The various routines detailed in the DS1307.c library discussed below enable setting the various DS1307 registers and enabling functions.
  • The internal oscillator circuitry of the DS1307 is designed for operation with a crystal having a specified load capacitance of 12.5pF. Check that the crystal being used has the correct specifications. I found that most run-of-the-mill 32.768kHz "watch" crytals (i.e., cheaply available from eBay) should be sufficient to get the DS1307 to operate. However, the final accuracy of the DS1307 is closely related to crystal quality and meeting the specified load capacitance.

Comments/Questions

No comments yet.

Add Comment/Question

Only Logged-In Members can add comments

"If we could sell our experiences for what they cost us, we'd all be millionaires".

Please donate any amount to help with hosting this web site.

If you subscribe (only $2/annum) you can view the site without advertisements and get emails abouts updates etc.

X

Sorry!

Only logged-in users with correct Membership Level can download.


Membership starts at only $2, so join now!