Interfacing 8051 with ds1307

Status
Not open for further replies.

sanpai

Newbie level 6
Joined
Oct 23, 2012
Messages
11
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Visit site
Activity points
1,367
Hello All,

I'm interfacing DS1307 RTC with 8051 using proteus simulator , I have written the code and the seconds part is working fine but the hour and minutes are showing as 0 and is not getting updated . I believe there's some timing issue or the DS1307 register is not getting updated with hour and minute values . I have attached the proteus file,screenshot of the setup and the code here .

Please let me know where i'm going wrong .

Code:
#include <reg51.h>

#define lcddata P1
sbit SDA= P0^0;
sbit SCL= P0^1;
sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;
sbit BSY = P1^7;


static void I2CInit()
{
  SDA = 1;
  SCL = 1;
}

//I2c start

static void I2CStart()
{
 SCL = 1;
 SDA = 0;
 SCL = 0;
}

static void I2CStop()
{
 SDA = 0;
 SCL = 1;
 SDA = 1;
}

static void I2CAck()
{
 SDA = 0;
 SCL = 1;
 SCL = 0;
}

static void I2CNak()
{
SDA = 1;
SCL = 1;
SCL = 0;
}

static void I2CRestart(){
SDA = 1;
SCL = 1;
SDA = 0;
}

/* routine to send data on the bus */
static unsigned char I2CSend(unsigned char Data)
{
	 unsigned char i, ack_bit;
	 for(i=0;i<8;i++)
	 {
	       SCL = 0;
		   if ((Data & 0x80) == 0)
	       SDA = 0;
		   else
	       SDA = 1;

	       SCL = 1;
	       Data<<=1;
	 }

     SCL = 0;
     ack_bit = SDA;
     SCL = 1;
     SCL = 0;
	 return !ack_bit;
}

/* routine to read the data out of the bus */

static unsigned char I2CRead()
{
	unsigned char i, Data=0;
	for(i=0;i<8;i++)
	{
   	    SCL = 0;
	    SCL = 1;
		if(SDA)
		Data |=1;
		if(i<7)
	    Data<<=1;
	}
   SCL = 0;
   SDA = 1;
	return Data;
}

static void delay(unsigned int);



static void lcd_ready()
{
 //make BSY pin as input 
  BSY=1;
  //Read out from register 
  RS=0;
  //Read
  RW=1;
  while(BSY==1)
  {
    EN=0;
	delay(1);
	EN=1;

  }
}
 
// delay function 
static void delay(unsigned int tme)
{
   unsigned int i,j;
   for(i=0;i<tme;i++)
   for(j=0;j<1275;j++);
}

/* code for sending command to the lcd */

static void lcd_cmd(unsigned char val)
{
  //check for busy flag 
  lcd_ready();
  lcddata=val;
  RS=0;
  RW=0;
  EN=1;
  delay(2);
  EN=0;
}

static void lcd_init()
{
  //16x2 lcd
  lcd_cmd(0x38);
  //clear lcd 
  lcd_cmd(0x01);
  //force the cursor to line 1 
  lcd_cmd(0x80);
   //display on cursor blinking 

   lcd_cmd(0x0E);
}

/* fucntion for transmitting data to the lcd */  
static void lcd_data(unsigned char datum)
{

	  lcd_ready();
	  lcddata=datum;
	  RS=1;
	  RW=0;
	  EN=1;
	  delay(1);
	  EN=0;
 
}

/* code for BCD to ASCII */
static void bcdconv(unsigned char datum)
{
  unsigned char x=0,y=0;
  x=datum&0x0f;
  x=x|0x30;
  y=datum&0xf0;
  y=y>>4;
  y=y|0x30;
  lcd_data(y);
  lcd_data(x);

}


/* main code */
void main()
{

   unsigned char i, a[7];
   unsigned int j;
   I2CInit();
   lcd_init();

/* Writing on i2c */
   I2CStart();
   I2CSend(0xD0);
  
/* first register */

   I2CSend(0x00);

/* seconds  */  
   I2CSend(0x59);
  
/* minutes */
   I2CSend(0x23);
 
/*12-hour mode : need to tick from 3:23 PM */

   I2CSend(0x63);
  
   I2CStop();
   
   while(1)
   {

			I2CStart();
			I2CSend(0xD0);
			I2CSend(0x00);
			/* Actual read */
			I2CRestart();
			I2CSend(0xD1);
			for(i=0;i<3;i++)
			{
			    
				a[i]=I2CRead();
				
				if(i==2)
				I2CNak();
				else
				I2CAck();
			}
			I2CStop();		 
			lcd_cmd(0x81);
			bcdconv(a[2]);
			lcd_data(':');
			bcdconv(a[1]);
			lcd_data(':');
			bcdconv(a[0]);
			for(j=65535;j>0;j--);

   }
    
}
 

Attachments

  • rtc.jpg
    480.4 KB · Views: 73
  • proteus file.rar
    15.3 KB · Views: 55
Last edited:

Have you written hours and minutes values to RTC? Initial value will be 0. Have you connected 3V battery to RTC's VBAT pin?
 
Last edited by a moderator:

Milan

I have attached the proteus binary and the screenshot in the question . I'm grounding the DS1307 battery pin as i'm not using the battery .It was told to be done this way in the datasheet of DS1307 .

As seen in the screenshot only the seconds value is ticking perfectly but the hour and minutes is showing as 0.
 

Battery is needed to hold the set time. If you don't use battery then every time you have to set the time else it will start from 00:00:00. Initially if the RTC was not set to a different value and if there is no battery then you will get this problem. Put battery and set hh:mm to say 2:45 then read RTC and it will display 2:45:00 and if you stop MCU at 2:45 and start it at 2:47 then RTC will show 2:47 as it will be running with the battery even if MCU was off.

Edit: Link for working project. https://saeedsolutions.blogspot.in/2012/11/interfacing-of-8051-with-ds1307-rtc.html
 
Last edited:

Sorry for replying lately,

There was an issue with the timing of the I2c routines due to which the issue used to occur .

I have written the below code , which works perfectly on the microcontroller .

https://pastebin.com/63UWVdmY

Thanks for the help .
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…