2012-12-04 04: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 06: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 06: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 07: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 07: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 08: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.