Skip to main content
anuj
Associate II
Feb 23, 2017 8:43 PM UTC
Question

Unable to Read and Write to I2C EEPROM

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
This topic has been closed for replies.

13 replies

john doe
Senior III
Feb 24, 2017 12:32 AM UTC
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
Feb 25, 2017 11:05 AM UTC
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
Mar 1, 2017 5:29 AM UTC
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.

S.Ma
Principal
Mar 1, 2017 9:06 AM UTC
Posted on March 01, 2017 at 09:06

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

 
Nicolas Felipe
Associate II
Mar 1, 2017 5:38 PM UTC
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.

Nicolas Felipe
Associate II
Mar 3, 2017 4:21 AM UTC
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.

john doe
Senior III
Jun 15, 2017 2:44 PM UTC
Posted on June 15, 2017 at 14:44

 ,

 ,

here is my ds3231 code, taken liberally from adafruit's library.

uint16_t ds3231_read_reg(uint16_t register_pointer)

 ,

{

 ,

 , , , HAL_StatusTypeDef status = HAL_OK,

 ,

 , , , uint8_t timeArray[7] = {0},

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

 ,

 , , , status = HAL_I2C_Mem_Read(&,hi2c1,  , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , , ,  ,// i2c handle

 ,

 , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , (uint16_t)(DS3231_ADDRESS<,<,1),  , ,  ,// i2c address, left aligned

 ,

 , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , (uint16_t)register_pointer,  , ,  , , ,  ,// register address

 ,

 , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , I2C_MEMADD_SIZE_8BIT,  , ,  , , ,  , , ,  , , ,  ,// ds3231 uses 8-bit register addresses

 ,

 , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , (uint8_t*)(&,timeArray), , ,  , , ,  , , ,  ,// place to put returned value

 ,

 , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , 7, , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , , ,  ,// return seven bytes

 ,

 , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , 100), , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , , ,  , , ,  ,// timeout

 , , , /* Check the communication status */

 ,

 , , , if(status != HAL_OK)

 ,

 , , , {

 , , , }

 , ,  ,uint8_t ampm = 0,

 ,

 , ,  ,uint8_t ss = , bcd2bin(timeArray[0] &, 0x7F),

 ,

 , ,  ,uint8_t mm = , bcd2bin(timeArray[1]),

 ,

 , ,  ,uint8_t hh = , bcd2bin(timeArray[2]),

 ,

 , ,  ,uint8_t d , = , bcd2bin(timeArray[4]),

 ,

 , ,  ,uint8_t m , = , bcd2bin(timeArray[5]),

 ,

 , ,  ,uint16_t y , = bcd2bin(timeArray[6]) + 2000,

 ,

 , ,  ,uint8_t dow = ((uint16_t)date2days(y,m,d) + 6) % 7,

 , ,  ,printf('%s, %s %d, %d , , ', dayNames[dow], monthNames[m], d, y),

 , ,  ,if (hh == 12) {

 ,

 , ,  , , ,  ,ampm = 1, // its 12:00pm

 ,

 , ,  , , ,  ,}

 ,

 , ,  ,if (hh >, 12) {

 ,

 , ,  , , ,  ,hh -= 12, // 12hr mode - 13:00 is 1:00pm

 ,

 , ,  , , ,  ,ampm = 1,

 ,

 , ,  , , ,  ,}

 ,

 , ,  ,if (hh == 0) {

 ,

 , ,  , , ,  ,hh = 12, // midnight is 12:00 am

 ,

 , ,  , , ,  ,ampm = 0,

 ,

 , ,  , , ,  ,}

 , ,  ,if (hh <, 10) {

 ,

 , ,  , , ,  ,printf(' %d', hh),

 ,

 , ,  ,} else {

 ,

 , ,  , , ,  ,printf('%d', hh),

 ,

 , ,  ,}

 ,

 , ,  ,printf(':%02d:%02d %s', mm,ss, amPmString[ampm]),

 , ,  ,printf('\r\n'),

 , , , return bcdToDec(timeArray[0]),

 ,

}

and here is my i2c initialization code, just as the STM32CubeMX application generated, for an L476 nucleo board.

/* Includes ------------------------------------------------------------------*/

 ,

♯ include 'i2c.h'

♯ include 'gpio.h'

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

I2C_HandleTypeDef hi2c1,

/* I2C1 init function */

 ,

void MX_I2C1_Init(void)

 ,

{

 , hi2c1.Instance = I2C1,

 ,

 , hi2c1.Init.Timing = 0x10909CEC,

 ,

 , hi2c1.Init.OwnAddress1 = 0,

 ,

 , hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT,

 ,

 , hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE,

 ,

 , hi2c1.Init.OwnAddress2 = 0,

 ,

 , hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK,

 ,

 , hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE,

 ,

 , hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE,

 ,

 , if (HAL_I2C_Init(&,hi2c1) != HAL_OK)

 ,

 , {

 ,

 , , , Error_Handler(),

 ,

 , }

 , , , /**Configure Analogue filter

 ,

 , , , */

 ,

 , if (HAL_I2CEx_ConfigAnalogFilter(&,hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)

 ,

 , {

 ,

 , , , Error_Handler(),

 ,

 , }

}

void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)

 ,

{

 , GPIO_InitTypeDef GPIO_InitStruct,

 ,

 , if(i2cHandle->,Instance==I2C1)

 ,

 , {

 ,

 , /* USER CODE BEGIN I2C1_MspInit 0 */

 , /* USER CODE END I2C1_MspInit 0 */

 ,

 ,

 ,

 , , , /**I2C1 GPIO Configuration , ,  ,

 ,

 , , , PB8 , , , , ------>, I2C1_SCL

 ,

 , , , PB9 , , , , ------>, I2C1_SDA

 ,

 , , , */

 ,

 , , , GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9,

 ,

 , , , GPIO_InitStruct.Mode = GPIO_MODE_AF_OD,

 ,

 , , , GPIO_InitStruct.Pull = GPIO_PULLUP,

 ,

 , , , GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH,

 ,

 , , , GPIO_InitStruct.Alternate = GPIO_AF4_I2C1,

 ,

 , , , HAL_GPIO_Init(GPIOB, &,GPIO_InitStruct),

 , , , /* Peripheral clock enable */

 ,

 , , , __HAL_RCC_I2C1_CLK_ENABLE(),

 , , , /* Peripheral interrupt init */

 ,

 , , , HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0),

 ,

 , , , HAL_NVIC_EnableIRQ(I2C1_EV_IRQn),

 ,

 , , , HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0, 0),

 ,

 , , , HAL_NVIC_EnableIRQ(I2C1_ER_IRQn),

 ,

 , /* USER CODE BEGIN I2C1_MspInit 1 */

 , /* USER CODE END I2C1_MspInit 1 */

 ,

 , }

 ,

}

void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)

 ,

{

 , if(i2cHandle->,Instance==I2C1)

 ,

 , {

 ,

 , /* USER CODE BEGIN I2C1_MspDeInit 0 */

 , /* USER CODE END I2C1_MspDeInit 0 */

 ,

 , , , /* Peripheral clock disable */

 ,

 , , , __HAL_RCC_I2C1_CLK_DISABLE(),

 ,

 ,

 ,

 , , , /**I2C1 GPIO Configuration , ,  ,

 ,

 , , , PB8 , , , , ------>, I2C1_SCL

 ,

 , , , PB9 , , , , ------>, I2C1_SDA

 ,

 , , , */

 ,

 , , , HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8|GPIO_PIN_9),

 , , , /* Peripheral interrupt Deinit*/

 ,

 , , , HAL_NVIC_DisableIRQ(I2C1_EV_IRQn),

 , , , HAL_NVIC_DisableIRQ(I2C1_ER_IRQn),

 , }

 ,

 , /* USER CODE BEGIN I2C1_MspDeInit 1 */

 , /* USER CODE END I2C1_MspDeInit 1 */

 ,

}

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/**

 ,

 , * @}

 ,

 , */

/**

 ,

 , * @}

 ,

 , */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

srinivas reddy
Associate II
Jun 15, 2017 10:43 AM UTC
Posted on June 15, 2017 at 12:43

I also have problem writing and reading the data EEPROM

My EEPROM DevAddress is 0xA0

the MSB bit of 

DevAddress is 0 for writing and 1 for readeing.

val = HAL_I2C_GetState (&hi2c1);

print('HAL_I2C_GetState = %x', val);

val = HAL_I2C_Master_Transmit (&hi2c1, (uint16_t) 0xA0, '

EEPROM

', 10, 10000);

print

('HAL_I2C_Master_Transmit error = %d', val);

val = HAL_I2C_Master_Receive (&hi2c1, (uint16_t) 0xA1,&temp, 10, 10000);

print

('HAL_I2C_Master_Receive error = %d', val);

print

('HAL_I2C_Master_Receive data = %s', (uint8_t *)&temp);

am getting:

HAL_I2C_GetState = 20   //

 0x20 i.e 

HAL_I2C_STATE_READY             = 0x20U,   /*!< Peripheral Initialized and ready for use  */

HAL_I2C_Master_Transmit error = 0

HAL_I2C_Master_Receive error = 0

HAL_I2C_Master_Receive data = ÿÿÿÿÿÿÿÿÿÿ

thnaks.

Shashank TS_2
Visitor II
Jan 22, 2018 6:30 AM UTC
Posted on January 22, 2018 at 07:30

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

}

}