Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] How to code for DS1307 RTC using pic18f87k22

Status
Not open for further replies.

dhakeparag81

Full Member level 2
Joined
Jun 6, 2012
Messages
131
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,298
Location
INDIA
Activity points
2,406
Hello there,

I am working on RTC Ds1307 using pic18f87k22 controller from few days but i dont know where i go wrong.
I search most of the website but didnt get the solution.
Here i post my code can you please trace out where are the problems.
Code:
#include<p18f87k22.h>
#include<i2c.h>

void delay(void);
signed char ack=0;
unsigned char sec=0,min=0,hr=0,day=0,date=0,month=0,year=0;
unsigned char temp=0,temp1=0,temp2=0,i=0;

#pragma interrupt chk_isr         // used for high priority interrupt only.

void chk_isr()
{
	if(PIR1bits.SSP1IF == 1)
    {
	    PIR1bits.SSP1IF=0;
		
	}

}
#pragma code HI_PRIO_INT=0x0008      // high priority interrupt location.

void HI_PRIO_INT(void)
{
  _asm
  goto chk_isr
 _endasm
} 
#pragma code
//-------------

void main(void)
{
	OSCTUNE = 0X80;			//	0xc0 for internal oscillator pll enabled
    OSCCON=0X74;             //16MHz
    OSCCON2=0X00;
	
	ANCON0=0x00;                   // make all analog channel as digital I/O.
    ANCON1=0x00;                   // make all analog channel as digital I/O.
    ANCON2=0x00;

    ODCON1=0x00;
    ODCON2=0x00;
    PADCFG1=0x20; 

    CM1CON=0x00;                    // comparator1 OFF.
    CM2CON=0x00;                    // comparator2 OFF.
    CM3CON=0x00;                    // comparator3 OFF.    
    MEMCONbits.EBDIS=1;

    ADCON0=0x00;                   // make all analog channel as digital I/O.
    CM1CON=0x00;                    // comparator1 OFF.
    CM2CON=0x00;                    // comparator2 OFF.
    CM3CON=0x00;                    // comparator3 OFF.
    
    TRISCbits.TRISC3=1;
    TRISCbits.TRISC4=1;
    OpenI2C1(MASTER,SLEW_OFF);
    //SSP1CON1=0x2b;
     SSP2CON2=0x080;
    SSP1ADD=0x27;	//for 100khz
    
    IdleI2C1();
    
   StartI2C1();
   ack=WriteI2C1(0xD0);
   delay();
   ack=WriteI2C1(0x00);//add   
   ack=WriteI2C1(0x00);
   ack=WriteI2C1(0x05);
   ack=WriteI2C1(0x72);
   ack=WriteI2C1(0x03);
   ack=WriteI2C1(0x11);
   ack=WriteI2C1(0x02);
   ack=WriteI2C1(0x14);
   ack=WriteI2C1(0x00);
   StopI2C1();
  delay();
  delay();
  
    while(1)
    {
	    
	    IdleI2C1();
	     StartI2C1();
   		delay();
   //
	//    StartI2C1();
	    delay();
	    delay();
	    ack=WriteI2C1(0xD1);
	    delay();
	    ack=WriteI2C1(0x00);
	    delay();
	    sec=ReadI2C1();
	    AckI2C1();
	   delay();
	   /* 
	    temp=0;
	    temp1=0;
	    temp2=0x80;
	    
	    for(i=7;i>0;i=i-2)
	    {
		    temp1 = sec & temp2;
		    temp |= (temp1>>i);
		    temp2 >>=1;
		    if(i==1)
		    i=2;
		    //i=i-2;
		} 
		
		 for(i=1;i<8;i=i+2)
	    {
		    temp1 = sec & temp2;
		    temp |= (temp1<<i);
		    temp2 >>=1;
		    //i=i+2;
		} 
	    sec=temp;
	    */
	    
	   
	     delay();
	     min=ReadI2C1();
	   AckI2C1();
	    delay();
	    
	    /* temp=0;
	    temp1=0;
	    temp2=0x80;
	    
	    for(i=7;i>0;i=i-2)
	    {
		    temp1 = min & temp2;
		    temp |= (temp1>>i);
		    temp2 >>=1;
		    if(i==1)
		    i=2;
		    //i=i-2;
		} 
		
		 for(i=1;i<8;i=i+2)
	    {
		    temp1 = min & temp2;
		    temp |= (temp1<<i);
		    temp2 >>=1;
		    //i=i+2;
		} 
		
		
	    min=temp;
	    */
	   
	  
	    delay();
	    hr=ReadI2C1();
	 AckI2C1();
	    delay();
	     
	     /*
	     temp=0;
	    temp1=0;
	    temp2=0x80;
	    
	    for(i=7;i>0;i=i-2)
	    {
		    temp1 = hr & temp2;
		    temp |= (temp1>>i);
		    temp2 >>=1;
		    if(i==1)
		    i=2;
		    //i=i-2;
		} 
		
		 for(i=1;i<8;i=i+2)
	    {
		    temp1 = hr & temp2;
		    temp |= (temp1<<i);
		    temp2 >>=1;
		    //i=i+2;
		} 
	 hr=temp;
			*/
	   	
	   	 
	    delay();
	   
	    day=ReadI2C1();
	    AckI2C1();
	    delay();
	   
	    /* 
	    temp=0;
	    temp1=0;
	    temp2=0x80;
	    
	    for(i=7;i>0;i=i-2)
	    {
		    temp1 = day & temp2;
		    temp |= (temp1>>i);
		    temp2 >>=1;
		    if(i==1)
		    i=2;
		    //i=i-2;
		} 
		
		 for(i=1;i<8;i=i+2)
	    {
		    temp1 = day & temp2;
		    temp |= (temp1<<i);
		    temp2 >>=1;
		    //i=i+2;
		} 
		  day=temp;
	    */
	    
	   
	        delay();

	    date=ReadI2C1();
	    AckI2C1();
	     delay();
	     
	   /*  
	    temp=0;
	    temp1=0;
	    temp2=0x80;
	    
	    for(i=7;i>0;i=i-2)
	    {
		    temp1 = date & temp2;
		    temp |= (temp1>>i);
		    temp2 >>=1;
		    if(i==1)
		    i=2;
		    //i=i-2;
		} 
		
		 for(i=1;i<8;i=i+2)
	    {
		    temp1 = date & temp2;
		    temp |= (temp1<<i);
		    temp2 >>=1;
		    //i=i+2;
		} 
	    date=temp;
	   */
	   
	    
	        delay();

	    month=ReadI2C1();
	    AckI2C1();
	    delay();
	   
	   /* temp=0;
	    temp1=0;
	    temp2=0x80;
	    
	    for(i=7;i>0;i=i-2)
	    {
		    temp1 = month & temp2;
		    temp |= (temp1>>i);
		    temp2 >>=1;
		    if(i==1)
		    i=2;
		    //i=i-2;
		} 
		
		 for(i=1;i<8;i=i+2)
	    {
		    temp1 = month & temp2;
		    temp |= (temp1<<i);
		    temp2 >>=1;
		    //i=i+2;
		} 
	    month=temp;
	    */
	    
	  
	      delay();

	    year=ReadI2C1();
	     NotAckI2C1();
	     delay();
	    
	    /* 
	    temp=0;
	    temp1=0;
	    temp2=0x80;
	    for(i=7;i>0;i=i-2)
	    {
		    temp1 = year & temp2;
		    temp |= (temp1>>i);
		    temp2 >>=1;
		    if(i==1)
		    i=2;
		    //i=i-2;
		} 
		
		 for(i=1;i<8;i=i+2)
	    {
		    temp1 = year & temp2;
		    temp |= (temp1<<i);
		    temp2 >>=1;
		    //i=i+2;
		} 
	    year=temp;
	    
	    */
	//
	 delay();
	 delay();
	    
	} 
    
    
	
}

void delay(void)
{
	unsigned int t=0;
	for(t=0;t<250;t++);
}

I used the internal library of mplabc18 compiler.
 

This is the code I used to interface DS1307 with PIC18F45K22(4MHz Crystal). You can refer this and make the necessary modifications. Change I2C2 to I2C1.

Code:
#include <delays.h>
#include <i2c.h>
#include <stdlib.h>

unsigned char sec, min, hr, week_day, day, mn, year;
unsigned char last_date;

char tnum[4],txt;

void readDS1307(char *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year)
{
    
	StartI2C2();
    	WriteI2C2(0xD0);
	WriteI2C2(0x00);
	RestartI2C2();
	WriteI2C2(0xD1); 

       *sec = ReadI2C2();
	AckI2C2();
	*min = ReadI2C2();
   	AckI2C2();
	*hr = ReadI2C2();
 	AckI2C2();
	*week_day = ReadI2C2();
 	AckI2C2();
	*day = ReadI2C2();
 	AckI2C2();
	*mn = ReadI2C2();
 	AckI2C2();
	*year = ReadI2C2();
	NotAckI2C2();
	StopI2C2();

}


void writeDS1307()
 {
    StartI2C2();	
	WriteI2C2(0xD0);	
	WriteI2C2(0x00);	
	WriteI2C2(0x00);// sec
	WriteI2C2(0x01);//minutes	
	WriteI2C2(0x01);// hours	
	WriteI2C2(0x01);//week_day	
	WriteI2C2(0x15);//date	
    WriteI2C2(0x12);//month	
	WriteI2C2(0x13);//year
	WriteI2C2(0x10);   // REG 7 - Enable squarewave output pin1hz 
	StopI2C2();
	
}


// -------------------- Formats date and time
void Transform_Time(char *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year)
     {
*sec = ((*sec & 0x70) >> 4)*10 + (*sec & 0x0F);
*min = ((*min & 0x70) >> 4)*10 + (*min & 0x0F);
*hr =  ((*hr  & 0x30) >> 4)*10 + (*hr & 0x0F);
*week_day =(*week_day & 0x07);
*day = ((*day  & 0x30) >> 4)*10 + (*day  & 0x0F);
*mn =  ((*mn   & 0x70) >> 4)*10 + (*mn   & 0x0F);
*year =((*year & 0xF0) >> 4)*10 + (*year & 0x0F);

}

void __init(void){
    ANSELA = 0;
    ANSELB = 0;
    ANSELD = 0;
    ANSELC = 0;
    ANSELE = 0;
    ADCON0 = 0;

    
    OpenI2C2(MASTER,SLEW_OFF);
    Delay10KTCYx(25);
    SSP2ADD=39;  //set i2c clock
    
    StartI2C2();
    IdleI2C2();
    Delay10KTCYx(25);
   
   //  writeDS1307();
 
}

void main(void)
{  
   __init();

    while(1){
    
    readDS1307(&sec, &min, &hr, &week_day, &day, &mn, &year);
    Transform_Time(&sec, &min, &hr, &week_day, &day, &mn, &year);
    Delay10KTCYx(25);
}
}

Refer this link:
https://www.edaboard.com/threads/305029/
 
Try with changing

SSPCON1 = 38;

Note:
I think This PIC itself has RTC
 
Last edited:

Thank you for u r time,

The code posted by ADGN working for me.
I made several changes which are require for my controller.
I also change the DS1307 then i able to read the values, may be IC was damage.
But at first i received some random number due to that i am not considering to change DS1307.

- - - Updated - - -

Hello PA3040,

Yes this pic have the RTC but to keep it up to date i have to power (BAT) whole CPU which drain the battery rapidly
instead i prefer to use external RTC and supply battery only to the RTC i think it is more efficient.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top