Skip to main content
olivier239955_stm1_stmicro_com
Associate
April 24, 2012
Question

STM32L-Discovery communicate in I2C with M24LR64

  • April 24, 2012
  • 20 replies
  • 3661 views
Posted on April 24, 2012 at 09:13

Hello everybody,

I have some troubel to communicate with m24LR64. I use a STM32L- Discovery.

I try to see something in the oscilloscope but nothing, could you help me to see what is wrong in my code:

#define I2C2_SLAVE_ADDRESS7     0xA0   // EEPROM I2C Address

#define ClockSpeed              200000 // 200 KHz

#include ''mainsee.h''

void I2Cmain(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

I2C_InitTypeDef  I2C_InitStructure;

       

  /* I2C1 and I2C2 Periph clock enable */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);

  /* GPIOB Periph clock enable */

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

 

  /* Configure I2C2 pins: SCL and SDA ----------------------------------------*/

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10 | GPIO_Pin_11;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_PinAFConfig(GPIOB, GPIO_Pin_10, GPIO_AF_I2C2);

  GPIO_PinAFConfig(GPIOB, GPIO_Pin_11, GPIO_AF_I2C2);

  //I2C_DeInit(I2C2);    

           

  /* I2C2 configuration ------------------------------------------------------*/

  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

  I2C_InitStructure.I2C_OwnAddress1 = I2C2_SLAVE_ADDRESS7;

  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

  I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;

  I2C_Init(I2C2, &I2C_InitStructure);

  /* Enable I2C2 -------------------------------------------------------------*/

  I2C_Cmd(I2C2, ENABLE);

  /* Send I2C1 START condition */

  I2C_GenerateSTART(I2C2, ENABLE);

  /* Test on I2C1 EV5 and clear it */

 // while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));

   /* Send EEPROM slave Address for write */

  //I2C_Send7bitAddress(I2C2, I2C2_SLAVE_ADDRESS7, I2C_Direction_Transmitter);  }

  /* Test on I2C1 EV6 and clear it */

 // while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

 while(1){

  /* Send I2C1 EEPROM internal address */

  I2C_SendData(I2C2, 0x00);   }

  /* Test on I2C1 EV8 and clear it */

  while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  /* Send I2C1 EEPROM data */

  I2C_SendData(I2C2, 0x05);

  /* Test on I2C1 EV8 and clear it */

  while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  /* Send I2C1 STOP Condition */

  I2C_GenerateSTOP(I2C2, ENABLE);

  while(1); // Do not exit

}

Thank you very much in advance to help me.

P.S: Sorry for the english, i'm French.

    This topic has been closed for replies.

    20 replies

    Tesla DeLorean
    Guru
    April 24, 2012
    Posted on April 24, 2012 at 13:39

    Start by moving I2C_Cmd(I2C2, ENABLE); before the I2C_Init()

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    olivier239955_stm1_stmicro_com
    Associate
    April 24, 2012
    Posted on April 24, 2012 at 14:26

    No change unfortunately, I've read some post to configure the I2C and i've make like in this post, but nothing in oscilloscope. Pull-up resistori is needed? even with, no change.

    It's curious because one month ago i manged to have SCL and SDA for different value of data, but now tha i have m24Lr, it doesn't work. plug or not this the same.

    alok472
    Associate
    April 24, 2012
    Posted on April 24, 2012 at 15:24

    Yes, Pull-up are needed on I2C bus.

    Did you try to run the standard peripheral example on I2C ?

    Eventually you may have to uncomment the code for sending the I2C Address

    olivier239955_stm1_stmicro_com
    Associate
    April 24, 2012
    Posted on April 24, 2012 at 15:43

    I've tried with resistor but one month ago when it works i don't have pull up resistor.

    i have find in library code for i2C with the M24LR64, but it use some function that it don't implement with the library stm32l152_eval_i2c_ee.c, i had come difficulties to add it, but even with the result are the same.

    sEE_Init();

      sEE_WriteBuffer(Tx1_Buffer, sEE_WRITE_ADDRESS1, BUFFER_SIZE1); /* première écriture */

      sEE_WaitEepromStandbyState();     /* Wait for EEPROM standby state */

      NumDataRead = BUFFER_SIZE1; /* Set the Number of data to be read */                                                                             

      sEE_ReadBuffer(Rx1_Buffer, sEE_READ_ADDRESS1, (uint16_t *)(&NumDataRead)); /* Read from I2C EEPROM from sEE_READ_ADDRESS1 */

      LCD_GLASS_DisplayString(''T1 ONGOING'');

      while (NumDataRead > 0)

      {}        

      TransferStatus1 = Buffercmp(Tx1_Buffer, Rx1_Buffer, BUFFER_SIZE1); /* Check if the data written to the memory is read correctly */

      /* TransferStatus1 = PASSED, if the transmitted and received data to/from the EEPROM are the same */

      /* TransferStatus1 = FAILED, if the transmitted and received data to/from the EEPROM are different */

      if (TransferStatus1 == PASSED)

      {

        LCD_GLASS_DisplayString(''T1 PASS'');

      }

      else

      {

        LCD_GLASS_DisplayString(''T1 FAIL'');

      }

     

      sEE_WriteBuffer(Tx2_Buffer, sEE_WRITE_ADDRESS2, BUFFER_SIZE2);        /* Second write in the memory followed by a read of the written data -------*/

      sEE_WaitEepromStandbyState();  /* Wait for EEPROM standby state */  

      NumDataRead = BUFFER_SIZE2;/* Set the Number of data to be read */   

      sEE_ReadBuffer(Rx2_Buffer, sEE_READ_ADDRESS2, (uint16_t *)(&NumDataRead)); /* Read from I2C EEPROM from sEE_READ_ADDRESS2 */

      LCD_GLASS_DisplayString(''T2 ONGOING'');

      /* Wait till DMA transfer is compelete (Tranfer complete interrupt handler resets the variable holding the number of data to be read) */

     while (NumDataRead > 0)

     {}      

      TransferStatus2 = Buffercmp(Tx2_Buffer, Rx2_Buffer, BUFFER_SIZE2);/* Check if the data written to the memory is read correctly */

      /* TransferStatus2 = PASSED, if the transmitted and received data to/from the EEPROM are the same */

      /* TransferStatus2 = FAILED, if the transmitted and received data to/from the EEPROM are different */

      if (TransferStatus2 == PASSED)

      {

        LCD_GLASS_DisplayString(''T2 PASS'');

      }

      else

      {

        LCD_GLASS_DisplayString(''T2 FAIL'');

      }

      sEE_DeInit();

            

       while(1)

       { }

    }

    TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)

    {

      while(BufferLength--)

      {

        if(*pBuffer1 != *pBuffer2)

        {

          return FAILED;

        }

        

        pBuffer1++;

        pBuffer2++;

      }

      return PASSED;  

    }

    simonlee0311
    Associate II
    April 24, 2012
    Posted on April 24, 2012 at 15:48

    Hi!!

    Yes. You need to add the Pull-high resistor on SDA and SCL pin.

    You can try official sample code to try it.

    I also try it before, and it will more quickly to know the setting of I2C function on STM32.

    olivier239955_stm1_stmicro_com
    Associate
    April 24, 2012
    Posted on April 24, 2012 at 15:56

    and what value of the resistor i have to make?

    i keep this?

      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

    alok472
    Associate
    April 24, 2012
    Posted on April 24, 2012 at 19:23

    Yes, the settings are fine.

    I normally use 4.7K. I will suggest a value between 2.2K to 10K.

    olivier239955_stm1_stmicro_com
    Associate
    April 25, 2012
    Posted on April 25, 2012 at 09:12

    Good morning everybody!

    No change this morning even with the resistor. Before the programme are running the two signal are at 3.3V, and at the moment of i push for run the two signals begin to 0V.

    I

    gives

    the code

    in case

    an error

    that would

    drag

    .

    void I2Cmain(void)

    {

    GPIO_InitTypeDef GPIO_InitStructure;

    I2C_InitTypeDef  I2C_InitStructure;

               

      /* I2C1 and I2C2 Periph clock enable */

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);

      /* GPIOB Periph clock enable */

      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);  

     

      /* Configure I2C2 pins: SCL and SDA ----------------------------------------*/

      GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10 | GPIO_Pin_11;

      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

      GPIO_Init(GPIOB, &GPIO_InitStructure);

      GPIO_PinAFConfig(GPIOB, GPIO_Pin_10, GPIO_AF_I2C2);

      GPIO_PinAFConfig(GPIOB, GPIO_Pin_11, GPIO_AF_I2C2);

      /* Enable I2C2 -------------------------------------------------------------*/

      //I2C_DeInit(I2C2);    

      I2C_Cmd(I2C2, ENABLE);  

               

      /* I2C2 configuration ------------------------------------------------------*/

      I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

      I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

      I2C_InitStructure.I2C_OwnAddress1 = 0xA0;

      I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

      I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

      I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;

      I2C_Init(I2C2, &I2C_InitStructure);

      //I2C_StretchClockCmd(I2C2,ENABLE);

     while(1){

      /* Send I2C1 START condition */

      I2C_GenerateSTART(I2C2, ENABLE);

      /* Test on I2C1 EV5 and clear it */

     // while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));

       /* Send EEPROM slave Address for write */

      I2C_Send7bitAddress(I2C2, I2C2_SLAVE_ADDRESS7, I2C_Direction_Transmitter);  

      /* Test on I2C1 EV6 and clear it */

     // while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

      /* Send I2C1 EEPROM internal address */

      I2C_SendData(I2C2, 0x00);   

      /* Test on I2C1 EV8 and clear it */

     // while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

      /* Send I2C1 EEPROM data */

      I2C_SendData(I2C2, 0x05);

      /* Test on I2C1 EV8 and clear it */

      //while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

      /* Send I2C1 STOP Condition */

      I2C_GenerateSTOP(I2C2, ENABLE);

      }

     

    }

    olivier239955_stm1_stmicro_com
    Associate
    April 26, 2012
    Posted on April 26, 2012 at 08:16

    hi,

    No error in my code? I've pull up resistor of 4k7.

    I really don't know why it doesn't wor, i need your help.

    thanks

    stm32forum
    Associate III
    April 26, 2012
    Posted on April 26, 2012 at 09:47

    Do you have no communication at all?

    You need to unlock the eeprom with password before you can use it, see page 28 of the datasheet.

    Never used the M24LR64 with an stm32, only with avr, so i can't say exactly what's wrong.