• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

real time clock ds1307 interfacing with 8051

Papabravo

Well-Known Member
How are you connecting the part to the 8051, and why exactly can't you write the code yourself?
 

siprax345

New Member
Ds1307

sir we r using I2C protocol which DS1307 supports but AT89S52 doesnt.
We wrote the code in C but we are not getting whether the communication is goin or not. I can give u the code made by us also to see.
 

siprax345

New Member
Sir this is the code that we made :

#include<AT89X52.h>
#include<abco.h>
#include<Lcddisp.c>
#define ack 0
#define nack 1
#define addrtc 0xd0
//#define DS1307

#define scl P1_1
#define sda P1_2

void i2c_start();
void i2c_stop();
void i2c_write(unsigned char d);
unsigned char i2c_read(unsigned char);
//void read_byte();
//void write_byte();
void disp_clk_regs(unsigned char);
//void ramwrite(unsigned char);
//void ramread();
void initialize();
void i2c_start()
{
sda=1;scl=1;sda=0;
}
void i2c_stop()
{
sda=0;sda=0;sda=0;scl=1;scl=1;sda=1;
}
void i2c_write(unsigned char d)
{
unsigned char i;
scl=0;
for(i=1;i<=8;i++)
{
sda=(d>>7);
scl=1;
d=d<<1;
scl=0;
}
sda=1;
scl=0;
scl=1;
if(sda)
{
disp_string("ACK missing",line1);
disp_val(d,l1col1);
}
scl=0;
}
unsigned char i2c_read(unsigned char b)
{
unsigned char d,i;
sda=1;
scl=0;
for(i=1;i<=8;i++)
{
scl=1;
d=d<<1;
d=d | (unsigned char)sda;
scl=0;
}
sda=b;
scl=0;
scl=1;
if(b==nack) sda=1;
scl=0;
sda=1;
return d;
}
/*void readbyte()
{ unsigned char loc,value;
loc=0x80;
i2c_start();
i2c_write(addrtc);
i2c_write(loc);
i2c_start();
i2c_write(addrtc|1);
value=i2c_read(nack);
i2c_stop();
} */
/*void writebyte()
{
unsigned char address;
address=0x80;
i2c_start();
i2c_write(addrtc);
i2c_write(address);
i2c_write(0x30);
i2c_stop();
} */
void initialize()
{
//unsigned char yr,mon,dt,dy,hr,min,sec;

i2c_start();
i2c_write(addrtc);
i2c_write(0x00);
i2c_write(0x00);
i2c_stop();

i2c_start();
i2c_write(addrtc);
i2c_write(0x00);
i2c_write(0x00);
i2c_write(0x00);
i2c_write(0x50); //01010000
i2c_write(0x04);
i2c_write(0x11);
i2c_write(0x05);
i2c_write(0x06);

//#if defined DS1307
i2c_write(0x10);
//#endif
i2c_stop();
}
void disp_clk_regs(unsigned char prv_sec)
{
unsigned char sec,min,hr,dt,mon,dy,yr,mil,pm;
disp_string("DISP. CLOCK",line1);
i2c_start();
i2c_write(addrtc);
i2c_write(0x00);
i2c_start();
i2c_write(addrtc|1);
sec=i2c_read(ack);
min=i2c_read(ack);
hr=i2c_read(ack);
dy=i2c_read(ack);
dt=i2c_read(ack);
mon=i2c_read(ack);
yr=i2c_read(ack);
i2c_stop();
if(hr&0x40)
mil=0;
else
mil=1;
if(sec!=prv_sec)
{
if(mil)
{

disp_val((hr&0xf0)+0x30,l1col1);
disp_val((hr&0x0f)+0x30,l1col2);
disp_val((min&0xf0)+0x30,l1col3);
disp_val((min&0x0f)+0x30,l1col4);
disp_val((sec&0xf0)+0x30,l1col5);
disp_val((sec&0x0f)+0x30,l1col6);
}
else
{
if(hr&0x20)
pm='A';
else
pm='P';
hr&=0x1f;
disp_val((hr&0xf0)+0x30,l1col1);
disp_val((hr&0x0f)+0x30,l1col2);
disp_val((min&0xf0)+0x30,l1col3);
disp_val((min&0x0f)+0x30,l1col4);
disp_val((sec&0xf0)+0x30,l1col5);
disp_val((sec&0x0f)+0x30,l1col6);}
}
if(prv_sec ==0xfe)
return;
prv_sec=sec;
}
void main()
{
//unsigned char M,M1;
lcd_init();
//#if defined DS1307
disp_string("DS1307 RTC",line1);
// #endif

disp_string("INITIALIZING",line1);
initialize();
disp_string("INITIALIZED",line1);
while(1)
{
/*#if defined DS1307
disp_string("DS1307 RTC",line1);
#endif */
disp_clk_regs(0x99);
clear_disp(line1);
}
}
 

Papabravo

Well-Known Member
That's better now I have a chance. I see that you did write your own code but that it does not work the way you expect it to work. Now I need to know what exactly does not work. Can you help me out here?
 

siprax345

New Member
RE

sir,the problem we are when we start reading from the clcok register the value is not at all incrementing .
We are in dobut that whether the chip is getting the instructions or not coz we tried out 1Hz sqw wavw osc also but it didnt work, we tested the thing using LED at pin7.
We also wrote many debug strings to be displayed in the LCD , the program flow was correct but nothin was happening when we access the clock registers.
How to confirm whether the chip is getting our instructions or not ?
Plz help !
 

Papabravo

Well-Known Member
Let us focus on the following small code fragment

siprax345 said:
Code:
void i2c_write(unsigned char d)
{
	unsigned char i;
	scl=0;
	for(i=1;i<=8;i++)
	{
		sda=(d>>7);
		scl=1;
		d=d<<1;
		scl=0;
	}
	sda=1;
	scl=0;
	scl=1;
	if(sda)
	{
		disp_string("ACK missing",line1);
		disp_val(d,l1col1);
	}
	scl=0;
}
Please tell me what code you think the compiler generates for the line
Code:
  sda=(d>>7) ;
You are taking a byte variable and shifting it to the right by 7 positions and assigning the result to the bit "sda". Is it your intention to set sda equal to the high order bit of the byte. Is that the code that the compiler generated?

Assuming the right value was written to sda, you take the clock high, shift the input byte to the left by one position, then take the clock low. This loop repeats eight times.

At the end of the loop you look for the ACK pulse. Are you getting the ACK pulse?

Can you see the write transaction on an oscilliscope?

That's all for now until we have more information.
 

Papabravo

Well-Known Member
siprax345 said:
sir,the problem we are when we start reading from the clcok register the value is not at all incrementing .
We are in dobut that whether the chip is getting the instructions or not coz we tried out 1Hz sqw wavw osc also but it didnt work, we tested the thing using LED at pin7.
We also wrote many debug strings to be displayed in the LCD , the program flow was correct but nothin was happening when we access the clock registers.
How to confirm whether the chip is getting our instructions or not ?
Plz help !
OK, we're crossing messages. So is there another register besides the incrementing clock that you can read to narrow the problem down to the I2C write transaction or the I2C read transaction. Maybe a status register or an internal RAM location? I will take a look at the data sheet since you may have a hardware problems. Would posting a schematic be out of the question?
 

siprax345

New Member
sir , when slave will be transmitting master (mc) will have to check the ack after 8 bits ? m i right here?
and when master is transmitting, mc will generate the no ack pulse after 8 bits ?
 

Papabravo

Well-Known Member
No I don't have any sample code handy that you can use.
I'm going to assume that your circuit is similar to the one on page 13 of the data sheet.

I think you have a slight misunderstanding of the ACK pulse convention. When the master transmits the slave address(0x1101000), the DS1307 transmits a single ACK bit after receiving 8 bits. Then depending on the state of the R/W bit the process continues for the data bytes.

As near as I can tell the slave always sends an ACK for each 8 bits that the processor sends. When the master is reciving he sends an ACK of each byte except the last one.

Did you attempt to turn on the CH bit in address 0 to enable the oscillator?
 

kinjalgp

Active Member
The other reason why seconds are not incrementing may be that the internal clock to DS1307 is disabed. This is the default state when DS1307 is powered up for the very first time. In the main code read CH bit, if it is 1 make it 0.

This thing is clearly mentioned in the datasheet,
"Please note that the initial power-on state of all registers is not defined. Therefore, it is important to
enable the oscillator (CH bit = 0) during initial configuration."
 
Last edited:

Papabravo

Well-Known Member
So if you have read and write working well enough to access RAM locations then try turning on the CH bit as both of us have mentioned.

If the read and write are still not working then we must look deeper.
 

EE World Online Articles

Loading

 
Top