cancel
Showing results for 
Search instead for 
Did you mean: 

I2C EEPROM Transmittiong and Receiving

khouja_houssem
Associate II
Posted on March 21, 2013 at 11:55

Hi,

I am trying to send Datas to a 24C128 EEPROM via I2C interface of an STM32F4 Discovery. 

The problem is that I am not receiving the same value I am writing into the EEPROM. I am trying to write 0x05 into 0x00 address but when I run the program I get 0xA1 instead. And if I debug the code step by step I get 0xFF on reception. Couldnt find out what's wrong. Here is my code.

#include ''stm32F4xx.h''

#include ''stm32f4xx_gpio.h''

#include ''stm32f4xx_i2c.h''

#define I2C1_SLAVE_ADDRESS7     0xA0   // EEPROM I2C Address

#define ClockSpeed              200000 // 200 KHz

uint8_t a=0;

void I2CInit(void);

void I2C1_WriteDeviceRegister(uint8_t , uint8_t , uint8_t );

uint8_t I2C_ReadDeviceRegister(uint8_t , uint8_t );

int main(void)

{  

  I2CInit();

  /*----- Transmission Phase -----*/

  I2C1_WriteDeviceRegister(0xA0 , 0x00 , 0x05);

  /*----- Reception Phase -----*/

  a=I2C_ReadDeviceRegister(0xA0 , 0x00);

  while(1); 

}

void I2CInit(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  I2C_InitTypeDef I2C_InitStructure;

  /* Enable GPIO clock */

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

  /* Enable UART clock */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);

  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_9;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  

  I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;

  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

  I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;

  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

  /* Enable I2C */

  I2C_Cmd(I2C1, ENABLE);

  I2C_Init(I2C1, &I2C_InitStructure);

}

/*************************/

void I2C1_WriteDeviceRegister(uint8_t DeviceAddr, uint8_t RegisterAddr, uint8_t RegisterValue)

{

/* Send I2C1 START condition */

  I2C_GenerateSTART(I2C1, ENABLE);

  /* Test on I2C1 EV5 and clear it */

 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

  /* Send EEPROM slave Address for write */

  I2C_Send7bitAddress(I2C1, DeviceAddr, I2C_Direction_Transmitter);

  /* Test on I2C1 EV6 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

  /* Send I2C1 EEPROM internal address */

  I2C_SendData(I2C1, RegisterAddr);

  /* Test on I2C1 EV8 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  /* Send I2C1 EEPROM data */

  I2C_SendData(I2C1, RegisterValue);

  /* Test on I2C1 EV8 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  /* Send I2C1 STOP Condition */

  I2C_GenerateSTOP(I2C1, ENABLE);

}

/****************************/

uint8_t I2C_ReadDeviceRegister(uint8_t DeviceAddr, uint8_t RegisterAddr)

  uint8_t tmp;

/* Send I2C1 START condition */

  I2C_GenerateSTART(I2C1, ENABLE);

  /* Test on I2C1 EV5 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

  /* Send EEPROM slave Address for write */

  I2C_Send7bitAddress(I2C1, DeviceAddr, I2C_Direction_Transmitter);

  /* Test on I2C1 EV6 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

  /* Send I2C1 EEPROM internal address */

  I2C_SendData(I2C1, RegisterAddr);

  /* Test on I2C1 EV8 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  /* Regenerate a start condition */

  I2C_GenerateSTART(I2C1, ENABLE);

  

  /* Test on I2C1 EV5 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

  /* Transmit the slave address and enable writing operation */

  I2C_Send7bitAddress(I2C1, DeviceAddr, I2C_Direction_Receiver);

  

  /* Test on I2C1 EV6 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

  /* End the configuration sequence */

  I2C_GenerateSTOP(I2C1, ENABLE);

  

  /* Load the register value */

  tmp = I2C_ReceiveData(I2C1);

  /* Return the read value */

  return (tmp);

}

#ifdef  USE_FULL_ASSERT

/**

  * @brief  Reports the name of the source file and the source line number

  *         where the assert_param error has occurred.

  * @param  file: pointer to the source file name

  * @param  line: assert_param error line source number

  * @retval None

  */

void assert_failed(uint8_t* file, uint32_t line)

{

  /* User can add his own implementation to report the file name and line number,

     ex: printf(''Wrong parameters value: file %s on line %d\r\n'', file, line) */

  /* Infinite loop */

  while (1)

  {

  }

}

#endif

 
3 REPLIES 3
khouja_houssem
Associate II
Posted on March 21, 2013 at 12:17

There was missing ''I2C_AcknowledgeConfig(I2C1, DISABLE)'' in the I2C_ReadDeviceRegister function. I am still receiving a wrong value, this time I am receiving 0xFF instead of 0x05. 

khouja_houssem
Associate II
Posted on March 22, 2013 at 11:54

Well I'm still fine, thought I'm going psyco.

The 0xFF was the manufacturer default value and it remained unchanged after writing into it.

The code is alright. The problem was in the EEPROM used. I changed it and everything started working.

Thanks anyway.
khouja_houssem
Associate II
Posted on March 27, 2013 at 11:08

I am trying to read from the EEPROM via I2C using interrupts to get rid of the while loops after every step of the read sequence. The sequence is alright it's only making trouble when I introduce it into the I2C_IRQ_Handler. (The start byte generation is executed in main).

The problem is that the interrupt runs only in the first step of the sequence witch is Start byte Generation. The rest of the events are not enabling the I2C interrupt.

I am not sure if the problem is that the Stat Byte (SB) is not cleared but I suppose it is cleared as I am reading SR1 register (inside I2C_GetITStatus() function) and writing in DR register (I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Transmitter))  right after verifying the SB flag.

I think that I am messing something I hope someone can help me through.