| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| Phil 
 
 
 Joined: 09 Sep 2003
 Posts: 12
 
 
 
			    
 
 | 
			
				| Another DS1307 driver |  
				|  Posted: Wed Jun 15, 2005 8:48 am |   |  
				| 
 |  
				| 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
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sun Jun 19, 2005 10:45 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sun Jun 19, 2005 11:19 pm |   |  
				| 
 |  
				| 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
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sun Jun 19, 2005 11:26 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon Jun 20, 2005 12:13 am |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Apr 25, 2007 11:14 am |   |  
				| 
 |  
				|  	  | 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Jun 15, 2007 3:21 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Jun 15, 2007 3:40 pm |   |  
				| 
 |  
				| 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
 
 
			      
 
 | 
			
				| where I find ds1307.h? |  
				|  Posted: Sat Sep 22, 2007 9:40 am |   |  
				| 
 |  
				| hi, im trying to compile the routine on top, does it works for 18f4550? |  |  
		|  |  
		| hadeelqasaimeh 
 
 
 Joined: 05 Jan 2006
 Posts: 105
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Nov 03, 2007 6:44 am |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sun Nov 04, 2007 11:18 am |   |  
				| 
 |  
				|  	  | 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
 
 
 
			      
 
 | 
			
				| Thanks |  
				|  Posted: Wed Jun 25, 2008 5:06 am |   |  
				| 
 |  
				| Thanks alot buddy... Probably the simplest working code Ive seen online..
 thanks again..
  |  |  
		|  |  
		| pattousai 
 
 
 Joined: 23 Aug 2006
 Posts: 37
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Aug 19, 2008 7:21 pm |   |  
				| 
 |  
				| 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
 
 to
 
 
 is that right?
 
 
 thanks
 |  |  
		|  |  
		| Phil 
 
 
 Joined: 09 Sep 2003
 Posts: 12
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Aug 20, 2008 5:36 am |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Aug 20, 2008 10:21 am |   |  
				| 
 |  
				| thanks Phil, 
 i had check the datasheet, it was just a type error, but thanks again
 |  |  
		|  |  
		|  |  
  
	| 
 
 | 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
 
 |