Skip to main content
anuj
Associate II
February 23, 2017
Question

Unable to Read and Write to I2C EEPROM

  • February 23, 2017
  • 6 replies
  • 6811 views
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.

6 replies

john doe
Senior III
February 24, 2017
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
February 25, 2017
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
March 1, 2017
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
March 1, 2017
Posted on March 01, 2017 at 09:06

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

 
Nicolas Felipe
Associate II
March 1, 2017
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
March 3, 2017
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
June 15, 2017
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
June 15, 2017
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
January 22, 2018
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

}

}