View previous topic :: View next topic |
Author |
Message |
art
Joined: 21 May 2015 Posts: 181
|
EX_EXTEE.C question (3) |
Posted: Sun Jul 30, 2017 6:00 am |
|
|
Hi,
In EX_EXTEE.C example, I would like to know if I used EEPROM 24LC256
what is the first address and the last address we can write in ?
As I understand it, if pin A0, pin A1 and pin A2 are low, the address we can write in is (0000~7FFF)
How about below condition ?
1) pin A0 high, pin A1 and A2 low
2) pin A1 high, pin A0 and A2 low
3) pin A2 high, pin A0 and A1 low
Hope to get answers for these questions.
Thanks |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Sun Jul 30, 2017 6:26 am |
|
|
The A2,A1,A0 define the address for the chip on the I2C bus, not the EEPROM data memory (32KB).
This allows you to have up to 8 EEPROMs on one I2C bus.
Traditionally, if you only have one device, you program A2,A1,A0 as '0'. Be aware that some devices have internal hardware to do this even if you don't.
Jay |
|
|
art
Joined: 21 May 2015 Posts: 181
|
|
Posted: Sun Jul 30, 2017 6:42 am |
|
|
Hi temtronic,
If i want to use 4 eeprom connected to pic18f4550, do i need to modify #include <24256.c> ? What value should i change? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sun Jul 30, 2017 7:09 am |
|
|
Where it uses 0xA0, and 0xA1, you would need to substitute a variable for the device address. So:
Code: |
void write_ext_eeprom(int8 device_address, long int address, BYTE data)
{
short int status;
i2c_start();
i2c_write(device_address);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
i2c_start();
status=i2c_write(device_address);
while(status==1)
{
i2c_start();
status=i2c_write(device_address);
}
i2c_stop();
}
BYTE read_ext_eeprom(int8 device_address, long int address) {
BYTE data;
i2c_start();
i2c_write(device_address);
i2c_write(address>>8);
i2c_write(address);
i2c_start();
i2c_write(device_address | 1);
data=i2c_read(0);
i2c_stop();
return(data);
}
|
Then when you call the routines, call with the device_address of the chip you want.
So (to match the standard code)
val=read_ext_eeprom(0xA0, address_to_read);
and similarly for the write. |
|
|
art
Joined: 21 May 2015 Posts: 181
|
|
Posted: Sun Jul 30, 2017 7:37 am |
|
|
Ok, if i have 4 eeprom, all 4 eeprom sda will be tied together and same goes to scl. (parallel)
1) do i need to connect each eeprom sda and scl to the same pull up resistor?
2) is it right for eeprom 1, eeprom 1 pin must set to A0 high, A1 and A2 low
3) is it right for eeprom 2, eeprom 2 pin must set to A1 high, A0 and A2 low |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sun Jul 30, 2017 8:07 am |
|
|
You can set A0, A1, A2 to whatever pattern you want. So long as each is different. Eight possible patterns. Then read the data sheet, and work out the device address each will be at.
Yes, since they are all on the same bus, SCL will go to all four chips, and SDA to all four chips. Just one pull up on each of these lines.
Since the capacitance will be higher than for a single device the resistors chosen should be lower than may be needed for one device. Something like 1.8KR is a sensible value for a reasonably loaded bus.
As a comment though, why not just use a single larger chip. 4*24LC256 could be replaced by one 1Mb EEPROM. 5v ones are relatively rare, most are 3.3v, but there are several on the market like the CAT24M01.
Last edited by Ttelmah on Sun Jul 30, 2017 8:13 am; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Sun Jul 30, 2017 8:10 am |
|
|
1) yes, all SDA connect together( in parallel)
yes, all SCL connect together ( in parallel)
re: EEPROM device addresses
device A2 A1 A0
num
1 0 0 0
2 0 0 1
3 0 1 0
4 0 1 1
It would help to call device #1 actually #0, then the device addresses 'look' like the device programming sequences, easier to remember, at least for me !!
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sun Jul 30, 2017 8:18 am |
|
|
And (of course), it is very simple to have the device number automatically translated to the address. (Device_number *2) +0xA0.
So device#0 = 0xA0, #1 = 0xA2, #2 = 0xA4 etc.. |
|
|
art
Joined: 21 May 2015 Posts: 181
|
|
Posted: Sun Jul 30, 2017 5:16 pm |
|
|
I've never used I2C protocol before. Thanks for the info.
If i use eeprom 24LC256, i can write into address 0000 to 7FFF.
I' ve just tried to write at address 8000 just to know what will happen, and i found out it can read back data on this address. How can this happen? |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Sun Jul 30, 2017 6:28 pm |
|
|
Write something to 0x8000, then read from address 0x0000. What data do you get from the read? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Sun Jul 30, 2017 6:38 pm |
|
|
Why that happens is explained in the eeprom datasheet, it's called 'roll over' I believe.
Like counting to 6 on one hand, where the number '1' finger is also the number '6' finger.
There is a LOT of important, necessary information in datasheets.
'Little' details like that doing a page write can save over 300ms when storing data to the EEPROM using one write instead of 64.
Jay |
|
|
art
Joined: 21 May 2015 Posts: 181
|
|
Posted: Sun Jul 30, 2017 9:37 pm |
|
|
Dear Jay
You were right regarding "ROLL OVER".
Thank you very much. |
|
|
Arakel
Joined: 06 Aug 2016 Posts: 107 Location: Moscow
|
|
Posted: Thu Aug 17, 2017 5:30 am |
|
|
temtronic wrote: | Why that happens is explained in the eeprom datasheet, it's called 'roll over' I believe.
Like counting to 6 on one hand, where the number '1' finger is also the number '6' finger.
There is a LOT of important, necessary information in datasheets.
'Little' details like that doing a page write can save over 300ms when storing data to the EEPROM using one write instead of 64.
Jay |
EDIT:
My question is: "Should I use "BYTE" or "unsigned int8" and whats the difference, both of them should be "8-bit" integers since there is nothing else in "C"?
This is a good example about the problems that I have, if someone asks me what is a "roll over" I have no idea, but if they say "when the stack pointer reaches the last address, what happens" I perfectly know that the stack pointer goes only 1 direction. This is like "true" and "effective" reset vector for the factory calibration..... _________________ Yo! I love learning and technology! I just do not have experience so do not be angry if I ask a stupid question about a detail! From so much to remember sometimes I forget the details in order to remember the big problems! |
|
|
Arakel
Joined: 06 Aug 2016 Posts: 107 Location: Moscow
|
|
Posted: Thu Aug 17, 2017 5:39 am |
|
|
This is my code, what is the "i2c_write (0xA1)" in "read_ext_eeprom(int8 device_address, long int address)" for?
EDIT:
I know that we are following the sequence in the datasheet for "random address read", but why is it "0xa1", shouldnt it be the same address as before "0xa0"?
Code: |
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
///////////////////////////////////////////////////////////////////////////
#ifndef EEPROM_SDA
#define EEPROM_SDA PIN_C4
#define EEPROM_SCL PIN_C3
#endif
#define hi(x) (*((int8 *)&x+1))
#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 4096
void init_ext_eeprom() {
output_float(EEPROM_SCL);
output_float(EEPROM_SDA);
}
BOOLEAN ext_eeprom_ready(int8 device_address) {
int1 ack;
i2c_start(); // If the write command is acknowledged,
ack = i2c_write(device_address); // then the device is ready.
i2c_stop();
return !ack;
}
void write_ext_eeprom(int8 device_address, long int address, BYTE data) {
while(!ext_eeprom_ready());
i2c_start();
i2c_write(device_address);
i2c_write(hi(address));
i2c_write(address);
i2c_write(data);
i2c_stop();
}
BYTE read_ext_eeprom(int8 device_address, long int address) {
BYTE data;
while(!ext_eeprom_ready());
i2c_start();
i2c_write(device_address);
i2c_write(hi(address));
i2c_write(address);
i2c_start();
[b] i2c_write(0xa1);[/b]
data=i2c_read(0);
i2c_stop();
return(data);
}
|
_________________ Yo! I love learning and technology! I just do not have experience so do not be angry if I ask a stupid question about a detail! From so much to remember sometimes I forget the details in order to remember the big problems! |
|
|
Arakel
Joined: 06 Aug 2016 Posts: 107 Location: Moscow
|
|
Posted: Thu Aug 17, 2017 6:59 am |
|
|
I made it to work :D. Yeiiiiiiiiiiiiiiiiiiii! I am happy :D:D:D:D:D:D:D:D:D:D.
I need 5 tortillas to celebrate!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
The problem was that I needed to use "a2" not "a1" for the address. Because the last bit of the control byte was the "read/write" bit and bits 3, 2, 1 are actually the address.
I had to put in the "device_address" for "eeprom_ready" test in the "read" and "write" functions in the driver. _________________ Yo! I love learning and technology! I just do not have experience so do not be angry if I ask a stupid question about a detail! From so much to remember sometimes I forget the details in order to remember the big problems! |
|
|
|