RTC ds1307 Interface c Code for pic16F877A
November 27th, 2009
12 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);
}
Categories: Code Library 8051projects.net|embed4u.com, 8051projects/projects|embed4u.com, A PIC Real Time Clock IC (RTC) using the DS1307, A PIC Real Time Clock IC (RTC) using the DS1307 -embed4u.com, c code for ds1307 real time clock with pic microcontroller, C driver for ds13307 with pic16f877a|embed4u.com, DS1307 + PIC16F877A | PIC Microcontroller Note|embed4u.com, Interfacing RTC DS1307 with PIC microcontroller programming with C, kmitl.ac.th/~kswichit/embed4u.com, need help with program to interface DS1307 with 16F877, Pic16f877a interfce with ds1307 c code, Pic16f877a with rtc ds1307 c code, RTC ds1307 Interface c Code for pic16F877A