cancel
Showing results for 
Search instead for 
Did you mean: 

I2C SCL operating frequency is very low. I configured the I2C2 Interface of my STM32F103 to have a clock frequency of 100 KHz (standard Mode) but it turns out to only be around 4 kHz. Can you point me in the right direction as why this could happen?

TKöhl.1
Associate II

I am using the STM32F103C8T6 Microcontroller to read a sensor via I2C. I am using the stm32Cubemx to generate the initialisation code and Visual Studio and VisualGDB for debugging. My STM32CubeMX setup reads as follows:

0690X00000DBuO8QAL.png

and my clock configuration:

0690X00000DBuOwQAL.png

But when i try reading the i2c bus by calling

HAL_I2C_Master_Transmit(&hi2c2, IMU_address, buffer, 1, 100);

It takes very long and my logic analyzer reports a SCL frequency of about 4.4kHz instead of 100kHz. I tryed using fast mode, too, but it behaves the same.

0690X00000DBuPzQAL.png

I would be very happy, if you could help me and tell me, why i am not getting the desired faster clock and transmission speeds.

The generated initialisation code looks as follows:

static void MX_I2C2_Init(void)

{

 /* USER CODE BEGIN I2C2_Init 0 */

 /* USER CODE END I2C2_Init 0 */

 /* USER CODE BEGIN I2C2_Init 1 */

 /* USER CODE END I2C2_Init 1 */

 hi2c2.Instance = I2C2;

 hi2c2.Init.ClockSpeed = 100000;

 hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;

 hi2c2.Init.OwnAddress1 = 0;

 hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

 hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

 hi2c2.Init.OwnAddress2 = 0;

 hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

 hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

 if (HAL_I2C_Init(&hi2c2) != HAL_OK)

 {

   Error_Handler();

 }

 /* USER CODE BEGIN I2C2_Init 2 */

 /* USER CODE END I2C2_Init 2 */

}

And I am calling the following commands to enable the I2C Bus (fixes a bug)

__HAL_RCC_GPIOB_CLK_ENABLE();

__HAL_RCC_I2C2_FORCE_RESET();

HAL_Delay(1000);

__HAL_RCC_I2C2_RELEASE_RESET();

As said, any help is highly apprechiated!

4 REPLIES 4
berendi
Principal

Check all RCC registers using the reference manual, that they contain the intended values. Recent versions of STM32CubeMX are known to generate buggy code in SystemClock_Config(). You may have to rewrite it using the register interface.

... and/or verify the system clock by outputting it to MCO and measuring it there.

Also read out and check/post content of I2C registers.

JW

TKöhl.1
Associate II

Thank you for your answers.

I will take a look into the RCC registers and trace back where the error in the clock generation could lie.

I have quite an amature setup and can't measure clock speeds that are beyond a few MHz. So I configured the hardware timer to give me a pulse of 1us based on the system clock (PWM Generation based on Internal Clock with Prescaler of 71 and CCR Register with value 1). The measured Signal is indeed 1us long therefore making me believe, that my system clock is clocked at 72 MHz.

The I2C2 Registers have the following values:

CR1: 0x00000001

CR2: 0x00000000

OAR1: 0x00000000

OAR2: 0x00000000

DR: 0x00000003

SR1: 0x00000000

SR2: 0x00000000

CCR: 0x00000000

TRISE: 0x00000002

I find it notable, that the Clock control register is not configured in any way. Although the reference manual claims something like "The CCR register must be configured only when the I2C is disabled (PE = 0)". I would expect I2C to be enabled but also that the CCR Register should be configured for the clock generation. Can you help me with my confusion?

Tim

TKöhl.1
Associate II

Thank you for your hints. I now solved the error:

After the first i2c initialisation i force reset the interface to get rid of some bug (It just dosn't work without it 😅)

__HAL_RCC_I2C2_FORCE_RESET();

   HAL_Delay(1000);

   __HAL_RCC_I2C2_RELEASE_RESET();

After this reset all the registers are cleared and i have to call the init function again:

MX_I2C2_Init();

I did not do this. But now it is working again with the desired frequency of 100kHz (400kHz).

Tim