Increase your Embedded skills with our new online classes (from Just Rs750/-) for details click here

Home > Code Library > RTC ds1307 Interface c Code for pic16F877A

RTC ds1307 Interface c Code for pic16F877A

November 27th, 2009 Leave a comment Go to comments
#if defined(__PCM__)
#include <16F877A.h>
#include <stdio.h>
#include <string.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=6000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif
BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);
#define RTC_SDA  PIN_B1
#define RTC_SCL  PIN_B0
#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)
// RA0 – Enable bit
// RA1 – Register Select bit
// RD0 – RD7   are data pins
int d_sec,d_min,rst1,rst2;
char clk1[10];
////////////////////////////////////////////////////////////////////////////////
///////////////////////////   LCD ROUTINE    ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void init_lcd()
{
unsigned char x[] = { 0×38,0x0c,0×01,0×80,0×06 };
unsigned char i;
for( i = 0 ; i < 5 ; i++ )
{
output_a (0×00);
output_d (x[i]);
output_a (0×01);
delay_us (10);
output_a (0×00);
delay_ms (10);
}
}
void display(char s)
{
output_a (0×02);
output_d (s);
output_a (0×03);
delay_ms (20);
output_a (0×02);
delay_ms (20);
}
////////////////////////////////////////////////////////////////////////////////
///////////////////////////   RTC(DS1307) ROUTINE  /////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void ds1307_init(void)
{
BYTE seconds = 0;
i2c_start();
i2c_write(0xD0);      // WR to RTC
i2c_write(0×00);      // 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(0×00);      // REG 0
i2c_write(bin2bcd(seconds));     // Start oscillator with current “seconds value
i2c_start();
i2c_write(0xD0);      // WR to RTC
i2c_write(0×07);      // Control Register
i2c_write(0×80);     // 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(0×00);            // 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(0×80);            // 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(0×03);            // 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(0×00);            // 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 += 0×10;
}
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 &= 0×78;
// Now return: (Tens * 8) + (Tens * 2) + Ones
return(temp + (temp >> 2) + (bcd_value & 0x0f));
}
////////////////////////////////////////////////////////////////////////////////
///////////////////////////   MAIN PROGRAM   ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void main()
{
BYTE sec;
BYTE min;
BYTE hrs;
BYTE day;
BYTE month;
BYTE yr;
BYTE dow;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
init_lcd ();
display(“HELLO WORLD 2008″);
ds1307_init();                    // Set date for -> 11 MARCH 2008 Tuesday
ds1307_set_date_time(25,3,8,2,11,06,00);    // Set time for -> 15:42:30
while(1)
{
delay_ms(1000);
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
//d_sec = get_data(0); // sec
clk1[5] = (char) (rst1 + 48);
clk1[4] = (char) (rst2 + 48);
clk1[3]=’:';
//d_sec = getdata(0); // min
clk1[2] = (char) (rst1 + 48);
clk1[1] = (char) (rst2 + 48);
clk1[0] = ‘:’;
printf(“\fDATE:\%02d/\%02d/\%02d\r\n”,day,month,yr);
printf(“TIME:\%02d:\%02d:\%02d”, hrs,min,sec);
}
//   while(1);
}

#include <16F877A.h>

#include <stdio.h>

#include <string.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP

#use delay(clock=6000000)

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#endif

BYTE bin2bcd(BYTE binary_value);

BYTE bcd2bin(BYTE bcd_value);

#define RTC_SDA  PIN_B1

#define RTC_SCL  PIN_B0

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

// RA0 - Enable bit

// RA1 - Register Select bit

// RD0 - RD7   are data pins

int d_sec,d_min,rst1,rst2;

char clk1[10];

////////////////////////////////////////////////////////////////////////////////

///////////////////////////   LCD ROUTINE    ///////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

void init_lcd()

{

unsigned char x[] = { 0x38,0x0c,0x01,0x80,0x06 };

unsigned char i;

for( i = 0 ; i < 5 ; i++ )

{

output_a (0x00);

output_d (x[i]);

output_a (0x01);

delay_us (10);

output_a (0x00);

delay_ms (10);

}

}

void display(char s)

{

output_a (0x02);

output_d (s);

output_a (0x03);

delay_ms (20);

output_a (0x02);

delay_ms (20);

}

////////////////////////////////////////////////////////////////////////////////

///////////////////////////   RTC(DS1307) ROUTINE  /////////////////////////////

////////////////////////////////////////////////////////////////////////////////

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

}

////////////////////////////////////////////////////////////////////////////////

///////////////////////////   MAIN PROGRAM   ///////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

void main()

{

BYTE sec;

BYTE min;

BYTE hrs;

BYTE day;

BYTE month;

BYTE yr;

BYTE dow;

setup_adc_ports(NO_ANALOGS);

setup_adc(ADC_OFF);

setup_psp(PSP_DISABLED);

setup_spi(FALSE);

init_lcd ();

display("HELLO WORLD 2008");

ds1307_init();                    // Set date for -> 11 MARCH 2008 Tuesday

ds1307_set_date_time(25,3,8,2,11,06,00);    // Set time for -> 15:42:30

while(1)

{

delay_ms(1000);

ds1307_get_date(day,month,yr,dow);

ds1307_get_time(hrs,min,sec);

//d_sec = get_data(0); // sec

clk1[5] = (char) (rst1 + 48);

clk1[4] = (char) (rst2 + 48);

clk1[3]=':';

//d_sec = getdata(0); // min

clk1[2] = (char) (rst1 + 48);

clk1[1] = (char) (rst2 + 48);

clk1[0] = ':';

printf("\fDATE:\%02d/\%02d/\%02d\r\n",day,month,yr);

printf("TIME:\%02d:\%02d:\%02d", hrs,min,sec);

}

//   while(1);

}

  1. March 9th, 2010 at 20:44 | #1

    u5IQKs Excellent article, I will take note. Many thanks for the article!

  2. April 13th, 2010 at 16:44 | #2

    I like the site.

  3. mali
    May 7th, 2010 at 08:29 | #3

    Hi ,

    I need an immediate help about pic16f877a and ds 1307 project….

    If you dont mind could you send me whole c code file ….

    It is so important for me , I need it as soon as possible

  4. May 7th, 2010 at 14:09 | #4

    i have send the code u check it…

  5. mali
    May 8th, 2010 at 02:12 | #5

    I received your mail thank you .

    But still I have some problem program give 2 errors and doesnt work on proteus simulation program .

    I send a mail to info@embed4u.com , I want to show my proteus design . If you dont mind please help about my design .

    Thankse, best wishes

  6. May 12th, 2010 at 14:41 | #6

    Thank You For This Post, was added to my bookmarks.

  7. May 17th, 2010 at 14:23 | #7

    Very Interesting Post! Thank You For Thi Post!

  8. May 30th, 2010 at 13:41 | #8

    Great Blog. I add this Blog to my bookmarks.

  9. parvo
    May 31st, 2010 at 06:42 | #9

    First of all, this  is a good site you have here. I stumbled upon your web site while doing a search on google. Fantastic blog post, I will probably bookmark it for future reading.

  10. May 31st, 2010 at 15:01 | #10

    You certainly deserve a round of applause for your post and more specifically, your blog in general. Very high quality material

  11. June 1st, 2010 at 14:20 | #11

    I just book marked your blog on Digg and StumbleUpon.I enjoy reading your commentaries.

  12. June 2nd, 2010 at 05:34 | #12

    I find myself coming to your blog more and more often to the point where my visits are almost daily now!

  1. No trackbacks yet.
You must be logged in to post a comment.