View previous topic :: View next topic |
Author |
Message |
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
I2C addressing |
Posted: Mon Jan 30, 2012 1:41 pm |
|
|
Hello again! I've got another problem with I2C. Now I use PIC18F2520 and 24C16(EEPROM). I try to write a single byte at eeprom via master(PIC18F2520) and I had a success. Here is the code:
Code: |
#include <18f2520.h>
#fuses NOMCLR, intrc, nowdt
#use delay(internal=8M)
#use i2c(master, SDA=PIN_C4, SCL=PIN_C3)
void main ()
{
output_high(pin_B7);
delay_ms(3000);
output_low(pin_B7); //just to know when the writing get start.
delay_ms(50);
i2c_start();
i2c_write(0xa0);
i2c_write(0x01); //data address (my attention point)
i2c_write(42);
i2c_stop();
Delay_ms(11);
}
|
But the checksum of data addresses at the EEPROM is much more than 0xff.
When I declare address bigger than 0xFF (for example 0x1E0), the data has placed at address 0xE0. How could I put the data at higher address.
I will check for answers in case someone understood something of my words.
Tnx! |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9177 Location: Greensville,Ontario
|
|
Posted: Mon Jan 30, 2012 3:46 pm |
|
|
You should re-read the datasheet for the eeprom for the correct setup of the address/command/data structure to write and read to the device.
Not to sure where you're getting the 'checksum' info from either.... |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jan 30, 2012 8:01 pm |
|
|
1. Don't write your own EEPROM driver. Use the CCS 2416 driver.
Use #include to include the driver file in your program and then call
the functions in the driver.
When you need a driver, always look in the CCS drivers directory first:
Quote: |
c:\program files\picc\drivers |
2. Most of the commonly asked questions like "how do I write values
to eeprom that are larger than a byte ?" are in the FAQ. The link for
the FAQ is at the top of the forum. Use it. Look in the Memory section. |
|
![](templates/subSilver/images/spacer.gif) |
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
re |
Posted: Tue Jan 31, 2012 7:12 am |
|
|
I know the checksum from the software (IC-prog) via which one I read at the EEPROM. About the drivers I will check in this directory. I hope that there is examples in the program directory. Thank you. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19382
|
|
Posted: Tue Jan 31, 2012 7:48 am |
|
|
Seriously you speak as if there is just one 'checksum'. There are an infinite number of possible checksums. However the commonest used for things like EEPROM's, is CRC16 which _will_ be a 16bit value, so will be 'more than 0xff'. It won't be just an 8bit sum of the bytes, but something more complex...
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
re |
Posted: Tue Jan 31, 2012 11:03 am |
|
|
In datasheet has written: 1byte for device select ; 1byte for data address; 1 or more bytes for data. But one (8bit) byte for 2000 addresses is quiet not enough. So how to apply 8bit byte to 16bit address? Maybe answer seems like this:
Code: |
i2c_write((0xa0|(BYTE)(address>>7))&0xf0);
|
but what this code means?
At driver file it is not explained at all. |
|
![](templates/subSilver/images/spacer.gif) |
jeremiah
Joined: 20 Jul 2010 Posts: 1329
|
Re: re |
Posted: Tue Jan 31, 2012 2:27 pm |
|
|
rikotech8 wrote: | In datasheet has written: 1byte for device select ; 1byte for data address; 1 or more bytes for data. But one (8bit) byte for 2000 addresses is quiet not enough. So how to apply 8bit byte to 16bit address? Maybe answer seems like this:
Code: |
i2c_write((0xa0|(BYTE)(address>>7))&0xf0);
|
but what this code means?
At driver file it is not explained at all. |
The line from the driver is actually:
Code: |
i2c_write((0xa0|(BYTE)(address>>7))&0xfe);
|
The reason for this is because you have more than 256 addresses, so they take the first 3 bits of the 11bit address and group them with the i2c address 0xa0
So the i2c address byte would look like this:
1 0 1 0 X Y Z 0/1
Where X, Y, and Z are the first 3 bits of the 11 bit address and the 0/1 is 0 for writes and 1 for reads
The remaining 8 bits of the address are in the next byte, so for example, say you want to write to address 0x1E0, your i2c bytes would look like this:
10100010 11100000
The bolded part is called the "block address" and is the first 3 bits of the address, while the 11100000 is the remaining 8 bits.
so if you were to put them together: 00111100000, or 0x1E0
All of this is in the data sheet (see section 3.6 for the block address description).
As for the line of code:
Code: |
i2c_write((0xa0|(BYTE)(address>>7))&0xfe);
|
They are taking the device address 0xa0 (or the 1010 at the beginning) and or'ing it with the block address (the address >> 7 positions this), and finally and'ing it with 0xFE to ensure the last bit is 0 (for "write").
The drivers should work as long as you are physically connected. The thing I absolutely hate about the drivers is that they can get caught in an infinite loop if something goes wrong with the physical connection or chip. That said, they should still work if you are setup correctly.
The trick with the driver is to make sure to define:
EEPROM_SDA
EEPROM_SCL
in your code BEFORE including the driver or it will set the PIC pins to PIN_E0 and PIN_E1 specifically. Failing to define those before the inclusion could cause your code not to work. |
|
![](templates/subSilver/images/spacer.gif) |
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Wed Feb 01, 2012 10:44 am |
|
|
Thank you, but there is one more thing.
In data sheet is written: first byte (0xa0) == (0b 1010 0000).
First part(1010) select the type of slave device.
Second part (000) chip select in case we connected more than one devices on the same bus.The wast bit (0) is for write operation.
My question is if we take this 3 bits(X,Y,Z) from the first byte, what happen with the chip select bits? |
|
![](templates/subSilver/images/spacer.gif) |
jeremiah
Joined: 20 Jul 2010 Posts: 1329
|
|
Posted: Wed Feb 01, 2012 11:03 am |
|
|
For that particular chip, they don't let you do that. They took out the chip select functionality of those 3 bits and made them "block address" select instead.
So you can only use one of those type of EEPROM on the I2C bus. If you read through the data sheet, you will see notes where they say pins A0-A2 (the pins normally for the chip select part of the address) are not used at all. |
|
![](templates/subSilver/images/spacer.gif) |
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Wed Feb 01, 2012 12:04 pm |
|
|
Oh I see. Thank you very much! |
|
![](templates/subSilver/images/spacer.gif) |
|