CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Another DS1307 driver
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
Phil



Joined: 09 Sep 2003
Posts: 12

View user's profile Send private message

Another DS1307 driver
PostPosted: Wed Jun 15, 2005 8:48 am     Reply with quote

I've found some Ds1307 code from Tullos and changed it to work easier for my application. It's a very basic driver just for setting and reading the date & time. Tested on PIC 18F452 with hardware I2C, hope some people will find it usefull.

Code:


////////////////////////////////////////////////////////////////////////////////
///                               DS1307.C                                   ///
///                     Driver for Real Time Clock                           ///
///                                                                          ///
/// ds1307_init() - Enable oscillator without clearing the seconds register -///
///                 used when PIC loses power and DS1307 run from 3V BAT     ///
///               - Disable squarewave output                                ///
///                                                                          ///
/// ds1307_set_date_time(day,mth,year,dow,hour,min,sec)  Set the date/time   ///
///                                                                          ///
/// ds1307_get_date(day,mth,year,dow)               Get the date             ///
///                                                                          ///
/// ds1307_get_time(hr,min,sec)                     Get the time             ///
///                                                                          ///
////////////////////////////////////////////////////////////////////////////////

#define RTC_SDA  PIN_C4
#define RTC_SCL  PIN_C3

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)

BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);

void ds1307_init(void)
{
   BYTE seconds = 0;

   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x00);      // REG 0
   i2c_start();
   i2c_write(0xD1);      // RD from RTC
   seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307
   i2c_stop();
   seconds &= 0x7F;

   delay_us(3);

   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x00);      // REG 0
   i2c_write(bin2bcd(seconds));     // Start oscillator with current "seconds value
   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x07);      // Control Register
   i2c_write(0x80);     // Disable squarewave output pin
   i2c_stop();

}

void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec)
{
  sec &= 0x7F;
  hr &= 0x3F;

  i2c_start();
  i2c_write(0xD0);            // I2C write address
  i2c_write(0x00);            // Start at REG 0 - Seconds
  i2c_write(bin2bcd(sec));      // REG 0
  i2c_write(bin2bcd(min));      // REG 1
  i2c_write(bin2bcd(hr));      // REG 2
  i2c_write(bin2bcd(dow));      // REG 3
  i2c_write(bin2bcd(day));      // REG 4
  i2c_write(bin2bcd(mth));      // REG 5
  i2c_write(bin2bcd(year));      // REG 6
  i2c_write(0x80);            // REG 7 - Disable squarewave output pin
  i2c_stop();
}

void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
{
  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x03);            // Start at REG 3 - Day of week
  i2c_start();
  i2c_write(0xD1);
  dow  = bcd2bin(i2c_read() & 0x7f);   // REG 3
  day  = bcd2bin(i2c_read() & 0x3f);   // REG 4
  mth  = bcd2bin(i2c_read() & 0x1f);   // REG 5
  year = bcd2bin(i2c_read(0));            // REG 6
  i2c_stop();
}

void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x00);            // Start at REG 0 - Seconds
  i2c_start();
  i2c_write(0xD1);
  sec = bcd2bin(i2c_read() & 0x7f);
  min = bcd2bin(i2c_read() & 0x7f);
  hr  = bcd2bin(i2c_read(0) & 0x3f);
  i2c_stop();

}

BYTE bin2bcd(BYTE binary_value)
{
  BYTE temp;
  BYTE retval;

  temp = binary_value;
  retval = 0;

  while(1)
  {
    // Get the tens digit by doing multiple subtraction
    // of 10 from the binary value.
    if(temp >= 10)
    {
      temp -= 10;
      retval += 0x10;
    }
    else // Get the ones digit by adding the remainder.
    {
      retval += temp;
      break;
    }
  }

  return(retval);
}


// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
  BYTE temp;

  temp = bcd_value;
  // Shifting upper digit right by 1 is same as multiplying by 8.
  temp >>= 1;
  // Isolate the bits for the upper digit.
  temp &= 0x78;

  // Now return: (Tens * 8) + (Tens * 2) + Ones

  return(temp + (temp >> 2) + (bcd_value & 0x0f));
}


Example use:
Code:

#include <18F452.h>
#device adc=8
#fuses NOWDT,WDT128,HS, NOPROTECT, NOOSCSEN, BROWNOUT, BORV20, NOPUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use delay(clock=20000000,RESTART_WDT)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PC,errors)
#include <ds1307.c>

void main()
{
  BYTE sec;
  BYTE min;
  BYTE hrs;
  BYTE day;
  BYTE month;
  BYTE yr;
  BYTE dow;
 
  ds1307_init();
 
  // Set date for -> 15 June 2005 Tuesday
  // Set time for -> 15:20:55
  ds1307_set_date_time(15,6,5,2,15,20,55);
 
  while(1)
  {
    delay_ms(1000);
   
    ds1307_get_date(day,month,yr,dow);
    ds1307_get_time(hrs,min,sec);
     
    printf("\f\%02d/\%02d/\%02d\r\n",day,month,yr);
    printf("\%02d:\%02d:\%02d", hrs,min,sec);
  }
}
Charles Linquist



Joined: 07 May 2005
Posts: 28
Location: Campbell, CA

View user's profile Send private message

PostPosted: Sun Jun 19, 2005 10:45 pm     Reply with quote

When I try to compile the code, on the line

#use I2C(master,sda=RTC_SDA, scl=RTC_SCL)


I get the error:

Use parameter is out of range: Not a number PIN_C4

Does anyone know why I would be getting this error?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 19, 2005 11:19 pm     Reply with quote

In this thread, you suggest that your next project will use a 16F818.
http://www.ccsinfo.com/forum/viewtopic.php?t=23222
The 16F818 has no Port C, so the compiler gives an error if you specify
pins PIN_C3 and PIN_C4 in the #use i2c() statement.
Charles Linquist



Joined: 07 May 2005
Posts: 28
Location: Campbell, CA

View user's profile Send private message

PostPosted: Sun Jun 19, 2005 11:26 pm     Reply with quote

Don't know where you got that idea. The only chip I use is a 18F8720, although I have used an 18F452 in the past.

I changed the header file to

#include <18F8720.h>

No luck.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 20, 2005 12:13 am     Reply with quote

It compiled OK for me. I saved the first portion as ds1307.c and
put it in the project folder. I saved the 2nd portion as Test.c and
it also went in the project folder. It gave an error on the #fuses
statement because the 18F8720 has different fuses than the 18F452,
so I commented out that statement for the purposes of this test.

The only change to the 2nd portion of code was to change 18F452.h to
18F8720.h as shown below. If you still get the error, then check
your 18F8720.h file and make sure that PIN_C3 and PIN_C4 are
defined in it.

Code:

#include <18F8720.h>
#device adc=8
//#fuses NOWDT,WDT128,HS, NOPROTECT, NOOSCSEN, BROWNOUT, BORV20, NOPUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use delay(clock=20000000,RESTART_WDT)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PC,errors)
#include <ds1307.c>

void main()
{
densimitre



Joined: 21 Dec 2004
Posts: 45

View user's profile Send private message

PostPosted: Wed Apr 25, 2007 11:14 am     Reply with quote

Charles Linquist wrote:
When I try to compile the code, on the line

#use I2C(master,sda=RTC_SDA, scl=RTC_SCL)


I get the error:

Use parameter is out of range: Not a number PIN_C4

Does anyone know why I would be getting this error?


put following code:

Code:
#include <ds1307.h>
#use I2C(MULTI_MASTER,sda=RTC_SDA, scl=RTC_SCL)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PC,errors)


the compiler read first definitions of ds1307.h file, for use it after in #use I2C..

Try and will see all OK when compiling...

by..
rfreddy



Joined: 03 Jun 2007
Posts: 7

View user's profile Send private message

PostPosted: Fri Jun 15, 2007 3:21 pm     Reply with quote

Has anybody tried this code in a 16f877?, I'm actually using on it but I'm unable to set the date and time correctly. Any idea?

Thanks,

Freddy.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jun 15, 2007 3:40 pm     Reply with quote

1. Make sure that you call the ds1307_init() routine.

2. Make sure you have a 3v lithium battery connected between
the Vbat pin and ground.

3. Make sure you have pull-up resistors on SDA and SCL.
Ami



Joined: 02 Sep 2007
Posts: 5
Location: Venezuela

View user's profile Send private message MSN Messenger

where I find ds1307.h?
PostPosted: Sat Sep 22, 2007 9:40 am     Reply with quote

hi, im trying to compile the routine on top, does it works for 18f4550?
hadeelqasaimeh



Joined: 05 Jan 2006
Posts: 105

View user's profile Send private message

PostPosted: Sat Nov 03, 2007 6:44 am     Reply with quote

its work fine with this driver
but this mean i must set clock every run!!!!!!!
how to avoid this?
hadeelqasaimeh



Joined: 05 Jan 2006
Posts: 105

View user's profile Send private message

PostPosted: Sun Nov 04, 2007 11:18 am     Reply with quote

hadeelqasaimeh wrote:
its work fine with this driver
but this mean i must set clock every run!!!!!!!
how to avoid this?


hi ,i replace ds1307 initialization by this
Code:


   output_float(RTC_SCL);
   output_float(RTC_SCL);



and it will not need setting time anymore
any idea?
razorhash



Joined: 10 Jun 2008
Posts: 1

View user's profile Send private message MSN Messenger

Thanks
PostPosted: Wed Jun 25, 2008 5:06 am     Reply with quote

Thanks alot buddy...
Probably the simplest working code Ive seen online..
thanks again..Smile
pattousai



Joined: 23 Aug 2006
Posts: 37

View user's profile Send private message

PostPosted: Tue Aug 19, 2008 7:21 pm     Reply with quote

why the squarewave output pin is disabled in the init() and set_date_time()?

if i want a squarewave of 1Hz i'm only have to replace the
Code:

i2c_write(0x80);

to
Code:

i2c_write(0x01);


is that right?


thanks
Phil



Joined: 09 Sep 2003
Posts: 12

View user's profile Send private message

PostPosted: Wed Aug 20, 2008 5:36 am     Reply with quote

To ENABLE 1Hz squarewave you need to write 0x10 (00010000b), if you check the datasheet you will see that to enable the squarewave output you need to set bit4 in the control REG and for 1Hz output bit0 & bit1 needs to be zero in the control REG!

Regards
pattousai



Joined: 23 Aug 2006
Posts: 37

View user's profile Send private message

PostPosted: Wed Aug 20, 2008 10:21 am     Reply with quote

thanks Phil,

i had check the datasheet, it was just a type error, but thanks again
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group