Electronic Sculpture Archive
Bruce Cannon

This site is an archive of my older interactive,  electronic and computer-controlled sculpture.  You can always find out about my latest projects via my gateway, brucecannon.com.

   

my_ds1302.c

Code Listing

Below is my driver for using the Dallas Semiconductor DS1302 serial real time clock with Custom Computer Services' PIC C compiler.  There are functions to access the time RAM and the user RAM.

To use this code you will also need my standard header file of convenience labels, my_prefs.h.

As with all my code listings, you may need to copy them to an editor which supports 4-char tabs to see and print them correctly.

/*
09-17-99
Bruce Cannon
Modified CCS DS1302 RTC driver.
Sort of half way between what they did and what I would do if I had more time.
Could use some work.
In general, should call initialize_DS1302() to set up charger and unwrite-protect before
using.  And to be most secure, should write protect after setting.
*/
/****************************************************************************************
Pin labels and data constants.
****************************************************************************************/
#define DS_SCLK RA1
#define DS_IO RA2
#define _DS_RST RA3
//To write to any register use as-is.  To read, make LSB hi (add one):
#define SC_ADDR 0x80
#define MN_ADDR 0x82
#define HR_ADDR 0x84
#define DT_ADDR 0x86
#define MT_ADDR 0x88
#define DY_ADDR 0x8A
#define YR_ADDR 0x8C
#define WRITE_PROTECT 0x8E              //To write to the write-protect bit,
#define PROTECT 128                     //which is bit seven.
#define UNPROTECT 0                     //	"
#define TRICKLE_CHARGER 0x90            //To write to the charger setup register.
#define CLOCK_BURST 0xBE                //To write to all time registers at once.
#define NV_ADDR 0xC0
#define CLOCK_HALT_FLAG 0x80            //If secs reg >= this value, clock stopped.
/****************************************************************************************
Switches.
****************************************************************************************/
#define CHARGE_SETTINGS 0xA6            //Charger enabled, one diode, 4k resistor.
                                        //Rem out to prevent charging (power up default).
/****************************************************************************************
Prototypes.
****************************************************************************************/
void initialize_DS1302();                 //Call after power up.
void write_DS1302(byte cmd, byte data);   //A single data element.
byte read_DS1302(byte cmd);               //	"
void write_DS1302_byte(byte cmd);         //	"
void write_DS_NVR(address,data);          //Write to DS1302's user NVR.
byte read_DS_NVR(address);                //Read from DS1302's user NVR.
/****************************************************************************************
Functions.
****************************************************************************************/
void initialize_DS1302()
{
	output_low(_DS_RST);
	output_low(DS_SCLK);
	write_DS1302(WRITE_PROTECT,UNPROTECT);
	//write_DS1302(TRICKLE_CHARGER,CHARGE_SETTINGS);
	if((read_DS1302(SC_ADDR) >= CLOCK_HALT_FLAG))   //If clock stopped,
	{
		write_DS1302(SC_ADDR,0);                //start it.
	}
}
void write_DS1302_byte(byte cmd)
{
   byte i;
   for(i=0;i<=7;++i)
   {
      output_bit(DS_IO, shift_right(&cmd,1,0) );
      output_high(DS_SCLK);
      output_low(DS_SCLK);
   }
}
void write_DS1302(byte cmd, byte data)
{
   output_high(_DS_RST);
   write_DS1302_byte(cmd);
   write_DS1302_byte(data);
   output_low(_DS_RST);
}
byte read_DS1302(byte cmd)
{
   byte i,data;
   output_high(_DS_RST);
   write_DS1302_byte(cmd | 0x01);                        //Set LSB hi for read request.
   for(i=0;i<=7;++i)
   {
      shift_right(&data,1,input(DS_IO));
      output_high(DS_SCLK);
      delay_us(2);
      output_low(DS_SCLK);
      delay_us(2);
   }
   output_low(_DS_RST);
   return(data);
}
void write_DS_NVR(byte address, byte data)
{
	address <<= 1;                                   //Shift up one bit (LSB is write flag).
	address |= NV_ADDR;                              //Set NVRAM access bits.
	write_DS1302(address, data);                     //Save the value.
}
byte read_DS_NVR(byte address)
{
	address <<= 1;                                   //Shift up one bit (LSB is write flag).
	address |= NV_ADDR;                              //Set NVRAM access bits.
	return(read_DS1302(address));                    //Get the value and pass it back.
}

 

Site contents licensed under a
Creative Commons License.

Creative Commons License