18.08.2015 12:22

STM32 F2 I2C2 init tricks

We spent incredible amount of time figuring out why I2C2 on pins PF0 and PF1 do not work on STM32F205 but it is probably the same at STM32 F4. At the end it shows up there was a problem with initialization order of the I2C peripheral pins and alternate function configuration. I found several similar questions on the net, but none with a valid answer.

How to set up I2C2 on PF0 and PF1 correctly

This is when using STM StdPeriph library version 1.1.2 (which is outdated now by STM32Cube, but is still used in production).

/*Initialize I2C2*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);

I2C_InitTypeDef I2C_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_Init(GPIOF, &GPIO_InitStructure); //First init the pins

/* Connect PXx to I2C_SCL, I2C_SDA*/
GPIO_PinAFConfig(GPIOF, GPIO_PinSource1, GPIO_AF_I2C2); //SCL needs to be configured first
GPIO_PinAFConfig(GPIOF, GPIO_PinSource0, GPIO_AF_I2C2); //SDA

I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 400000;
I2C_Init(I2C2, &I2C_InitStructure);

I2C_Cmd(I2C2, ENABLE);

volatile int x= 0;

I2C_GenerateSTART(I2C2, ENABLE);

while(I2C_GetFlagStatus(I2C2, I2C_FLAG_SB)!= SET) //Wait for Startbit set
{
x++;
}

I2C_Send7bitAddress(I2C2,0xEC,I2C_Direction_Transmitter);

while(I2C_GetFlagStatus(I2C2, I2C_FLAG_ADDR)!= SET) //Wait for Address send flag
{
x++;
}

I2C_SendData(I2C2,0x48);

while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BTF)!= SET) //Wait for Address send flag
{
x++;
}

Does or does not work?

Does not work (init before AF incorrect order)

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
      GPIO_Init(GPIOF, &GPIO_InitStructure);
      GPIO_PinAFConfig(GPIOF, GPIO_PinSource0, GPIO_AF_I2C2);  //SDA
      GPIO_PinAFConfig(GPIOF, GPIO_PinSource1, GPIO_AF_I2C2); //SCL

Does not work (init after AF of correct order)

      GPIO_PinAFConfig(GPIOF, GPIO_PinSource1, GPIO_AF_I2C2); //SCL
      GPIO_PinAFConfig(GPIOF, GPIO_PinSource0, GPIO_AF_I2C2);  //SDA
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
      GPIO_Init(GPIOF, &GPIO_InitStructure);       

Works:

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
      GPIO_Init(GPIOF, &GPIO_InitStructure);
      GPIO_PinAFConfig(GPIOF, GPIO_PinSource1, GPIO_AF_I2C2); //SCL
      GPIO_PinAFConfig(GPIOF, GPIO_PinSource0, GPIO_AF_I2C2);  //SDA


refs.: STM32 F4 I2C2 geht nicht auf pins PF0 und PF1

Email comment