Electronic – arduino – STM32F3 I2C communication with Arduino

arduinoi2cstm32stm32f3

I am trying to implement the Inter-Integrated Circuit (I2C) of STM32F3 Discovery Board to communicate with 2 slaves (arduino) in my project. However, I cannot send any data to arduino.

Here is my coding:

    void I2CInit(I2C_TypeDef* I2Cx){

        if (I2Cx == I2C1){

         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
         GPIO_Init(GPIOB,&GPIO_InitStructure);

         GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_4);
         GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_4);

         I2C_DeInit(I2C1);
         I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
         I2C_InitStructure.I2C_AnalogFilter =  I2C_AnalogFilter_Enable;
         I2C_InitStructure.I2C_DigitalFilter = 0x00;
         I2C_InitStructure.I2C_OwnAddress1 = 0x2F;
         I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
         I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
         I2C_InitStructure.I2C_Timing = 0xA061191F;
         I2C_Init(I2C1,&I2C_InitStructure);
         I2C_Cmd(I2C1,ENABLE);
         I2C_AcknowledgeConfig(I2C1,ENABLE);

         I2C_Init(I2C1,&I2C_InitStructure);
         I2C_Cmd(I2C1,ENABLE);
         }

         else {

         GPIO_InitStructure1.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
         GPIO_InitStructure1.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_AF;
         GPIO_InitStructure1.GPIO_OType = GPIO_OType_OD ;
         GPIO_InitStructure1.GPIO_PuPd = GPIO_PuPd_NOPULL ;
         GPIO_Init(GPIOA,&GPIO_InitStructure1);

         GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_4);
         GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_4);

         I2C_DeInit(I2C2);
         I2C_InitStructure1.I2C_Mode = I2C_Mode_I2C;
         I2C_InitStructure1.I2C_AnalogFilter =  I2C_AnalogFilter_Enable;
         I2C_InitStructure1.I2C_DigitalFilter = 0x00;
         I2C_InitStructure1.I2C_OwnAddress1 = 0x01;
         I2C_InitStructure1.I2C_Ack = I2C_Ack_Enable;
         I2C_InitStructure1.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
         I2C_InitStructure1.I2C_Timing =0x00902025;
         I2C_Init(I2C2,&I2C_InitStructure1);
         I2C_Cmd(I2C2,ENABLE);
         I2C_AcknowledgeConfig(I2C2,ENABLE);

         I2C_Init(I2C2,&I2C_InitStructure);
         I2C_Cmd(I2C2,ENABLE);
         }
    }

I thinks I have done the I2C configuration correctly. Thus, I think the problem most probably come from the I2Cx_Write().

Test_Status I2Cx_Write(I2C_TypeDef* I2Cx, uint8_t *buff, uint32_t nbyte, uint8_t SlaveAddr){

    /*--------Test on BUSY Flag-------------*/
        __IO uint32_t timeout = 0xFFFF;

        while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)!=RESET)
        {
            if (timeout-- == 0) return Error;
        }

        I2C_TransferHandling(I2Cx,SlaveAddr,nbyte,I2C_AutoEnd_Mode,I2C_Generate_Start_Write);

        while(I2C_GetFlagStatus(I2Cx,I2C_FLAG_TXIS)== RESET);
        {
            if((timeout--) == 0) return Error;
        }

        while(nbyte){
        I2C_SendData(I2Cx, *buff++);
        GPIOE->ODR |= 1L << 11;

        while(I2C_GetFlagStatus(I2Cx,I2C_FLAG_TXE) == RESET);
        nbyte-- ;
        }

        I2C_GenerateSTOP(I2Cx, ENABLE);

        while(I2C_GetFlagStatus(I2Cx,I2C_FLAG_STOPF) == RESET)
        {
                if((timeout--) == 0) return Error;
        }

        return Success;

}

Coding for Arduino:

#include <Wire.h>

void setup() 
{
Wire.begin(8);                
Wire.onReceive(receiveEvent); 
Serial.begin(115200);           
}

void loop() 
{
delay(100);
}

void receiveEvent(int howMany) 
{
while (1 < Wire.available()) 
{ 
  char c = Wire.read(); 
  Serial.print(c);        
}
int x = Wire.read();  
Serial.println(x);      
}

I will be very thankful if anyone can help me spot the problem.

Edit #1

I had tried using both I2C1 and I2C2 of STM32F3.

Edit #2

Actually it is okay if put the I2C_OwnAddress,it does not affect the STM32 as master in I2C communication.Just set any number will do. e.g. I set the I2C_OwnAddress = 0x2F; You only set it properly when use it as slave.

Edit #3

Some extra information:

Wire Connection:

I2C1:

PB6 – SCL

PB7 – SDA

I2C2:

PA9 – SCL

PA10 – SDA

*Do remember the common ground connection between the I2C devices.

Best Answer

Yesterday just solve the I2C communication problem, just realize I have forget to configure the clock for I2C.

RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
RCC_I2CCLKConfig(RCC_I2C2CLK_SYSCLK);

Here is my clock configuration:

//activate clock for I2C1 and I2C2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);
//config clock of I2C1 and I2C2
RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
RCC_I2CCLKConfig(RCC_I2C2CLK_SYSCLK);

Now my STM32F3 can successfully using I2C to communication with arduino. And take note that the slave address in the I2Cx_Write(...) have to be left-shifted by 1 bit. For example, if the slave address is 21 (00010101), then the address you set in the I2Cx_Write(...) has to be 42 (00101010).