2012-12-04 4:12 AM
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
2012-12-04 6:45 AM
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 Peacock2012-12-04 6:53 AM
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.2012-12-04 7:31 AM
No effect.
I test the manual STOP condition and the HW STOP condition.I don't know which way to turn!!!Please help!2012-12-04 7:59 AM
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.2012-12-04 8:35 AM
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!2012-12-04 11:30 AM
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.We’re moving the ST Community to a new platform to give you a better and more reliable community experience.