cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to Read and Write to I2C EEPROM

anuj
Associate II
Posted on February 23, 2017 at 21:43

I am using atmega AT24C256 EEPROM and STM32F0 discovery module. I am struggling to read/Write to the memory. Here is the example I trying to use:-

&sharpdefine I2C1_DEVICE_ADDRESS   0x50           /* A0 = A1 = A2 = 0 */

&sharpdefine MEMORY_ADDRESS 0x07

Buffer[0] = 'M';

HAL_I2C_Mem_Write(&hi2c1, (uint16_t) I2C1_DEVICE_ADDRESS<<1, MEMORY_ADDRESS, 1, Buffer, 1, 5);

HAL_Delay(1000);

Buffer[0] = 0x00;

HAL_Delay(1000);

HAL_I2C_Mem_Read(&hi2c1, (uint16_t) I2C1_DEVICE_ADDRESS<<1, MEMORY_ADDRESS, 1, Buffer, 1, 5); 

if (Buffer[0] == 0x4D) // if xBuffer[0] = 'M'

{

Test = 1;

}

On reading from memory, I do not get the  'M' or but some '255' instead. Where is the problem? Do I need to configure clock properly? I used CUBEMX for basic routines.

#cubemx #eeprom #hal #stm32f0 #i2c
13 REPLIES 13
john doe
Lead
Posted on February 24, 2017 at 01:32

this works for me, maybe it helps you. 'addr' is the register address in the eeprom you want to read.

uint8_t  read_eeprom_reg(uint16_t addr)

{

        uint8_t buffer[] = {addr};

        uint8_t value;

        while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)

        {

        }

        while (HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(0x50<<1), 3, 100) != HAL_OK) { }

        while (HAL_I2C_Master_Transmit(&hi2c1,                // i2c handle

                                      (uint16_t)(0x50<<1),    // i2c address, left aligned

                                      (uint8_t *)&buffer,    // data to send

                                      2,                    // how many bytes - 16 bit register address = 2 bytes

                                      100)                    // timeout

                                      != HAL_OK)            // result code

        {

            if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)

            {

                Error_Handler();

            }

        }

        while (HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(0x50<<1), 3, 100) != HAL_OK) {}

        while (HAL_I2C_Master_Receive(&hi2c1,            // i2c handle

                                     (uint16_t)(0x50<<1),    // i2c address, left aligned

                                     (uint8_t *)&value,        // pointer to address of where to store received data

                                     1,                        // expecting one byte to be returned

                                     100)                    // timeout

                                     != HAL_OK)                // result code

        {

            if (HAL_I2C_GetError (&hi2c1) != HAL_I2C_ERROR_AF)

            {

                Error_Handler();

            }

        }      

return value;

}

void write_eeprom_reg(uint16_t reg_addr, uint8_t value)

{

    uint8_t d[3];

    d[0] = (reg_addr >> 8) & 0xFF;                        // high byte of 16-bit register address

    d[1] = (reg_addr) & 0xFF;                            // low byte of 16-bit register address

    d[2] = value;                                        // what value are we writing to the register

    while (HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(0x50<<1), 3, 100) != HAL_OK) {}

    if (HAL_I2C_Master_Transmit(&hi2c1,                    // i2c handle

                               (uint16_t)(0x50<<1),     // i2c address, left aligned

                               (uint8_t *)d,             // pointer to the buffer containing the data

                               sizeof(d),                 // how many bytes are we transmitting

                               1000)                    // timeout value

                               != HAL_OK)                // result code

    {

        Error_Handler();

    } else {

    //printf('Master transmit successful\r\n');

    }

}

S.Ma
Principal
Posted on February 25, 2017 at 12:05

Euh... 256kbit = 32kbyte a single byte for the memory address location might be too short... 

Nicolas Felipe
Associate II
Posted on March 01, 2017 at 06:29

do you have an example of that function looping the eeprom?

for me has been very hard trying to control an AT24C32 with 0x57 address,.

uint8_t eeprominfo;

write_eeprom_reg(0x00,0x4D);

HAL_Delay(500);

eeprominfo = read_eeprom_reg(0x00);

was trying this with not luck, thanks.

Posted on March 01, 2017 at 09:06

https://community.st.com/0D50X00009XkW1qSAF

 
Posted on March 01, 2017 at 17:38

thanks for the example i have tried to use that but it does not work with hal projects,

i chose not to work with stdperiph and learn Hall Drivers since its the ST path

but it has been really hard since i have not been able to write to AT24C32 or AT24C0, i have used everything i have found in the web, i know the chip its ok since i have an arduino to test the components and check the address.

would be awesome to see an example using johndoe classes

uint8_t eeprominfo;

write_eeprom_reg(0x00,0x4D);

HAL_Delay(500);

eeprominfo = read_eeprom_reg(0x00);

i also tried this.

♯ define I2C1_DEVICE_ADDRESS   0x57 

♯ define MEMORY_ADDRESS 0x07

Buffer[0] = 'M';

HAL_I2C_Mem_Write(&hi2c1, (uint16_t) I2C1_DEVICE_ADDRESS<<1, MEMORY_ADDRESS, 1, Buffer, 1, 5);

HAL_Delay(1000);

Buffer[0] = 0x00;

HAL_Delay(1000);

HAL_I2C_Mem_Read(&hi2c1, (uint16_t) I2C1_DEVICE_ADDRESS<<1, MEMORY_ADDRESS, 1, Buffer, 1, 5); 

if (Buffer[0] == 0x4D) // if xBuffer[0] = 'M'

{

Test = 1;

}

also not results i tried many things like the first poster on this thread,

please help if u know what im doing wrong, thanks.

Posted on March 01, 2017 at 18:34

Ok, back to original code:

Try this:

Buffer[0] = 'M';

HAL_I2C_Mem_Write(&hi2c1, 0xA0, 0x0007, 2, Buffer, 1, 5);

HAL_Delay(10);

Buffer[0] = 0x00;

HAL_I2C_Mem_Write(&hi2c1, 0xA0,

0x0007

, 2, Buffer, 0, 5);

HAL_I2C_Mem_Read(&hi2c1, 0xA1, 0x0007, 2, Buffer, 1, 5); 

Posted on March 02, 2017 at 03:50

thank you, for ur answer but it does not work too

:(

 

i changed the address to 0x57 since is the address of the AT24C32 in the circuit, (arduino reads it ok)

tried changing the values for example to 0x00, 0x01, 0x02, 0x03 of the reg address and checking back the value but nothing,

i can read from other i2c devices but not the eeprom.

Buffer[0] = 'M';

HAL_I2C_Mem_Write(&hi2c1, 0x57, 0x0007, 2, Buffer, 1, 5);

HAL_Delay(10);

Buffer[0] = 0x00;

HAL_I2C_Mem_Write(&hi2c1,

0x57

,

0x0007

, 2, Buffer, 0, 5);

HAL_I2C_Mem_Read(&hi2c1,

0x57

, 0x0007, 2, Buffer, 1, 5); 
Posted on March 02, 2017 at 10:20

Your eeprom is probably not powered, or SDA/SCL crossed or WP pin level is wrong, or bad soldering. Should be typically something obviously simple that is missed. Take a step back and contemplate the board.

Nicolas Felipe
Associate II
Posted on March 03, 2017 at 05:21

its not my friend , when switched to the arduino it reads it ok.

its the DS3231 AT24C32 IIC Module (this one

http://www.icstation.com/images/big/productimages/2416/2416.JPG

 )

can read the DS3231 rtc at the 0xD0 address with :

I2C_ReadBuffer(hi2c1,(uint16_t)0xD0,7); // function writes to 

aTxBuffer

year = aTxBuffer[6];

year = RTC_ConvertFromDec(year);

month = aTxBuffer[5];

month = RTC_ConvertFromDec(month);

date = aTxBuffer[4];

date = RTC_ConvertFromDec(date);

day = aTxBuffer[3];

day = RTC_ConvertFromDec(day);

but cant get or write any data to the ATC32 at the 0x57 with the Hall Library.