‎2020-02-19 07:50 AM
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:
and my clock configuration:
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.
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!
‎2020-02-19 08:51 AM
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.
‎2020-02-19 01:50 PM
... 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
‎2020-02-20 04:50 AM
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
‎2020-02-20 05:05 AM
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 :grinning_face_with_sweat:)
__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