cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 I2C Problem

aveal
Associate II
Posted on March 16, 2016 at 19:41

Hello!

I'm trying to connect STM32F103RBT6 to LIS331DLH (accelerometer). LIS331 is connected to PB6/PB7 (I2C1) with pull-up resistors (4K7). STM32CubeMX generated simple code and I added only HAL_I2C_Master_Transmit() function:

int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I
2
C
1
_Init();
result = HAL_I
2
C_Master_Transmit(&hi
2
c
1
, 
0
x
30
, sendData, 
1
, 
2000
);
/* USER CODE BEGIN WHILE */
while (
1
)
{
}
}

The problem is that BUSY flag is alwauys set, so the program can't pass the first while() in function HAL_I2C_Master_Transmit():

if(I
2
C_WaitOnFlagUntilTimeout(hi
2
c, I
2
C_FLAG_BUSY, SET, I
2
C_TIMEOUT_BUSY_FLAG) != HAL_OK)
{
return HAL_BUSY;
}

How can I solve this problem? Thank you in advance!
6 REPLIES 6
Walid FTITI_O
Senior II
Posted on March 18, 2016 at 12:32

Hi mt.aveal, 

How did you initialize the buffer ''

sendData''  ?

-Hannibal-

aveal
Associate II
Posted on March 18, 2016 at 15:50

Hi! It's simple data buffer:

uint8_t sendData[DATA_SIZE];

sendData[0] = ...

sendData[1] = ...

sendData[2] = ...

I didn't post it, cause I don't think it is a problem. The program doesn't pass to any operations with this buffer.

clark2
Associate II
Posted on March 20, 2016 at 14:58

It sounds like the SDA or SCL (or both) are being held low.  This would cause the peripheral to be in a perpetual busy state.  This can be ''real'' and caused by a slave holding one of the signals low or can be ''fake'', caused by buggy silicon as described in the silicon errata in section 2.13.7

http://www.st.com/st-web-ui/static/active/en/resource/technical/document/errata_sheet/CD00190234.pdf

aveal
Associate II
Posted on March 20, 2016 at 17:44

Now it passes BUSY flag checking, but stops on:

/* Wait until SB flag is set */
if
(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout) != HAL_OK)
{
return
HAL_TIMEOUT;
}

The SB is always reset
aveal
Associate II
Posted on March 20, 2016 at 18:41

I changed initialization from:

MX_I2C1_Init();
MX_GPIO_Init();

to

MX_GPIO_Init();
MX_I2C1_Init();

And now the program passes SB flag checking and tries to send the address. But I don't see anything on SDA and SCL lines, they are always high...
clark2
Associate II
Posted on March 21, 2016 at 13:52

Without knowing what these functions actually do, it's difficult to offer advice.  Personally, I would stay right away from the ''Cube'' HAL.  As far as making the peripheral operate, there are certain things that must be done:

1. The peripheral clock must be enabled. (RCC->APB1ENR, I2C1EN)

2. The pins must be configured as alternate function, open drain.

3. The peripheral must be enabled. (I2C1->CR1, PE)

Have you chased through the code to see that all this is done properly?