Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

How to write data ds1307 for 8051

Status
Not open for further replies.

ansh11

Member level 4
Joined
Feb 27, 2018
Messages
71
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
659
I need your help to understand the datasheet

DS1307 Write.jpg

What is the word address ?

Is the word address from here 00H to 3FH

What is Data(n)?

It may be n bytes 0, 1, 2, ..etc

What is Data (n +1)

What is Data (n +x)
 

Attachments

  • DS1307_datasheet.pdf
    348.5 KB · Views: 106

On most I2C devices, once that you have sent the device's unique address, and will send the register's (n) address that you would like to write into.

If more than one byte will be written, you can start to sequentially send bytes which will be written in register addresses n, n+1, n+2, and so forth all the way to n+x
 

On most I2C devices, once that you have sent the device's unique address, and will send the register's (n) address that you would like to write into.

If more than one byte will be written, you can start to sequentially send bytes which will be written in register addresses n, n+1, n+2, and so forth all the way to n+x

Sorry still don't understand

It's not real program but does it show what happens


line 21 What happen if slave send A? if A received send next byte but how to send
What happen if slave send N? if N received stop communication
How to pass four Data and check A/N one by one ?
after if condition what should be there ?


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
main()
{
    Address = 0xD0
    second = 0x00
    minute = 0x01
    hour = 0x02
    
    start(); //strat communication 
    
    Write_Time_DS1307(Address, second, minute, hour)
    
}
    start(); // start communication 
    stop();  // stop communication 
    send(data);// send 8 bit data 
 
void Write_Time_DS1307(0xD0, 0x00, 0x01, 0x02)
{
    send(0xD0)
     slave send A/N
    if(A)  // check A/N
    {
        
    }
    
}

 
Last edited:

Hi,

Word address is the address of the first data(register) you want to access.
If you want to access the register for seconds, then the address is "0x00".
Now consider this address as "n".

If you send the next byte (in a steeam), then the address is automatically incremented.
Thus you access address n+1 = 0x01 = the register for minutes.

It's rather straight forward, isn't it?

If you want to access the date register, you start with 0x04...and it becomes auto incremented to 0x05, 0x06....

Klaus

Btw: especially for DS1307 there are more than enough descriptions, examples, even videos...
 

Hi,

Btw: especially for DS1307 there are more than enough descriptions, examples, even videos...

I want to understand information given in datasheet with pseudo code

I am struggling to complete complete Write_Time_DS1307 routine Can you help me to create this

remember I am only asking pseudo code for Write_Time_DS1307
 

Hi,

Then in your pseudo code just do it byte by byte as given in the datasheet.


But your code is weird
In line 10 you call the function with variables ... which is OK.
But in line 17 you use fix values...which makes no sense.

I assume you confuse yourself:
Code:
Address = 0xD0
    second = 0x00
    minute = 0x01
    hour = 0x02
Do you want second (minute, hour..) to be defined as address or as values?

Klaus
 
  • Like
Reactions: ansh11

    ansh11

    Points: 2
    Helpful Answer Positive Rating
Hi,


But your code is weird
In line 10 you call the function with variables ... which is OK.
But in line 17 you use fix values...which makes no sense.Klaus
correction
Code:
 main()
{
    Address = 0xD0
    second = 0x00
    minute = 0x01
    hour = 0x02
    
    start(); //strat communication 
    Write_Time_DS1307(0xD0, 0x00, 0x01, 0x02)
    
}
    start(); // start communication 
    stop();  // stop communication 
    send(data);// send 8 bit data 
 
void Write_Time_DS1307(Address, second, minute, hour)
    
{
    send(0xD0)
     slave send A/N
    if(A)  // check A/N
    {
        
    }

Hi,I assume you confuse yourself:
Code:
Address = 0xD0
    second = 0x00
    minute = 0x01
    hour = 0x02
Do you want second (minute, hour..) to be defined as address or as values?

Klaus

yes I am confused

This means that we send some data to each address
HTML:
	//Address
    Address = 0xD0
    second = 0x00
    minute = 0x01
    hour = 0x02
    
    //Value
    secondValue = 60
    minuteValue = 30
    hourValue = 12
 

Hi,

This means that we send some data to each address

Yes, what else? ...if you want to set the clock.

Btw: "secondValue = 60" is not allowed .... read the datasheet.

Klaus
 

Hi,



Yes, what else? ...if you want to set the clock.

Btw: "secondValue = 60" is not allowed .... read the datasheet.

Klaus

fine Now I have one slave address , three register address and three value

What should function pass from main ?

Code:
Write_Time_DS1307(SecondAddress, secondValue, minuteValue, hourvalue)
or
Code:
Write_Time_DS1307(SecondAddress, minuteAddress, hourAdress,  secondValue, minuteValue, hourvalue)
{
   for (loop)
   {
          SecondAddress =  secondValue;
          minuteAddress =  minuteValue;   
         hourAdress =  hourvalue;
   }
}
 
Last edited by a moderator:

Hi,

What should function pass from main ?

Write_Time_DS1307(SecondAddress, secondValue, minuteValue, hourvalue)
There are many way. But your idea isn't bad.

From figure6 of the datasheet you should transmit:
* device address
* word address
* data (as much as you like)

Now your function's name is "Write_Time_DS1307", thus it "knows" that it wants to access "DS1307", thus the device address is fix.
No need to pass it.
Thus
* word address
* data (as much as you like)

Is a correct way.

Klaus
 
  • Like
Reactions: ansh11

    ansh11

    Points: 2
    Helpful Answer Positive Rating
Hi,

From figure6 of the datasheet you should transmit:
* device address
* word address
* data (as much as you like)


Klaus

assume

* device address = 0x0d
* word address = 0x00
* data = 10, 20, 30 // three data bytes

I have this logic in mind

Code:
Write_Time_DS1307(device address, word address, data)
{
   device address;

   for (n = 0; n <3, n++)
   {
     word address = data  // n = 0, write 10 to word address,   n = 1, write 20 to word address, and  n = 3, write 30 to word address,
   }
}
 

Hi,

* device address = 0x0d
* word address = 0x00
* data = 10, 20, 30 // three data bytes

The values in red are not correct. Please read the datasheet.
Honestly, if you want to work with an IC you need to read it's datasheet. Thoroughly.
We professionals need to read them too. Every day. And we all find it boring.
But there's no way around it.

Your code example makes no sense.
I can not see wow it follows figure6 of the datasheet.

Klaus
 

Hi,

Your code example makes no sense.
I can not see wow it follows figure6 of the datasheet.

Klaus

oh sorry it should be 0xD0

if you seen I am just focusing my attention on function flow. please ignore them for now. I'll fix them later

Code:
    start(); // start communication 
    stop();  // stop communication 
    send(Data);// send 8 bit data 

 main()
{
     device Address = 0xD0
     word address = 0x00	 
    data[3] = (10, 20, 30)
  
    start(); //strat communication 
    Write_Time_DS1307(0xD0, 0x00, data[i] )
    
}

 
void Write_Time_DS1307(device Address, word address, data    
    
{
    send(0xD0)
     slave send A/N
    if(A)  // check A/N
    {
        
    }
}
 
Last edited:

Hi,

Tell me where do you see the difficulty in figure6?
It tells ... from left to right
* send I2C_START
* send I2C_DEVICE_ADDRESS (with the LSB = 0 to tell you want to write data into the Device
* send ACK = 1 (slave will acknowledge with pulling ACK = 0)
* send WORD_ADDRESS (to tell the slave at wich address you want to put your first data)
* send ACK = 1 (slave will acknowledge with pulling ACK = 0)
* send DATA (to tell the slave WHAT to put into the previously given address)
* send ACK = 1 (slave will acknowledge with pulling ACK = 0)
* send DATA (to tell the slave WHAT to put into the next address)
* send ACK = 1 (slave will acknowledge with pulling ACK = 0)
...repeat the last two lines as often as you like = as many DATA bytes you want to transmit
* send I2C_STOP
finished
***************

if you seen I am just focusing my attention on function flow. please ignore them for now. I'll fix them later
I'm not the friend of this. The more often you knowingly repeat this wrong lines, the more it will be burned into your brain .... and the more difficult it will be later recognize them as wrong.
***************

void Write_Time_DS1307(device Address, word address, data
Why did you chage it now?
There was no reason for it, because in post#10 I clearly told you that your way before was correct.
Why do you change "correct" lines, while you don't change "knowingly incorrect" lines.

This way we/you can make no progress.

Klaus
 

Hi,

Tell me where do you see the difficulty in figure6?
It tells ... from left to right
* send I2C_START
* send I2C_DEVICE_ADDRESS (with the LSB = 0 to tell you want to write data into the Device
* send ACK = 1 (slave will acknowledge with pulling ACK = 0)
* send WORD_ADDRESS (to tell the slave at wich address you want to put your first data)
* send ACK = 1 (slave will acknowledge with pulling ACK = 0)

fifth step * send ACK = 1 (slave will acknowledge with pulling ACK = 0)

Code:
 main()
{
    Address = 0xD0
    second = 0x00
   data[3] = (59, 49, 39)

    start(); //strat communication 
    send(0xD0)
    ReceiveACK_NAk(); //receive ACK/NAK from DS1307

   if(ReceiveACK_NAk()= ACK)
	send(0x00)	
   else
	stop();  
	
}

How to check ACK after sending word address 0x00 ?
 

Hi,

How to check ACK after sending word address 0x00 ?
Refer to the 8051 datasheet. I'm not familiar with 8051.

Code:
]main()
{
    [COLOR="#FF0000"]devAddr[/COLOR] = 0xD0
    [COLOR="#FF0000"]addrSecond[/COLOR] = 0x00
    data[3] = ([COLOR="#FF0000"]0x[/COLOR]59, [COLOR="#FF0000"]0x[/COLOR]49, [COLOR="#FF0000"]0x[/COLOR]39) // 59 is not allowed, since it's binary value is 0b0011[COLOR="#FF0000"]1011[/COLOR]

    start(); //strat communication 
    send([COLOR="#FF0000"]devAddr[/COLOR])
    ReceiveACK_NAk(); //receive ACK/NAK from DS1307

   if(ReceiveACK_NAk()= ACK)
	send([COLOR="#FF0000"]addrSecond[/COLOR])	
   else
	stop();  
	
}

Please read through some examples, even here in the forum you will find some.
Then - if there still are questions - please give a link to the document and give detailed information what is clear so far and what is unclear.

I'm away for the next hours.

Klaus
 

You are using functions not defined in the shown code respectively imported from an unknown 8051 library like ReceiveACK_NAk(). Without knowing there exact operation, we can't assess your code snippets.

Presuming ReceiveACK_NAk() also generates one SCL pulse, you must store the result with a single call, not call it twice.
 

Hi,


Code:
]main()
{
    [COLOR="#FF0000"]devAddr[/COLOR] = 0xD0
    [COLOR="#FF0000"]addrSecond[/COLOR] = 0x00
    data[3] = ([COLOR="#FF0000"]0x[/COLOR]59, [COLOR="#FF0000"]0x[/COLOR]49, [COLOR="#FF0000"]0x[/COLOR]39) // 59 is not allowed, since it's binary value is 0b0011[COLOR="#FF0000"]1011[/COLOR]

    
}
Klaus

Slave address and register address will never change

#define devAddr 0xD0
#define addrSecond 0x00

0xD0, 0x00 Is it integer byte or char byte?
 

0xD0, 0x00 Is it integer byte or char byte?
1. The data type is imposed by the argument type of send(). If you had presented complete code instead of snippets, we all would know the answer.
2. Neither "integer byte" nor "char byte" are generic C data types. In so far the question doesn't make much sense.

Obviously, I2C is sending 8 bit data, in most cases interpreted as unsigned. The respective generic C type is unsigned char. byte or uint8 are alias types used for it by some compilers. I notice that you didn't yet reveal which compiler you are using.

Integer constants don't necessarily need a type. You defines e.g. don't prescribe a type. When assigning the constant to a variable or a function argument, automatic type conversion according to C rules takes place.
 

1. The data type is imposed by the argument type of send(). If you had presented complete code instead of snippets, we all would know the answer.


Ok i try to do what you want


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <reg51.h>
 
//Define the Pin for the I2c 
sbit SDA_BUS = P2^0;
sbit SCL_BUS = P2^1;
 
#define I2C_DELAY    50         //Delay for I2c
#define DS1307_ADDRESS  0xD0    //  the device address
#define DS1307_SECONDS  0x00    //  DS1307 register addresses
 
void InitI2c(void);
void StartI2c(void);
void RepeatedStartI2c(void);
void StopI2c(void);
void delay(unsigned int);
unsigned char write_i2c(unsigned char);
 
/* This function provide the delay which is used in clock generation.*/
void delay(unsigned int d)
{
    unsigned int i;
    for(i=0; i<d; i++);
}
 
/*This function  use to make the data line and clock line idle to put the both line high
*/
void InitI2c(void)
{
    SDA_BUS =1;
    SCL_BUS =1;
}
 
/*This function performs the start operation to initiate the communication.
*/
void StartI2c(void)
{
    SDA_BUS  = 1;
    SCL_BUS  = 1;
    delay(I2C_DELAY);
    SDA_BUS  = 0;
    delay(I2C_DELAY);
}
 
/*When master want to stop the communication then it will assert the stop condition to the i2c bus.*/
 
void StopI2c(void)
{
    SCL_BUS  = 0;
    delay(I2C_DELAY/2);
    SDA_BUS  = 0;
    delay(I2C_DELAY/2);
    SCL_BUS  = 1;
    delay(I2C_DELAY/2);
    SDA_BUS  = 1;
    delay(I2C_DELAY);
}
 
/*When master does not want to relaese the control from the bus then it assert the repeated
start condition on the i2c bus*/
 
void RepeatedStartI2c()
{
    SCL_BUS  = 0;
    delay(I2C_DELAY/2);
    SDA_BUS  = 1;
    delay(I2C_DELAY/2);
    SCL_BUS  = 1;
    delay(I2C_DELAY/2);
    SDA_BUS  = 0;
    delay(I2C_DELAY);
}
 
//send a byte and get ack 
unsigned char write_i2c(unsigned char byte);
{
     unsigned char i, ack_bit;
    
     for (i = 0; i < 8; i++) {
        if ((byte & 0x80) == 0)
            SDA_BUS = 0;
        else
            SDA_BUS = 1;
        SCL_BUS = 1;
        SCL_BUS = 0;
        byte<<=1;
     }
 
     SDA_BUS = 1;
     SCL_BUS = 1;
     ack_bit = SDA_BUS;
     SCL_BUS = 0;
 
     return ack_bit;
}
void main ()
{
    InitI2c();
    StartI2c();
 
    ACK = write_i2c(unsigned char DS1307_SECONDS);;
    
}

 
Last edited:

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top