AnsweredAssumed Answered

m24lr64r write problem

Question asked by Ricy on Nov 5, 2015
Latest reply on Nov 13, 2015 by NFC software support 3
Hello,
now I try to use STM32F103 with I2C bus to communicate with EEPROM M24LR64-R. When the Byte of write data is less than a page size(4 bytes), write and read are both ok. But when I want to write more than 4 Bytes data, there is always problem, the second time write always has a AF error. I have tried a lot of ways, but I can still not find the answer, can you help me?

PS: I use the STM32CubeMx to initialize all the pins and clock and generate the project for MDK5

I hope you can understand my question and help me, thank you in advance!!

Here is my code:

#define  I2C_PageSize              4
#define  I2C1_SLAVE_ADDRESS7       (uint16_t)0xA0
#define  EE_MemAddress_Write     (uint16_t)0
#define  EE_MemAddress_Read     (uint16_t)0
#define  Amount_Data_Send      (uint16_t)7
#define  Amount_Data_Read      (uint16_t)4

uint8_t I2c_Buf_Write[256];
uint8_t I2c_Buf_Read[256];
void I2C_Test(void);


/* I2C1 init function */
void MX_I2C1_Init(void)
{

 __HAL_RCC_I2C1_CLK_ENABLE();
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 400000;              // Fm mode I2C
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;          // Fm mode duty cycle (t_low/t_high = 2)
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;   // Disable General Call
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
  HAL_I2C_Init(&hi2c1);
 
 //I2C1->CR1 |= 1 << 10;          // Enable Acknowledge
 __HAL_I2C_ENABLE(&hi2c1);

}

void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(hi2c->Instance==I2C1)
  {
  /* USER CODE BEGIN I2C1_MspInit 0 */

  /* USER CODE END I2C1_MspInit 0 */
 
    /**I2C1 GPIO Configuration   
    PB6     ------> I2C1_SCL
    PB7     ------> I2C1_SDA
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* Peripheral clock enable */
    __I2C1_CLK_ENABLE();
  /* USER CODE BEGIN I2C1_MspInit 1 */

  /* USER CODE END I2C1_MspInit 1 */
  }

}


int main(void)
{

 
  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_CAN_Init();
  MX_I2C1_Init();
  MX_USART1_UART_Init();

 I2C_Test();

  while (1)
  {

  }
}

void I2C_Test(void)
{
 HAL_StatusTypeDef i2c_statusT, i2c_statusR;
 uint16_t i;

 printf("\r\nThe Data to Write\r\n");
   
 for ( i=0; i<Amount_Data_Send; i++ )        // Write the data to the buffer
  {  
    I2c_Buf_Write[i] = i+1;

    printf("0x%02X ", I2c_Buf_Write[i]);
    if(i%16 == 15)
  {
   printf("\n\r");
  }   
           
  }
 
   /* Write the data from I2c_Buf_Write into EERPOM */
  i2c_statusT = I2C_EE_BufferWrite(I2c_Buf_Write, EE_MemAddress_Write, Amount_Data_Send);
 
  printf("\r\nTransmit status is 0x%02X\r\n", i2c_statusT); 
 
 HAL_Delay(50);
 
   /* Read the data from EEPROM and store into I2c_Buf_Read */
  i2c_statusR = HAL_I2C_Mem_Read(&hi2c1, I2C1_SLAVE_ADDRESS7, EE_MemAddress_Read, I2C_MEMADD_SIZE_16BIT, I2c_Buf_Read, Amount_Data_Read, 1000);
  
 printf("\r\nReceive status is 0x%02X\r\n", i2c_statusR);
 
 printf("The Data Read from EEPROM\r\n");

  // Print the data from I2c_Buf_Read via a serial port
 for (i=0; i<Amount_Data_Read; i++)
 { 
  if(I2c_Buf_Read[i] != I2c_Buf_Write[i])
  {
   printf("\r\nThe Buf[%d]=0x%02X is wrong!\r\n", i, I2c_Buf_Read[i]);
   printf("\r\nError:The data written to EEPROM and read out are different! \r\n");
   return;
  }
    printf("Buf[%d]=0x%02X ", i, I2c_Buf_Read[i]);
    if(i%16 == 15)   
        printf("\n\r");
   
 }
  printf("\r\nI2C(M24LR64-R)W/R Succeed!\r\n");
}

/***************************************************************************
 * Function Name: I2C_EE_BufferWrite
 * Description  : Write the data from buffer to a block of I2C EEPROM
 * Input     : -pBuffer      The pointer to the buffer
 *             -WriteAddr     The EEPROM Address to receive the data
 *             -NumByteToWrite  The byte number of written data
 * Output     : None
 * Return     : StatusFlag
 * Called     : Extern Called
 ***************************************************************************/
HAL_StatusTypeDef I2C_EE_BufferWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
{
  uint16_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;
 uint16_t DataIndex = 0;
 HAL_StatusTypeDef  StatusFlag = HAL_OK;

  Addr = WriteAddr % I2C_PageSize;
  count = I2C_PageSize - Addr;
  NumOfPage =  NumByteToWrite / I2C_PageSize;
  NumOfSingle = NumByteToWrite % I2C_PageSize;
 
  /* If WriteAddr is I2C_PageSize aligned  */
  if(Addr == 0)
  {
    /* If NumByteToWrite < I2C_PageSize */
    if(NumOfPage == 0)
    {
   DataIndex = NumOfSingle;
   StatusFlag = HAL_I2C_Mem_Write(&hi2c1, I2C1_SLAVE_ADDRESS7, WriteAddr, I2C_MEMADD_SIZE_16BIT, pBuffer, DataIndex, 500);
   
   if(StatusFlag != HAL_OK)
   {
    printf("1");
    return StatusFlag;
   }
    }
    /* If NumByteToWrite > I2C_PageSize */
    else 
    {
      while(NumOfPage--)
      {
    DataIndex = I2C_PageSize;
    StatusFlag = HAL_I2C_Mem_Write(&hi2c1, I2C1_SLAVE_ADDRESS7, WriteAddr, I2C_MEMADD_SIZE_16BIT, pBuffer, DataIndex, 500);

    if(StatusFlag != HAL_OK)
    {
     printf("2");
     return StatusFlag;
    } 
        WriteAddr +=  I2C_PageSize;
        pBuffer += I2C_PageSize;
      }

      if(NumOfSingle!=0)
      {
    /* Store the number of data to be written */
    DataIndex = NumOfSingle;
    StatusFlag = HAL_I2C_Mem_Write(&hi2c1, I2C1_SLAVE_ADDRESS7, WriteAddr, I2C_MEMADD_SIZE_16BIT, pBuffer, DataIndex, 500);

    if(StatusFlag != HAL_OK)
    {
     printf("3");
     return StatusFlag;
    }
      }
    }
  }
  /* If WriteAddr is not I2C_PageSize aligned  */
  else
  {
    /* If NumByteToWrite < I2C_PageSize */
    if(NumOfPage == 0)
    {
   /* If the number of data to be written is more than the remaining space in the current page: */
       if (NumByteToWrite > count)
       {
         /* Store the number of data to be written */
         DataIndex = count;        
         /* Write the data contained in same page */ 
         StatusFlag = HAL_I2C_Mem_Write(&hi2c1, I2C1_SLAVE_ADDRESS7, WriteAddr, I2C_MEMADD_SIZE_16BIT, pBuffer, DataIndex, 500);
         if (StatusFlag != HAL_OK)
         {
      printf("4");
           return StatusFlag;
         }

     /* Store the number of data to be written */
         DataIndex = (NumByteToWrite - count);
     WriteAddr += count;
         pBuffer += count;    
         /* Write the remaining data in the following page */
         StatusFlag = HAL_I2C_Mem_Write(&hi2c1, I2C1_SLAVE_ADDRESS7, WriteAddr, I2C_MEMADD_SIZE_16BIT, pBuffer, DataIndex, 500);
    
         if (StatusFlag != HAL_OK)
         {
      printf("5");
           return StatusFlag;
         }
       }
    else      
       {
         /* Store the number of data to be written */
         DataIndex = NumOfSingle;
         StatusFlag = HAL_I2C_Mem_Write(&hi2c1, I2C1_SLAVE_ADDRESS7, WriteAddr, I2C_MEMADD_SIZE_16BIT, pBuffer, DataIndex, 500);
    
         if (StatusFlag != HAL_OK)
         {
      printf("6");
           return StatusFlag;
         }
       }    
    }
    /* If NumByteToWrite > I2C_PageSize */
    else
    {
      NumByteToWrite -= count;
      NumOfPage =  NumByteToWrite / I2C_PageSize;
      NumOfSingle = NumByteToWrite % I2C_PageSize; 
     
      if(count != 0)
      { 
    /* Store the number of data to be written */
    DataIndex = count;
    StatusFlag = HAL_I2C_Mem_Write(&hi2c1, I2C1_SLAVE_ADDRESS7, WriteAddr, I2C_MEMADD_SIZE_16BIT, pBuffer, DataIndex, 500);
    
        if (StatusFlag != HAL_OK)
        {
     printf("7");
          return StatusFlag;
        }
        WriteAddr += count;
        pBuffer += count;
      }
     
      while(NumOfPage--)
      {
    /* Store the number of data to be written */
    DataIndex = I2C_PageSize;
    StatusFlag = HAL_I2C_Mem_Write(&hi2c1, I2C1_SLAVE_ADDRESS7, WriteAddr, I2C_MEMADD_SIZE_16BIT, pBuffer, DataIndex, 500);
    HAL_Delay(100);
    
        if (StatusFlag != HAL_OK)
        {
     printf("8");
          return StatusFlag;
        }
        WriteAddr +=  I2C_PageSize;
        pBuffer += I2C_PageSize;
      }
      if(NumOfSingle != 0)
      {
    /* Store the number of data to be written */
    DataIndex = NumOfSingle;
    StatusFlag = HAL_I2C_Mem_Write(&hi2c1, I2C1_SLAVE_ADDRESS7, WriteAddr, I2C_MEMADD_SIZE_16BIT, pBuffer, DataIndex, 500);
    
    if (StatusFlag != HAL_OK)
    {
     printf("9");
     return StatusFlag;
    }
      }
    }
  }
 
 /* If all operations OK, return HAL_OK (0) */
 return HAL_OK;
}

 

Outcomes