Sie sind auf Seite 1von 8

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;
}
}
}

Das könnte Ihnen auch gefallen