Microcontroller › 8051 › RTC DS1307 interfacing with 8051 in C using I2C…….
- This topic has 24 replies, 21 voices, and was last updated 8 years ago by
nagar.
-
AuthorPosts
-
December 1, 2010 at 12:45 pm #484
A.Govindarajan
ParticipantHi…………..
I want to interface DS1307 RTC with 8051 by using I2C protocol.. anybody can help me by giving c code for this?
Thanks…………………………….
December 4, 2010 at 6:37 am #5184dagakshay
Participantfor i2c code in 8051 using c is very betufully used in the interfacing of EEPROM on this site (check the link)….. you might get help from that…
http://www.engineersgarage.com/microcontroller/8051projects/interface-serial-eeprom-24c02-AT89C51
April 22, 2011 at 10:04 am #6018Gaurav
ParticipantHi Govind!
I am using this code and using ds1307 and LCD in my project.Run this one, you’d see the results. B/w I’d be grateful if you can help me with DS12887 rtc. The codes on EG are able to initialize it successfully but aren’t able to update the clock every second. Do you have any idea about this?
Thanks and Regards,
Gaurav
/ interfacing ds1307 with AT89C51
#include<reg51.h>
void _nop_(void);
#define delay_us _nop_(); //generates 1 microsecond
#define LCD P1
sbit RS=P3^0; //connect p3.0 to rs pin of lcd
sbit EN=P3^2; //connect p3.2 to en pin of lcd
sbit RW=P3^1; //connect p3.1 to en pin of lcd
sbit SCK=P2^4; //serial clock pin
sbit SDA=P2^5; //serial data pin
#define SCKHIGH SCK=1;
#define SCKLOW SCK=0;
#define SDAHIGH SDA=1;
#define SDALOW SDA=0;
void integer_lcd(int);
void init_lcd(void);
void cmd_lcd(unsigned char);
void write_lcd(unsigned char);
void display_lcd(unsigned char *);
void delay_ms(unsigned int);
void start(void);
void stop(void);
void send_byte(unsigned char);
unsigned char receive_byte(unsigned char);
void write_i2c(unsigned char,unsigned char,unsigned char);
unsigned char read_i2c(unsigned char,unsigned char);
//clock[]={seconds,minutes,hours,day_of_week,date,month,year};
unsigned char clock[]={0x00,0x40,0x17,0x06,0x24,0x03,0x06};
unsigned char *s[]={“SUN”,”MON”,”TUE”,”WED”,”THU”,”FRI”,”SAT”};
unsigned char slave_ack,add=0,c,k;
unsigned int num;
// Real Time Clock Mode
void main(void)
{
init_lcd();
//cmd_lcd(0x01);
//display_lcd(“UTL”);
//delay_ms(1000);
while(add<=6) //update real time clock
{
write_i2c(0xd0,add,clock[add]);
add++;
}
// stop();
while(1)
{
c=read_i2c(0xd0,0x02);//read hours register and display on LCD
write_lcd((c/16)+48);
write_lcd((c%16)+48);
write_lcd(‘:’);
c=read_i2c(0xd0,0x01);//read minutes register and display on LCD
write_lcd((c/16)+48);
write_lcd((c%16)+48);
write_lcd(‘:’);
delay_ms(10);
c=read_i2c(0xd0,0x00);//read seconds register and display on LCD
write_lcd((c/16)+48);
write_lcd((c%16)+48);
write_lcd(‘ ‘);
display_lcd(s[read_i2c(0xd0,0x03)]);//read day register and display
cmd_lcd(0xc0);
c=read_i2c(0xd0,0x04);//read date register and display on LCD
write_lcd((c/16)+48);
write_lcd((c%16)+48);
write_lcd(‘/’);
c=read_i2c(0xd0,0x05);//read month register and display on LCD
write_lcd((c/16)+48);
write_lcd((c%16)+48);
write_lcd(‘/’);
write_lcd(‘2’);
write_lcd(‘0’);
c=read_i2c(0xd0,0x06);//read year register and display on LCD
write_lcd((c/16)+48);
write_lcd((c%16)+48);
delay_ms(100);
cmd_lcd(0x01);
}
}
//starts i2c, if both SCK & SDA are idle
void start(void)
{
if(SCK==0) //check SCK. if SCK busy, return else SCK idle
return;
if(SDA==0) //check SDA. if SDA busy, return else SDA idle
return;
SDALOW //data low
delay_us
SCKLOW //clock low
delay_us
}
//stops i2c, releasing the bus
void stop(void)
{
SDALOW //data low
SCKHIGH //clock high
delay_us
SDAHIGH //data high
delay_us
}
//transmits one byte of data to i2c bus
void send_byte(unsigned char c)
{
unsigned mask=0x80;
do //transmits 8 bits
{
if(c&mask) //set data line accordingly(0 or 1)
SDAHIGH //data high
else
SDALOW //data low
SCKHIGH //clock high
delay_us
SCKLOW //clock low
delay_us
mask/=2; //shift mask
}while(mask>0);
SDAHIGH //release data line for acknowledge
SCKHIGH //send clock for acknowledge
delay_us
slave_ack=SDA; //read data pin for acknowledge
SCKLOW //clock low
delay_us
}
//receives one byte of data from i2c bus
unsigned char receive_byte(unsigned char master_ack)
{
unsigned char c=0,mask=0x80;
do //receive 8 bits
{
SCKHIGH //clock high
delay_us
if(SDA==1) //read data
c|=mask; //store data
SCKLOW //clock low
delay_us
mask/=2; //shift mask
}while(mask>0);
if(master_ack==1)
SDAHIGH //don’t acknowledge
else
SDALOW //acknowledge
SCKHIGH //clock high
delay_us
SCKLOW //clock low
delay_us
SDAHIGH //data high
return c;
}
//writes one byte of data(c) to slave device(device_id) at given address(location)
void write_i2c(unsigned char device_id,unsigned char location,unsigned char c)
{
do
{
start(); //starts i2c bus
send_byte(device_id); //select slave device
if(slave_ack==1) //if acknowledge not received, stop i2c bus
stop();
}while(slave_ack==1); //loop until acknowledge is received
send_byte(location); //send address location
send_byte(c); //send data to i2c bus
stop(); //stop i2c bus
delay_ms(4);
}
//reads one byte of data(c) from slave device(device_id) at given address(location)
unsigned char read_i2c(unsigned char device_id,unsigned char location)
{
unsigned char c;
do
{
start(); //starts i2c bus
send_byte(device_id); //select slave device
if(slave_ack==1) //if acknowledge not received, stop i2c bus
stop();
}while(slave_ack==1); //loop until acknowledge is received
send_byte(location); //send address location
stop(); //stop i2c bus
start(); //starts i2c bus
send_byte(device_id+1); //select slave device in read mode
c=receive_byte(1); //receive data from i2c bus
stop(); //stop i2c bus
return c;
}
/*display of 16bit(integers) values on LCD
void integer_lcd(int n)
{
unsigned char c[6];
unsigned int i=0;
if(n<0)
{
write_lcd(‘-‘);
n=-n;
}
if(n==0)
write_lcd(‘0’);
while(n>0)//Split integer to 2 bytes and send on 8bit line.
{
c[i++]=(n%10)+48;
n/=10;
}
while(i–>=1)
write_lcd(c);
}*/
//initialize lcd
void init_lcd(void)
{
delay_ms(10); //delay 10 milliseconds
cmd_lcd(0x0e); //lcd on, cursor on
delay_ms(10);
cmd_lcd(0x38); //8 bit initialize, 5×7 character font, 16×2 display
delay_ms(10);
cmd_lcd(0x06); //right shift cursor automatically after each character is displayed
delay_ms(10);
cmd_lcd(0x01); //clear lcd
delay_ms(10);
cmd_lcd (0x80);
}
//transmit command or instruction to lcd
void cmd_lcd(unsigned char c)
{
EN=1;
RW=0;//set enable pin
RS=0; //clear register select pin
LCD=c; //load 8 bit data
EN=0; //clear enable pin
delay_ms(2); //delay 2 milliseconds
}
//transmit a character to be displayed on lcd
void write_lcd(unsigned char c)
{
EN=1; //set enable pin
RW=0;
RS=1; //set register select pin
LCD=c; //load 8 bit data
EN=0; //clear enable pin
delay_ms(2); //delay 2 milliseconds
}
//transmit a string to be displayed on lcd
void display_lcd(unsigned char *s)
{
while(*s)
write_lcd(*s++);
}
//generates delay in milli seconds
void delay_ms(unsigned int i)
{
unsigned int j;
while(i–>0)
{
for(j=0;j<500;j++)
{
;
}
}
}
August 4, 2011 at 5:16 am #6571prabhu462
Participantin abovw program ,DS1307
HOW TO change time and date
and how to display am,pm mode
August 4, 2011 at 5:17 am #6572prabhu462
Participantin abovw program ,DS1307
HOW TO change time and date
and how to display am,pm mode
November 18, 2011 at 10:14 am #6851vairamani
ParticipantHI gaurav i have used your code.
it works well.
thanks for your code.
November 29, 2011 at 9:21 am #6887abcd
Participanthoe do i can set a alarm in DS 1307
im using 4 switches for time set i want to compare my switch value with RTC out values
how can i do it give me an sample code.
November 29, 2011 at 3:31 pm #6888dharmik
Participanthey is it possible to alter the time and date externally as we do in the digital clock??????
November 29, 2011 at 8:10 pm #6889Dexter
Participanti tryed the code
it works well
but not able to chang time .
program is to be modified.
tanx for the code ,( i will try to add switch and alarm in the code)
September 19, 2012 at 12:35 pm #8598Manav Rayamajhee
ParticipantCan anyone post the full circuit?It runs well on proteus but in hardware the circuit does not work at all
October 9, 2012 at 12:27 pm #8654Dexter
Participantplease copy the image to pc and see .
because web page is not able to show that fully .
i put up the screen snap directly
October 22, 2012 at 9:51 am #8682mohammedwaheeduddin
ParticipantCAN U HELP ME REGARDING
C VALUE
AND WRITE_LCD((C/16)+48);
AND WRITE_LCD((C%16)+48);
AND THIS LAST LINES
start(); //starts i2c bussend_byte(device_id+1); //select slave device in read modec=receive_byte(1); //receive data from i2c busstop(); //stop i2c busreturn c;December 10, 2012 at 6:04 pm #8818Tasmiya
ParticipantHey can i please have the full circuit diagram?? it will be really helpful for my project….and thank you for the code!
January 18, 2013 at 8:47 am #8972nidhin.k
Participant/********************************* MAIN PROGRAM START*************************************/#include<reg51.h>#include”lcd8.h”#include”rtcds1307.h”unsigned char i,j,a[10],cur=0;unsigned char sec,hour,min,date,month,year,sec1,hour1,min1,sec2,hour2,min2,hh,mm,ss,dd,mn,yy;unsigned char count[6]={0x86,0x89,0x8c,0xc6,0xc9,0xcc};sbit set=P1^2;sbit mov=P1^3;sbit inc=P1^4;sbit dec=P3^7;sbit ent=P3^6;void all_disp();void time_set();unsigned char dec_hex(unsigned char tt){if(tt>59)tt+=36;else if(tt>49)tt+=30;else if(tt>39)tt+=24;else if(tt>29)tt+=18;else if(tt>19)tt+=12;else if(tt>9)tt+=6;return(tt);}void all_disp(){sec = DS1307_get(SEC);min = DS1307_get(MIN);hour = DS1307_get(HOUR);date = DS1307_get(DATE);month = DS1307_get(MONTH);year = DS1307_get(YEAR);sec=Send2lcd(sec);min=Send2lcd(min);hour=Send2lcd(hour);date=Send2lcd(date);month=Send2lcd(month);year=Send2lcd(year);Lcd8_Decimal2(0x86,date);Lcd8_Write(0x88,’-‘);Lcd8_Decimal2(0x89,month);Lcd8_Write(0x8b,’-‘);Lcd8_Decimal2(0x8c,year);Lcd8_Decimal2(0xc6,hour);Lcd8_Write(0xc8,’.’);Lcd8_Decimal2(0xc9,min);Lcd8_Write(0xcb,’.’);Lcd8_Decimal2(0xcc,sec);}void main(){Lcd8_Init();Lcd8_Display(0x80,”RTC TESTING: “,16);Delay(65000);Delay(65000);Lcd8_Command(0x01);Lcd8_Display(First_Line,”Date:”,5);Lcd8_Display(Second_Line,”Time:”,5);Rtc_Init();//DS1307_setdate(0x04,0x11,0x11);//DS1307_settime(0x16,0x00,0x00);while(1){all_disp();if(!set)time_set();}}void time_set(){Lcd8_Display(0x80,” TIME SET “,16);Lcd8_Display(0xc0,” MODE “,16);Delay(65000);Lcd8_Command(0x01);Lcd8_Display(First_Line,”Date:”,5);Lcd8_Display(Second_Line,”Time:”,5);all_disp();cur=0;while(ent){Lcd8_Command(0x0f);Lcd8_Command(count[cur]);if(mov==0){while(!mov);cur++;if(cur==6)cur=0;}else if(count[cur]==0x86){if(inc==0){while(!inc);date++;if(date>=32)date=1;Lcd8_Decimal2(count[cur],date);}else if(dec==0){while(!dec);date–;if(date==0xff)date=31;Lcd8_Decimal2(count[cur],date);}}else if(count[cur]==0x89){if(inc==0){while(!inc);month++;if(month>=13)month=1;Lcd8_Decimal2(count[cur],month);}else if(dec==0){while(!dec);month–;if(month==0xff)month=12;Lcd8_Decimal2(count[cur],month);}}else if(count[cur]==0x8c){if(inc==0){while(!inc);year++;if(year>99)year=0;Lcd8_Decimal2(count[cur],year);}else if(dec==0){while(!dec);year–;if(year==0xff)year=99;Lcd8_Decimal2(count[cur],year);}}else if(count[cur]==0xc6){if(inc==0){while(inc==0);hour++;if(hour>=24)hour=0;Lcd8_Decimal2(count[cur],hour);}else if(dec==0){while(dec==0);hour–;if(hour==0)hour=23;Lcd8_Decimal2(count[cur],hour);}}else if(count[cur]==0xc9){if(inc==0){while(inc==0);min++;if(min>=60)min=0;Lcd8_Decimal2(count[cur],min);}else if(dec==0){while(dec==0);min–;if(min==0)min=59;Lcd8_Decimal2(count[cur],min);}}else if(count[cur]==0xcc){if(inc==0){while(inc==0);Lcd8_Command(0x0c);sec++;if(sec>=60)sec=0;Lcd8_Decimal2(count[cur],sec);}else if(dec==0){while(dec==0);Lcd8_Command(0x0c);sec–;if(sec==0xff)sec=59;Lcd8_Decimal2(count[cur],sec);}}}Lcd8_Command(0x0c);Lcd8_Display(0x80,” TIME IS “,16);Lcd8_Display(0xc0,” STORED “,16);Delay(65000);Delay(65000);dd=dec_hex(date);mn=dec_hex(month);yy=dec_hex(year);hh=dec_hex(hour);mm=dec_hex(min);ss=dec_hex(sec);DS1307_settime(hh,mm,ss);DS1307_setdate(dd,mn,yy);Lcd8_Command(0x01);Lcd8_Display(First_Line,”Date:”,5);Lcd8_Display(Second_Line,”Time:”,5);Delay(65000);}/********************************* MAIN PROGRAM END*************************************//*********************************LCD HEADER FILE START*************************************/#define First_Line 0x80#define Second_Line 0xc0#define Curser_On 0x0f#define Curser_Off 0x0c#define Clear_Display 0x01#define Data_Port P0sbit Lcd_rs = P2^7;sbit Lcd_rw = P2^6;sbit Lcd_en = P2^5;void Lcd8_Init();void Lcd8_Command(unsigned char);void Lcd8_Write(unsigned char,unsigned char);void Lcd8_Display(unsigned char,const unsigned char*,unsigned int);void Lcd8_Decimal2(unsigned char,unsigned char);void Lcd8_Decimal3(unsigned char,unsigned char);void Lcd8_Decimal4(unsigned char,unsigned int);void Delay(unsigned int);void del();void Lcd8_Init(){Lcd8_Command(0x38); //to select function setLcd8_Command(0x06); //entry mode setLcd8_Command(0x0c); //display onLcd8_Command(0x01); //clear display}void Lcd8_Command(unsigned char com){Data_Port=com;Lcd_en=1;Lcd_rs=Lcd_rw=0;Delay(125);Lcd_en=0;Delay(125);}void Lcd8_Write(unsigned char com,unsigned char lr){Lcd8_Command(com);Data_Port=lr; // DataLcd_en=Lcd_rs=1;Lcd_rw=0;Delay(125);Lcd_en=0;Delay(125);}void Lcd8_Display(unsigned char com,const unsigned char *word,unsigned int n){unsigned char Lcd_i;for(Lcd_i=0;Lcd_i<n;Lcd_i++){Lcd8_Write(com+Lcd_i,word[Lcd_i]);}}void Lcd8_Decimal2(unsigned char com,unsigned char val){unsigned int Lcd_hr,Lcd_t,Lcd_o;Lcd_hr=val%100;Lcd_t=Lcd_hr/10;Lcd_o=Lcd_hr%10;Lcd8_Write(com,Lcd_t+0x30);Lcd8_Write(com+1,Lcd_o+0x30);}void Lcd8_Decimal3(unsigned char com,unsigned char val){unsigned int Lcd_h,Lcd_hr,Lcd_t,Lcd_o;Lcd_h=val/100;Lcd_hr=val%100;Lcd_t=Lcd_hr/10;Lcd_o=Lcd_hr%10;Lcd8_Write(com,Lcd_h+0x30);Lcd8_Write(com+1,Lcd_t+0x30);Lcd8_Write(com+2,Lcd_o+0x30);}void Lcd8_Decimal4(unsigned char com,unsigned int val){unsigned int Lcd_th,Lcd_thr,Lcd_h,Lcd_hr,Lcd_t,Lcd_o;val = val%10000;Lcd_th=val/1000;Lcd_thr=val%1000;Lcd_h=Lcd_thr/100;Lcd_hr=Lcd_thr%100;Lcd_t=Lcd_hr/10;Lcd_o=Lcd_hr%10;Lcd8_Write(com,Lcd_th+0x30);Lcd8_Write(com+1,Lcd_h+0x30);Lcd8_Write(com+2,Lcd_t+0x30);Lcd8_Write(com+3,Lcd_o+0x30);}void Delay(unsigned int del){while(del–);}void del(){Delay(65000);Delay(65000);}/*********************************LCD HEADER FILE END*************************************//*********************************RTC HEADER FILE START*********************************/#define DS1307_ID 0xD0#define SEC 0x00#define MIN 0x01#define HOUR 0x02#define DATE 0x04#define MONTH 0x05#define YEAR 0x06sbit sda_rtc =P1^0;sbit scl_rtc =P1^1;DS1307_get(unsigned char);void DS1307_settime(unsigned char, unsigned char, unsigned char);void DS1307_setdate(unsigned char, unsigned char, unsigned char);Send2lcd(unsigned char);void Rtc_Write(unsigned char,unsigned char);Rtc_Read(unsigned char);void Rtc_rd_wr_sub();void Rtc_Init();void Rtc_Start();void Rtc_Tx();void Rtc_Rx();void Rtc_Stop();void Rtc_Ack();unsigned int Rtc_add_wr,Rtc_add_rd;unsigned char d_rtc,datain_rtc,in_rtc,temp_rtc,dat_rtc,flag_rtc;DS1307_get(unsigned char addr){unsigned char ret;Rtc_Start();ret = Rtc_Read(addr);Rtc_Stop();return ret;}void DS1307_settime(unsigned char hh, unsigned char mm, unsigned char ss){Rtc_Start();Rtc_Write(0x00,ss); /* Write sec on RAM address 00H */Rtc_Write(0x01,mm); /* Write min on RAM address 01H */Rtc_Write(0x02,hh); /* Write hour on RAM address 02H */Rtc_Stop(); /* Stop i2c bus */}void DS1307_setdate(unsigned char dd, unsigned char mm, unsigned char yy){Rtc_Start();Rtc_Write(0x04,dd); /* Write date on RAM address 04H */Rtc_Write(0x05,mm); /* Write month on RAM address 05H */Rtc_Write(0x06,yy); /* Write year on RAM address 06H */Rtc_Stop(); /* Stop i2c bus */}Send2lcd(unsigned char value){unsigned char buf1,buf2,buf = 0;buf1 = value & 0xF0; /* Filter for high byte */buf1 = (buf1>>4); /* Convert to ascii code */buf2 = value & 0x0F; /* Filter for low byte */buf=(buf1*10)+buf2;return buf;}void Rtc_Init()//lower order 256 bytes of the chip{Rtc_add_wr=0xd0;Rtc_add_rd=0xd1;}void Rtc_Write(unsigned char zig,unsigned char zag)// program to write to EEPROM{dat_rtc=zig;temp_rtc=zag;Rtc_rd_wr_sub();above:d_rtc=temp_rtc;Rtc_Tx();if (CY==1)goto above;CY=0;Rtc_Stop();}Rtc_Read(unsigned char zig)// program to read from EEPROM{dat_rtc=zig;Rtc_rd_wr_sub();Rtc_Start();be:d_rtc=Rtc_add_rd;Rtc_Tx();if(CY==1)goto be;Rtc_Rx();Rtc_Ack();CY=0;Rtc_Stop();return(datain_rtc);}void Rtc_Start()// must for any operation on EEPROM{sda_rtc=1;scl_rtc=1;sda_rtc=0;scl_rtc=0;}void Rtc_Stop()// this is similar to the START operation whereas this should be performed after the completion of any operation{sda_rtc=0;scl_rtc=1;sda_rtc=1;}void Rtc_Tx()// program to send the device address, read/write address,data to be written{signed char i_rtc;for(i_rtc=7;i_rtc>=0;i_rtc–)// should necessarily be initialised as signed char.{CY=(d_rtc>>i_rtc)&0x01;sda_rtc=CY;scl_rtc=1;// clock is essential inorder to write or readscl_rtc=0;// clk should be alternated}sda_rtc=1;scl_rtc=1;CY=sda_rtc;scl_rtc=0;}void Rtc_Rx()// program read the data from the EEPROM{unsigned char l_rtc;sda_rtc=1;for (l_rtc=0;l_rtc<=7;l_rtc++){scl_rtc=1;in_rtc=in_rtc<<1;in_rtc|=sda_rtc;scl_rtc=0;}datain_rtc=in_rtc;in_rtc=0;}void Rtc_Ack()// this is to intimate the EEPROM that the read operation is over{sda_rtc=1;scl_rtc=1;scl_rtc=0;}void Rtc_rd_wr_sub()// this routine will be used by both the read & write operations to send the device address & the address at which the corresponding action is to be taken{Rtc_Start();here1:d_rtc=Rtc_add_wr;// device address is passedRtc_Tx();if(CY==1)goto here1;again1:d_rtc=dat_rtc;// the address from which data is to be read/written is to be passedRtc_Tx();if(CY==1)goto again1;}/*********************************RTC HEADER FILE END*********************************/January 18, 2013 at 9:49 am #8973nidhin.k
ParticipantIn the above program, we can change the time and date using keypad.
-
AuthorPosts
- You must be logged in to reply to this topic.