REAL-TIME CLOCKS                                                                      Jan 06, 2005
App Note 3449: Interfacing a DS1302 With an 8051-
             Type Microcontroller
         This application describes how to interface a DS1302 RTC using the 3-wire
         interface to an 8051-type microcontroller. The example includes a schematic
         and example software written in C.
DS1302 Pin Assignment
Description
This application note demonstrates how to interface a DS1302 real-time clock to an 8051-type
microcontroller and provides example code showing basic interface routines. The microcontroller
used in this example is the DS2250, and the software is written in C.
Operation
The program uses three general-purpose port pins on the microcontroller to control the 3-wire
synchronous bus. The microcontroller initiates a data transfer by sending a command byte to the
DS1302. The microcontroller then sends additional data and/or SCLKs to the DS1302, which
transmits or receives data based upon the command byte.
The software is shown in Figure 1. A schematic of the circuit is shown in Figure 2.
Figure 1. Program Listing (Download ZIP file)
For Larger Image
Figure 2. Schematic of DS1302 RTC
More Information
DS1302: QuickView -- Full (PDF) Data Sheet -- Free Samples
                      CON1
                                     5        GND
                                     9
                                     4        DTR
                                     8
                                     3        RX
                                     7
                                     2        TX
                                     6
                                     1                           C1                                                                    C2
                                                                 22pF                                                                  22pF
                        DB9                                                                               X1
                                                                                                      14.7456MHz
                                                                                        U2
                                                                        RST       17    RST                         24   PSEN                                          VCC
                                                                                                            PSEN
                                                        + C5                      37    X1                          35
                             +                                                                                X2
                                  C4                      10uF       VCC         20     EA                   ALE 22      ALE
                                  10uF                           CE               4     P0.0(AD0)                 40                                   C7
                                                                                                        P2.0 (A8)                                     0.1uF
                                                                 I/O                6   P0.1(AD1)                 38
                                                                                                        P2.1 (A9)
                                                                 SCLK               8   P0.2(AD2)                 36
                            2 6           VCC                                                          P2.2 (A10)
                                                                 AD3              10    P0.3(AD3)                 34
                                     16                                                                P2.3 (A11)                                                                  U?
                                                                 AD4              12    P0.4(AD4)                 32
                        V+                  U1                                                         P2.4 (A12)                                                                                   8
                                                                 AD5              14    P0.5(AD5)                 30                                                           1   VCC2     VCC1
                                                                                                       P2.5 (A13)                                                                                   7
 RX             13               VCC R2OUT 12 RXD                AD6              16    P0.6(AD6)                 28                                                           2   X1                     SCLK
                     R1IN                                                                              P2.6 (A14)                                                                           SCLK
 DTR             8                    T1OUT 9 DTRb               AD7              18    P0.7(AD7)                 26                                                           3   X2         I/O   6     I/O                   C?
                     R2IN                                                                              P2.7 (A15)                                                                                   5
 TXD            11   T1IN             T2OUT 14 TX                                   1   P1.0                      19      RXD              X2                                  4   GND        CE          CE                    0.47F
                                                                                                       P3.0(RXD)
GND             10   T2IN                C1- 7                                      3   P1.1                      21      TXD              32,768Hz
                                                  R1OUT                                                P3.1(TXD)
                 1   C1+                 C2- 3                                      5   P1.2                        23                                                             DS1302
                     C2+                                                                               P3.2(INT0)
                 4                      GND 5                                       7   P1.3                        25
                                   V-                                                                  P3.3(INT1)
                                                                                    9   P1.4                        27
                            15                                                                           P3.4(T0)
        + C3                             DS232A(16)                               11    P1.5                      29
                                                                                                         P3.5(T1)
          10uF                                                                    13    P1.6                        31
                                                                                                        P3.6(WR)
                                                                                  15    P1.7                        33
                                                                                                        P3.7(RD)
                                                                                        DS2250T32-12(40)
                                                    +     C6
                                                         10uF                         VCC
                                                                                                                                     AC1
                                                                               AD0
                                                                               AD1
            A                                                                  AD2                                                                                        U4
                 PSEN                                                                                                                      D5
                                                VCC                            AD3               J1                                                                       7805
                                                                                                                                                                                                                      VCC
                                                3                              AD4                                                                            +    1
                     D4                                                                                                   -                                                  Vin            Vout    3
                     1N914                                                     AD5
        K                                                                      AD6              9V AC IN                       AC2                    C8                                                      C9        C10         C11
 DTRb                                     2             Q1                     AD7                                                         BRIDGE     68uF        R5                                          100uF     0.1uF       0.1uF
                             R3                         2N2907                PSEN                                                                                4.7K             2
                                               1                                                                                                                                                        GND
                            1K ohm
                                                        RST                          R4
                                                                                     4.7K
                                                                                                                                                                         D3
                                                                                                                                                                         LED
Figure 1: Program Listing
/******************************************************************/
/* DEMO1302.C
*/
/******************************************************************/
/* This prgm is for eg only and is not supported by Dallas Maxim */
#include <stdio.h>
#include <DS5000.h>           /* Register declarations for DS5000 */
sbit CE    = P0^0;
sbit SCLK = P0^1;
sbit IO    = P0^2;
/****************************************************************/
/* Prototypes
*/
/****************************************************************/
uchar     rbyte_3w();
void reset_3w();
void wbyte_3w(uchar);
void writebyte();
void write_clk_regs();
void read_clk_regs();
void burstramrd();
void burstramwr();
/****************************************************************/
void reset_3w()     /* reset and enable the 3-wire interface --- */
{
   SCLK = 0;
   CE = 0;
   CE = 1;
}
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
void wbyte_3w(uchar W_Byte)   /* write one byte to the device   */
{
     uchar i;
     for(i = 0; i < 8; ++i)
     {
          IO = 0;
          if(W_Byte & 0x01)
          {
               IO = 1;   /* set port pin high to read data */
          }
          SCLK = 0;
          SCLK = 1;
          W_Byte >>= 1;
       }
}
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
uchar     rbyte_3w()     /* read one byte from the device --- */
{
uchar i; uchar R_Byte; uchar TmpByte;
     R_Byte = 0x00;
     IO = 1;
     for(i = 0; i < 8; i++)
     {
          SCLK = 1;
          SCLK = 0;
          TmpByte = (uchar)IO;
          TmpByte <<= 7;
          R_Byte >>= 1;
          R_Byte |= TmpByte;
     }
     return R_Byte;
}
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
void writebyte()    /*write one byte using values entered by user   */
{
uchar ClkAdd; uchar ClkData;
    /* Get Clock Address & Data */
    printf("\nEnter register write address (hex): ");
    scanf("%bx", &ClkAdd);
    printf("Enter data (hex): ");
    scanf("%bx", &ClkData);
    reset_3w();
    wbyte_3w(ClkAdd);
    wbyte_3w(ClkData);
    reset_3w();
}
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
void read_clk_regs()     /*loop read & display clock registers - */
{
uchar prev_sec = 99, sec, min, hrs, dte, mon, day, yr;
    printf("\nYr/Mn/Dt Dy Hr/Mn/Sec");
    do   /* Read & Display Clock Registers */
    {
         reset_3w();
         wbyte_3w(0xBF);     /* clock burst */
         sec = rbyte_3w();
         min = rbyte_3w();
         hrs = rbyte_3w();
         dte = rbyte_3w();
         mon = rbyte_3w();
         day = rbyte_3w();
         yr = rbyte_3w();
         reset_3w();
         if(sec != prev_sec) /* print once per second */
         {
         printf("\n%02bX/%02bX/%02bX %02bX", yr, dte, mon, day);
         printf(" %02bX:%02bX:%02bX", hrs, min, sec);
         prev_sec = sec;
         }
    }    while(!RI);
    RI = 0;   /* clear read buffer */
}
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
void burstramrd()   /* read RAM in burst mode --------------- */
{
uchar i;
     printf("\nDS1302 Ram");
    reset_3w();
    wbyte_3w(0xFF);     /* RAM burst read */
    for (i = 0; i < 31; i++)
    {
         if(!(i % 8)) printf("\n");
         printf("%2.bX ", rbyte_3w() );
    }
    reset_3w();
}
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
void burstramwr()   /* write one value entire RAM in burst mode */
{
uchar ramdata; uchar     i;
    printf("\nWrite Ram DATA (HEX):");      /* Get Ram Data */
    scanf("%bx", &ramdata);
    reset_3w();
    wbyte_3w(0xfe);     /* RAM burst write */
    for (i=0; i<31; ++i)
    {
         wbyte_3w(ramdata);
    }
    reset_3w();
}
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
void write_clk_regs()    /*initialize time & date from user entries*/
/* Note: NO error checking is done on the user entries! */
{
uchar    yr, mn, date, dy, hr, min, sec, day;
    printf("\nEnter the year (0-99): ");
    scanf("%bx", &yr);
    printf("Enter the month (1-12): ");
    scanf("%bx", &mn);
    printf("Enter the date (1-31): ");
    scanf("%bx", &date);
    printf("Enter the day (1-7): ");
    scanf("%bx", &dy);
    printf("Enter the hour (1-24): ");
    scanf("%bx", &hr);
    hr = hr & 0x3f;     /* force clock to 24 hour mode */
    printf("Enter the minute (0-59): ");
    scanf("%bx", &min);
    printf("Enter the second (0-59): ");
    scanf("%bx", &sec);
    reset_3w();
    wbyte_3w(0x8e);     /*   control register */
    wbyte_3w(0);        /*   disable write protect */
    reset_3w();
    wbyte_3w(0x90);     /*   trickle charger register */
    wbyte_3w(0xab);     /*   enable, 2 diodes, 8K resistor */
    reset_3w();
    wbyte_3w(0xbe);     /*   clock burst write (eight registers) */
    wbyte_3w(sec);
    wbyte_3w(min);
    wbyte_3w(hr);
    wbyte_3w(date);
    wbyte_3w(mn);
    wbyte_3w(dy);
    wbyte_3w(yr);
    wbyte_3w(0);   /* must   write control register in burst mode */
    reset_3w();
}
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
main (void)    /* --MAIN PROGRAM------------------------------ */
{
uchar     M, M1;
     while (1)
     {
     printf("\nDS1302 build: %s\n", __DATE__);
     printf("CW Clock Write CR Clock Read\n");
     printf("RW RAM Write   RR RAM Read\n");
     printf("W Write byte\n");
     printf("Enter Menu Selection: ");
        M = _getkey();
        switch(M)
        {    case 'C':
             case 'c':
             printf("\rEnter Clock Routine to run:C");
             M1 = _getkey();
            switch(M1)
              {
                 case 'R':
                 case 'r': read_clk_regs();    break;
                 case 'W':
                 case 'w': write_clk_regs();   break;
            }
            break;
            case 'R':
            case 'r':
            printf("\rEnter Ram Routine to run:R");
            M1 = _getkey();
            switch(M1)
            {
                 case 'R':
                 case 'r': burstramrd();   break;
                 case 'W':
                 case 'w': burstramwr();   break;
            }
            break;
            case 'W':
            case 'w': writebyte();   break;
        }
    }
}