cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F334 with 24C32 EEPROM I2C Read/Write

Manu Abraham
Senior
Posted on February 22, 2017 at 09:59

Hi,

Trying to get I2C communication between a F334 and a 24C32 EEPROM working,

The read and write functions do return correctly, but the reads do not match what

has been written to the EEPROM. Struggling to find the issue at hand and in the

thought that someone could possibly lend me a hand on this issue, which would

be very helpful. The EEPROM's address lines are all grounded, which effectively

puts the EEPROM at an address of 0xA0

The output I am reading in a terminal, which says:

-------------= I2C1 REG dump =-------------

I2C_CR1 : 0x01

I2C_CR2 : 0x20404a1

I2C_OAR1 : 0x8000

I2C_OAR2 : 0x00

I2C_TIMINGR : 0x10c08dcf

I2C_TIMEOUTR: 0x00

I2C_ISR : 0x01

I2C_ICR : 0x00

I2C_PECR : 0x00

I2C_RXDR : 0xff

I2C_TXDR : 0x00

-------------------------------------------

Data: ff ff ff ff

-------------= I2C1 REG dump =-------------

I2C_CR1 : 0x01

I2C_CR2 : 0x20404a1

I2C_OAR1 : 0x8000

I2C_OAR2 : 0x00

I2C_TIMINGR : 0x10c08dcf

I2C_TIMEOUTR: 0x00

I2C_ISR : 0x01

I2C_ICR : 0x00

I2C_PECR : 0x00

I2C_RXDR : 0xff

I2C_TXDR : 0x00

-------------------------------------------

Data: ff ff ff ff

which doesnt reflect what I have written. I was expecting 0x00, 0x01, 0x02, 0x03

as expected as in:

i2c_wr(0xa0, 0x00, 0x00);

i2c_wr(0xa0, 0x01, 0x01);

i2c_wr(0xa0, 0x02, 0x02);

i2c_wr(0xa0, 0x03, 0x03);

instead of 0xff, 0xff, 0xff, 0xff.

Any thoughts/suggestions ?

Thanks.

#stm32f334-i2c

Note: this post was migrated and contained many threaded conversations, some content may be missing.
26 REPLIES 26
Posted on January 20, 2018 at 09:14

In that case it would help if you colud post a part of your code for the communication with the 24c08.

Regards

Posted on January 20, 2018 at 11:37

Well i am simply calling

HAL_I2C_Mem_Read(&hi2c1, 0xA0, 1023, I2C_MEMADD_SIZE_16BIT, rData, 1, 1000);�?

0xA0 is device address for 24C I am reading address 1023 in 24C08 and reading into rData, size is 1 and 1000 is timout.

Posted on January 20, 2018 at 12:14

What is the exact paart numer of the EEPROM you are using?

Some parts such as Microchip's 24C08B only support WORD addressing.

Regards

Posted on January 20, 2018 at 12:27

Ideally, look at SDA and SCL on a scope to understand what's wrong. Sometime the function requires the 7 bit address shifted right 1, do you know if the address is MSB byte first or not? 32kbit=2 kbytes, check if the address is 16 bit or mixed in the slave address. Read the spec of the eeprom carefully.

Posted on January 20, 2018 at 12:53

Well i am using Atmel 24C08B and in the data sheet they have mentioned it is 8Kbit which is 1024byte eeprom. So technically i can access 1024 address on eeprom. Well over the internet i have read that HAL routine requires device address as 0x50 << 1 instead of 0xA0. i think that is left aligned ? so how about read will it be 0x51 <<1 or something else.....

Shashank TS_2
Associate II
Posted on January 22, 2018 at 07:29

Hello, Am using STM32F0 uC for interfacing with a AT24C64. I am not able to write sequentially to the EEPROM after one page, i.e 32 Bytes. Can someone please if the logic is wrong.

This is the code:

data[0]=0x00; //First word address 8bit

data[1]=0x00; //Second word address 8bit

for(i=2;i<34;i++)

{

data[i]=0x11;

}

HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS<<1, data, 34, 50); //data is int type,34 is number bytes of data

data[0]=0x00; //First word address 8bit

data[1]=0x20; //Second word address 8bit// Next Page

for(i=2;i<34;i++)

{

data[i]=0x22;

}

HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS<<1, data, 34, 50); //data is int type,34 is number bytes of data

while (1)

{

/* USER CODE END WHILE */

data[0]=0x00;

data[1]=0x00;

HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS<<1, data, 2, 50); //data is int type pointing to first address here

for(i=0;i<32;i++)

{

HAL_I2C_Master_Receive(&hi2c1, EEPROM_ADDRESS<<1, &dataout[i], 1, 50);//maximum is 32 byte data locations

}

data[0]=0x00;

data[1]=0x20;

HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS<<1, data, 2, 50); //data is int type pointing to first address here

for(i=0;i<32;i++)

{

HAL_I2C_Master_Receive(&hi2c1, EEPROM_ADDRESS<<1, &dataout_1[i], 1, 50);//maximum is 32 byte data locations

}

}

Ronald Niederhagen
Associate II
Posted on February 22, 2018 at 10:14

Hi, I'm not sure there is a clean answer, yet.

Here is what works for me in mbed:

/* start code */

#define AT24C32_PAGE_SIZE       32

int imin(int a, int b) { return a < b ? a : b; }

bool read_eeprom(int i2c_addr, int address, char *buffer, int len)

{

  int lx;

  char cmd[2];

  char mem_addr = (i2c_addr & 0xFE);

  while ((lx = imin(AT24C32_PAGE_SIZE - (address % AT24C32_PAGE_SIZE),len)) > 0)

    {

    cmd[0] = ((address & 0x1F00) >> 8);

    cmd[1] = (address & 0xFF);

    i2c_bus.write(mem_addr,cmd,2);

    i2c_bus.read(mem_addr,buffer,lx);

    address += lx;

    buffer += lx;

    len -= lx;

    }

  return true;

}

bool write_eeprom(int i2c_addr, int address, char *source, int len)

{

  int lx, i;

  char cmd[AT24C32_PAGE_SIZE+2];

  char mem_addr = (i2c_addr & 0xFE);

  while ((lx = imin(AT24C32_PAGE_SIZE - (address % AT24C32_PAGE_SIZE),len)) > 0)

    {

    cmd[0] = ((address & 0x1F00) >> 8);

    cmd[1] = (address & 0xFF);

    address += lx;

    len -= lx;

    lx += 2;

    for (i=2;i < lx;i++) {cmd[i] = *source++;}

    i2c_bus.write(mem_addr,cmd,lx);

    wait_ms(10); // wait until write cycle is complete

    }

  return true;

}

/* end code*/

And here is how you use these functions:

#define AT24C32_ADR     0xa0

read_eeprom(AT24C32_ADR,20,rtc_buf,sizeof(rtc_buf));

write_eeprom(AT24C32_ADR,40,txt,sizeof(txt));

The functions take care of sequential reads/writes across page boundaries.

Please note: larger EEPROMs like the AT24C32 or the AT24C64 require 2 byte addresses. Smaller ones like the AT24C08 uses 1 byte address. That's why these access functions are not (easily) compatible. See the data sheets for more detail.