RTC ds1307 Interface c Code for pic16F877A
#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,0×0c,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 &= 0×7F;
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 &= 0×7F;
hr &= 0×3F;
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() & 0×7f); // REG 3
day = bcd2bin(i2c_read() & 0×3f); // REG 4
mth = bcd2bin(i2c_read() & 0×1f); // 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() & 0×7f);
min = bcd2bin(i2c_read() & 0×7f);
hr = bcd2bin(i2c_read(0) & 0×3f);
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 *
+ (Tens * 2) + Ones
return(temp + (temp >> 2) + (bcd_value & 0×0f));
}
////////////////////////////////////////////////////////////////////////////////
/////////////////////////// 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);
}
Related posts:
u5IQKs Excellent article, I will take note. Many thanks for the article!
I like the site.
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
i have send the code u check it…
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
Thank You For This Post, was added to my bookmarks.
Very Interesting Post! Thank You For Thi Post!
Great Blog. I add this Blog to my bookmarks.
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.
You certainly deserve a round of applause for your post and more specifically, your blog in general. Very high quality material
I just book marked your blog on Digg and StumbleUpon.I enjoy reading your commentaries.
I find myself coming to your blog more and more often to the point where my visits are almost daily now!
You certainly have some agreeable opinions and views. Your blog provides a fresh look at the subject.
I just book marked your blog on Digg and StumbleUpon.I enjoy reading your commentaries.