cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 + I2C

michele239955_stm1
Associate II
Posted on December 04, 2012 at 13:12

Hi all,

I am using STm32f2 series and I have a sensor on I2C bus. The problem is that my I2C bus is always busy. My code:

void
setupClock()
{
RCC_DeInit ();
RCC_HSEConfig (RCC_HSE_ON); 

while
(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
RCC_HCLKConfig (RCC_SYSCLK_Div1);
RCC_PCLK2Config (RCC_HCLK_Div1);
RCC_PCLK1Config (RCC_HCLK_Div2);
RCC_ADCCLKConfig (RCC_PCLK2_Div4);
RCC_PLLConfig (0x00010000, RCC_PLLMul_9);
RCC_PLLCmd (ENABLE);
while
(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
RCC_SYSCLKConfig (RCC_SYSCLKSource_PLLCLK);
while
(RCC_GetSYSCLKSource() != 0x08);
}

void
setupI2C2()
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB, ENABLE);

GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);

I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS7;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = I2C2_SPEED;
I2C_Init(I2C2, &I2C_InitStructure);
I2C_Cmd(I2C2, ENABLE);
}

In main(void) I call setupClock() and setupI2C2() functions. If i checkI2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY) this flag is always true! If I configure SDA and SCL as GPIO, I see that at the begin SDA is down. So I manually generate a square-wave on SCL pin until SDA is down. In this waySDA return up but the problem remains. Any help in resolving the issue will be appreciated. #i2c
6 REPLIES 6
jpeacock2399
Associate II
Posted on December 04, 2012 at 15:45

This sounds like your peripheral on the I2C bus is in the middle of receiving data or has not reset properly.  The fix for this, and it's what I do, is to always manually clock the bus as GPIOs to get rid of a busy before starting up the I2C hardware.  I've encountered this problem with several I2C peripherals.

  Jack Peacock
frankmeyer9
Associate II
Posted on December 04, 2012 at 15:53

So I manually generate a square-wave on SCL pin until SDA is down. In this way SDA return up but the problem remains.

I would suggest to append a stop condition at the end.

michele239955_stm1
Associate II
Posted on December 04, 2012 at 16:31

No effect.

I test the manual STOP condition and the HW STOP condition.

I don't know which way to turn!!!

Please help!

frankmeyer9
Associate II
Posted on December 04, 2012 at 16:59

Only to be sure, this was ment to be an addition to jack peacock's hint.

First pulse SCL, until the slave releases SDA, then add the stop condition.

michele239955_stm1
Associate II
Posted on December 04, 2012 at 17:35

I send STOP condition after the slave releases SDA.

I try both the manual STOP condition (SDA low to hi when SCL hi) and the I2C_GenerateSTOP(I2C2, ENABLE).

No effect!

frankmeyer9
Associate II
Posted on December 04, 2012 at 20:30

The code you supplied looks reasonable so far.

I don't have any F2 board, and the F0/F4 is a little different.

Have you tried to abserve what really happens on the bus, i.e. using a scope ?

If you could remove the slave from the bus, you should see at least the first adressing frame. This would prove that your i2c initialization is working.