CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

register x address

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
nina



Joined: 20 Apr 2007
Posts: 111

View user's profile Send private message Send e-mail

register x address
PostPosted: Thu Mar 12, 2009 1:57 pm     Reply with quote

I have studied ds1307 and also i2c. All documents and articles about it talk about registers and address.
Someone could explain what are registers and address? What they work for?
I have realized some programs with i2c like below:
Code:
i2c_start();
i2c_write(0xd0); ????? why and for what???
i2c_wirte(address); ?????
i2c_write(data); ????? why i have to write data instead of read data????
i2c_stop() ????
i2c_start(); ???? why start again

tks
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Thu Mar 12, 2009 3:23 pm     Reply with quote

In I2C there are certain sequences that need to happen in order for the devices to communicate properly. Each device, such as a eeprom, requires certain commands in order to be written to or to be read from. I'll try to explain your example a little.

i2c_start();
This is the command that the Master, or PIC, uses to tell everybody on the I2C bus that it is taking control of the bus and that they need to pay attention.

i2c_write(0xd0);
After an i2c_start() the Master sends out the address of the device it wants to talk to. In this example the device is at 0xd0. All other devices on the bus will then ignore further commands that are sent on the bus.

i2c_write(address);
This is most likely an eeprom being talked to. This command, issued after the device's address, tells the eeprom what address, inside the eeprom, it wants to access.

i2c_write(data);
This is the actual data that is going to be written to the 'address' inside of the eeprom.

i2c_stop();
The Master issues this command saying that it's either finished talking and realeasing the bus from it's command OR, depending on the device, it's going to take control again to issue further commands to the device, which is does in many eeproms.

i2c_start();
This stop-start sequence can be a requirement for devices, at least with most eeproms that I've used, in order to write data to them.

The sequence that you've entered doesn't appear to be exactly in the correct order but hopefully this explaination helps a bit. Looking at the spec. sheet you will see the exact sequence that needs to be used in order to write data to or read data from the device.

Clear as mud?

Ronald
Ttelmah
Guest







PostPosted: Thu Mar 12, 2009 4:04 pm     Reply with quote

Start with the DS1307 data sheet.

On i2c, each device on the bus, has to have an address. Addresses of 0 to 127, are available, with then certain ones being 'reserved' for special stuff (ignore the bottom 16, and the top one). Manufacturers make their chips either with fixed addresses, or in some cases with addresses that can be changed through a number of values, by altering external pins, or sometimes with a range of values available as 'mask' options from the manufacturer.
For the 1307, you will find in the paragraph at the top of page 7, the line:

"The address byte is the first byte received after the start condition is generated by the master. The address byte contains the 7 bit DS1307 address, which is 1101000, followed by the *direction bit (R/W ) which, for a write, is a 0."

On I2C, each initial transaction carries a direction 'bit'. 0 for a write, and 1 for a read.

So the 1307, requires the first 'address' byte, to be:

1101 0000 for a write
1101 0001 for a read

In Hex, these are 0xD0, and 0xD1

Now, the next part of the I2C transaction.

Basically, with I2C, the byte(s) (more than one for a device that has more than 256 internal 'registers'), following a 'write' address, is the 'register number' to be talked to.

The sequence is:

Send a start.
Send the device address, for write (bottom bit = 0).
Send the register number.

Now, the chip is all set to _write_to specific location.
All you do at this point to _write_, is start sending the data.

However to _read_, you then use what is called a 'repeated start'

Send another start.
Send the device address, with the bottom bit set to _read_.
Start reading the data.

After either the read or write, you send a 'stop' to say you have finished.

Key is this idea, that you can select the 'register number', with a 'write' command, and then turn the bus around, by using the repeated start.

Figure 2, on the data sheet, gives the 'register numbers' used by the chip. 8 bytes for the clock, then 56bytes useable for storage.

The 'minutes' for example, are location 1. So the sequence to read the minutes, becomes:
Code:

i2c_start();
i2c_write(0xd0); //Chip address from the data sheet - write selected
i2c_write(1); //Select register 1
i2c_start(); //Send a restart
i2c_write(0xd1); Chip address - read selected
mins=i2c_read(); //read the minutes
i2c-stop(); //finish the transaction


Now, before you can read the minutes, the clock itself has to be enabled. This is done by clearing the top bit of register number 0. So the code to 'start' the chip, becomes:

Code:

i2c_start();
i2c_write(0xd0); //Chip address from the data sheet - write selected
i2c_write(0); //Select register 0
i2c_write(0); //clear the seconds, to start the clock
i2c-stop(); //finish the transaction


Now, in general, when you read or write to a register, the register number automatically advances to the next register. If you stop a transaction, and start again, the register number selected is retained. So if you combine the two jobs into one, and send a '0' to register 0, then stop, and start selecting 'read', you will get the contents of register 1. This appears to be what your example is doing.

Best Wishes
nina



Joined: 20 Apr 2007
Posts: 111

View user's profile Send private message Send e-mail

i2c
PostPosted: Thu Mar 12, 2009 7:39 pm     Reply with quote

Ttelmah/nielsen...

Thank you very much for all information...it is like that information I have looking for. Great. You explained in a simple way everything I wanted know. I'll read one more time the datasheet ds1307 and pay attention to all the information you gave me.

Just one more question..

Instead of using:
Code:

i2c_start();
i2c_write(0xd0); //Chip address from the data sheet - write selected
i2c_write(1); //Select register 1
i2c_start(); //Send a restart
i2c_write(0xd1); Chip address - read selected
mins=i2c_read(); //read the minutes
i2c-stop(); //finish the transaction


Could I use the code below???
Code:
i2c_start();
i2c_write(0xd1); Chip address - read selected
i2c_write(1); //Select register 1
mins=i2c_read(); //read the minutes
i2c-stop(); //finish the transaction

Thank you very much again.

nina
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Thu Mar 12, 2009 8:59 pm     Reply with quote

You need to do it just as Ttelmah describes with one exception. The statement:

Code:
mins=i2c_read();


needs to have the master send a NACK to notify the DS1307 that the master is finished reading data. So, the command needs to be:

Code:
mins=i2c_read(0);// insert a zero here to send a NACK


You can't make any short cuts. You have to do it exactly as the data sheet describes.

Ronald
Ttelmah
Guest







PostPosted: Fri Mar 13, 2009 3:23 am     Reply with quote

Aargh.
Typing from memory, rather than following the data sheet. Slap slap... naughty boy!....

Rnielsen makes the point, which applies all the way here, data sheet, line by line.

As you see from my post, the data sheet does contain the address details, and the numbers needed to select the registers (and when ACK/NACK is needed...). It is 'just' a matter of following this to the letter. The problem is that the actual 'layout', of what is involved, is not terribly 'obvious', unless you are experienced in I2C.

Best Wishes
Ttelmah
Guest







PostPosted: Fri Mar 13, 2009 3:40 am     Reply with quote

Ongoing, on the question about shortening the sequence, _no_.
The direction byte controls the whole transaction, after the initial address byte. You need to _write_the address, so the 'write' direction needs to be selected. Only after you have written this, can you turn the bus round, and read the bytes at the address. This is why you can't select 'read', and then write the address needed in one go...

Best Wishes
nina



Joined: 20 Apr 2007
Posts: 111

View user's profile Send private message Send e-mail

ds1307
PostPosted: Fri Mar 13, 2009 3:53 am     Reply with quote

telmah

I did not find why I have write (i2c_write(0xd0); //Chip address from the data sheet - write selected)
instead of (i2c_write(0xd1); Chip address - read selected )instead of read

could you show me where datasheet say it, please?


The address byte is the first byte received after the start condition is generated by the master. The address byte contains the 7-bit DS1307 address, which is 1101000, followed by the *direction bit (R/W ) which, for a read, is a 1. After receiving and decoding the address byte the
device inputs an acknowledge on the SDA line. The DS1307 then begins to transmit data starting with the register address pointed to by the register pointer. If the register pointer is not written to before the initiation of a read mode the first address that is read is the last one stored in the register pointer. The DS1307 must receive a “not acknowledge” to end a read.

many tks again
Ttelmah
Guest







PostPosted: Fri Mar 13, 2009 8:47 am     Reply with quote

In the DS1307 sheet, look at the example 'slave receiver mode' transaction (Fig 6). Note that the register address is transferred. Then look at the next paragraph 'slave transmitter mode'. Note that no address is sent. Read the paragraph itself. "After receiving and decoding the address byte the device inputs an acknowledge on the SDA line. The DS1307 then begins to transmit data starting with the register address pointed to by the register pointer. If the register pointer is not written to before the initiation of a read mode the first address that is read is the last one stored in the register pointer.".

Note the words _before the initiation of a read mode_.

The point is that to _write_ the register number pointer, you have to have 'write mode' selected. If you want to read from a particular register, you have to select write mode, and write the register number, then switch to read mode, to read from it. The bus is 'half duplex' (only talks in one direction at a time), so you have to turn it round to read, after writing an address. If you have selected 'read' (0xd1), you can't then write the address (the bus is setup to read from the device).

In the I2C specs, this is covered in the 'combined format' spec.

Best Wishes
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Fri Mar 13, 2009 10:50 am     Reply with quote

In I2C the master needs to send a start() to tell everybody that it's going to start talking. The next thing is to send the address of the device that will be talked to. Now, this address is an 8-bit address with the last bit determining if a Write or a Read is going to happen.

In the sequence that is needed, the address 0xD0 is first sent out on the bus telling the device, at 0xD0, that it needs to pay attention and that data is going to be written to it. 0xD0 is 11010000 in binary. Notice the last bit is a zero(0). This is the 'direction' bit. It tells the device which direction data is going to go. When 0xD1 is sent (11010001) this tells the device that data is going to be read from it.

So, the sequence that the DS1307 requires is:

Code:
i2c_start();// OK, the master is going to talk so pay attention!
i2c_write(0xD0);// hey, whoever is at address 0xD0, i'm talking to you
i2c_write(1);// okay, mr. device, I want to access whatever is inside you at address 1
i2c_start();// i'm sending another restart so i can change the direction of the bus
i2c_write(0xD1)// okay mr. device, i'm still talking to you and i want to READ data from you now
mins = i2c_read(0);// i'm reading whatever data is at internal address 1 from the device PLUS sending a NOACK
i2c_stop();// the master is now finished talking, you can all go back to sleep


Hopefully that might help clear things up a little. According to the spec. sheet, this is the sequence _required_ to read something from the device.

Now, if you wanted to read the Hours you would have sent a 2 instead of a 1 on the second i2c_write(). If you wanted the seconds you would have sent a 0.

Ronald
nina



Joined: 20 Apr 2007
Posts: 111

View user's profile Send private message Send e-mail

ds1307
PostPosted: Fri Mar 13, 2009 12:55 pm     Reply with quote

nielsen / Ttelmah

Thank you very much for all information. Now it very clear what happen with ds1307. That's what I needed to start understand datasheets.

thanks again

nina
Ttelmah
Guest







PostPosted: Fri Mar 13, 2009 3:56 pm     Reply with quote

and of course, if you want to read, the minutes, then the hours, use:
Code:

i2c_start();// OK, the master is going to talk so pay attention!
i2c_write(0xD0);// hey, whoever is at address 0xD0, i'm talking to you
i2c_write(1);// okay, mr. device, I want to access whatever is inside you at address 1
i2c_start();// i'm sending another restart so i can change the direction of the bus
i2c_write(0xD1)// okay mr. device, i'm still talking to you and i want to READ data from you now
mins = i2c_read(); //Don't NACK
hours = i2c_read(0); //Now send the NACK
i2c_stop();// the master is now finished talking, you can all go back to sleep

Having started a read sequence, you can potentially read _all_ the registers in sequence, till you NACK/stop.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group