Skip to main content
Visitor II
September 19, 2024
Question

I2C clock not working

  • September 19, 2024
  • 5 replies
  • 5227 views

Hi everybody !! i have an issue on I2C with a STM32 issue. i thought this was a code issue but in the main i also make LEDs blinking and it works, only the I2C doesn't work but... i noticed that my lines both rise to 3.3V but never fall down it just stay high. i guess it might be because i have a clock issue. Im using internal clock for some reasons, no external crystal. The HAL-delay function work with the SYSCLK but my I2C clock doesn't. Thx for your future answers. Best regards.

    This topic has been closed for replies.

    5 replies

    Super User
    September 19, 2024

    Do you call HAL_I2C_* functions? Show your usage of them. Do they return HAL_OK or something else?

    TendoAuthor
    Visitor II
    September 19, 2024

    Thank for your answer. I will show you what i did : 

    #include "STM332_IMU.h"
    
    
    #define IMU_addr_R 0xD0
    #define IMU_addr_W 0xD1
    
    #define IMU_REG_SMPLRT_DIV 0x19
    #define IMU_REG_CONFIG 0x1A
    #define IMU_REG_GYRO_CONFIG 0x1B
    #define IMU_REG_ACCEL_CONFIG 0x1C
    #define IMU_REG_PWR_MNGMT 0x6B
    
    #define IMU_TEMP_H 0x41
    #define IMU_TEMP_L 0x42
    #define IMU_GYRO_X_H 0x43
    #define IMU_GYRO_X_L 0x44
    #define IMU_GYRO_Y_H 0x45
    #define IMU_GYRO_Y_L 0x46
    #define IMU_GYRO_Z_H 0x47
    #define IMU_GYRO_Z_L 0x48
    
    I2C_HandleTypeDef hi2c;
    
    uint8_t tx_buffer,rx_buffer,temp_H,temp_L;
    uint16_t temperature;
    uint16_t temp_degree;
    uint8_t Rx_gyro_values[6];
    
    
    int16_t Gyro_X_data = 0;
    int16_t Gyro_Y_data = 0;
    int16_t Gyro_Z_data = 0;
    
    
    void Read_IMU_temp ()
    {
    	HAL_I2C_Mem_Read(&hi2c, IMU_addr_R, IMU_TEMP_H, 1, temp_H, 1, 1000);
    
    	HAL_I2C_Mem_Read(&hi2c, IMU_addr_R, IMU_TEMP_H, 1, temp_L, 1, 1000);
    
    	temperature = ((temp_H << 8) + temp_L);
    	temp_degree = ((temperature/340) + 36.53);
    }
    
    
    void Read_IMU_Gyro ()
    {
    	HAL_I2C_Mem_Read(&hi2c, IMU_addr_R, IMU_GYRO_X_H ,1, Rx_gyro_values, 6, 1000);
     Gyro_X_data = (int16_t)(Rx_gyro_values[0] << 8 | Rx_gyro_values [1]);
     Gyro_Y_data = (int16_t)(Rx_gyro_values[2] << 8 | Rx_gyro_values [3]);
     Gyro_Z_data = (int16_t)(Rx_gyro_values[4] << 8 | Rx_gyro_values [5]);
    }
    
    
    void init_IMU_MPU6050 ()
    {
    
    	if	(HAL_I2C_IsDeviceReady(&hi2c, IMU_addr_R, 1, 1000))
    
    		{
    			tx_buffer = 0x07;
    			HAL_I2C_Mem_Write(&hi2c, IMU_addr_W, IMU_REG_SMPLRT_DIV, 1, tx_buffer, 1, 1000);
    			tx_buffer = 0xE0;
    			HAL_I2C_Mem_Write(&hi2c, IMU_addr_W, IMU_REG_GYRO_CONFIG, 1, tx_buffer, 1, 1000);
    			tx_buffer = 0x00;
    			HAL_I2C_Mem_Write(&hi2c, IMU_addr_W, IMU_REG_PWR_MNGMT, 1, tx_buffer, 1, 1000);
    			tx_buffer = 0x00;
    			HAL_I2C_Mem_Write(&hi2c, IMU_addr_W, IMU_REG_ACCEL_CONFIG, 1, tx_buffer, 1, 1000);
    		}
    
    }
    Super User
    September 19, 2024

    As @TDK suggested, check the return values from all your HAL_I2C_... function calls

     

    I think this is wrong:

    	if	(HAL_I2C_IsDeviceReady(&hi2c, IMU_addr_R, 1, 1000))
    		{
    			tx_buffer = 0x07;

    If the device is ready, then HAL_I2C_IsDeviceReady() will return HAL_OK, which is zero - ie, false !

    So it should be:

    	if	(HAL_OK == HAL_I2C_IsDeviceReady(&hi2c, IMU_addr_R, 1, 1000))
    		{
    			tx_buffer = 0x07;

     

    Technical Moderator
    September 19, 2024

    Hello @Tendo,

    Please share more details to help you solve your issue.

    Have a look at this FAQ which describes few tips related to I2C: STM32 I2C does not work - STMicroelectronics Community

    Super User
    September 19, 2024

    please see the Posting Tips for how to properly post source code - not as screenshots:

    https://community.st.com/t5/community-guidelines/how-to-write-your-question-to-maximize-your-chances-to-find-a/ta-p/575228

     

    Super User
    September 19, 2024

    > I2C_HandleTypeDef hi2c;

    Where do you initialize this? Probably nowhere. Certainly not in the included code.

    Probably you should be using the handle that is declared and initialized in main.c or i2c.c. Something like:

    extern I2C_HandleTypeDef hi2c1;

     

    Debug your code, step through functions to understand where and why they don't work as expected. Don't treat them as a black box.

    TendoAuthor
    Visitor II
    September 19, 2024

    this doesn't compile with because it isn't declared i don't know why. teh thing is , i knwo there might have some issues in my code but :

    First, the code compiles properly

    Second, nothing block the program, my LED keep blinking and the loop do the job

    AND finally i don't have anything on SCL line, even with a bad code, if the I2C is activated we should see the clock however i just see the line going to 3.3V

    Super User
    September 19, 2024

    > AND finally i don't have anything on SCL line, even with a bad code, if the I2C is activated we should see the clock however i just see the line going to 3.3V

    Why do you expect specific functionality even with bad code? That is madness.

     

    Do you initialize I2C anywhere? If so, where and how? Really hard to debug through a keyhole. Might have to put in some work yourself to properly illustrate what you having going on in the code.

    Super User
    September 20, 2024

    Please include all your code. I don't know what "my new file" is. The details matter here. Attach it as a rar if needed.

    Let's be objective here. If main.c compiled before, there is no reason that adding that line will make it not compile.

    TendoAuthor
    Visitor II
    September 20, 2024

    ok sorry i will send you :

     

    Main.c :

    /* USER CODE BEGIN Header */
    /**
     ******************************************************************************
     * @file : main.c
     * @brief : Main program body
     ******************************************************************************
     * @attention
     *
     * Copyright (c) 2024 STMicroelectronics.
     * All rights reserved.
     *
     * This software is licensed under terms that can be found in the LICENSE file
     * in the root directory of this software component.
     * If no LICENSE file comes with this software, it is provided AS-IS.
     *
     ******************************************************************************
     */
    /* USER CODE END Header */
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    #include "STM332_IMU.h"
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    
    /* USER CODE END Includes */
    
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
    
    /* USER CODE END PTD */
    
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
    
    /* USER CODE END PD */
    
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
    
    /* USER CODE END PM */
    
    /* Private variables ---------------------------------------------------------*/
    
    extern I2C_HandleTypeDef hi2c1;
    
    /* USER CODE BEGIN PV */
    
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_I2C1_Init(void);
    /* USER CODE BEGIN PFP */
    
    /* USER CODE END PFP */
    
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
    
    /* USER CODE END 0 */
    
    /**
     * @brief The application entry point.
     * @retval int
     */
    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();
    
     /* USER CODE BEGIN Init */
    
     /* USER CODE END Init */
    
     /* Configure the system clock */
     SystemClock_Config();
    
     /* USER CODE BEGIN SysInit */
    
     /* USER CODE END SysInit */
    
     /* Initialize all configured peripherals */
     MX_GPIO_Init();
     MX_I2C1_Init();
     /* USER CODE BEGIN 2 */
     init_IMU_MPU6050 ();
     /* USER CODE END 2 */
    
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
     while (1)
     {
    
     /* USER CODE END WHILE */
    
     /* USER CODE BEGIN 3 */
    
    		 HAL_GPIO_TogglePin(GPIOA, LED_1_Pin);
    		 HAL_Delay(2000);
    		 HAL_GPIO_TogglePin(GPIOA, LED_5_Pin);
    		 HAL_Delay(2000);
    		 Read_IMU_temp();
    		 Read_IMU_Gyro();
    
     }
     /* USER CODE END 3 */
    }
    
    /**
     * @brief System Clock Configuration
     * @retval None
     */
    void SystemClock_Config(void)
    {
     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    
     /** Initializes the RCC Oscillators according to the specified parameters
     * in the RCC_OscInitTypeDef structure.
     */
     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
     RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV4;
     RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
     {
     Error_Handler();
     }
    
     /** Initializes the CPU, AHB and APB buses clocks
     */
     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
     |RCC_CLOCKTYPE_PCLK1;
     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
     RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
     RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;
     RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;
    
     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
     {
     Error_Handler();
     }
    }
    
    /**
     * @brief I2C1 Initialization Function
     * @PAram None
     * @retval None
     */
    static void MX_I2C1_Init(void)
    {
    
     /* USER CODE BEGIN I2C1_Init 0 */
    
     /* USER CODE END I2C1_Init 0 */
    
     /* USER CODE BEGIN I2C1_Init 1 */
    
     /* USER CODE END I2C1_Init 1 */
     hi2c1.Instance = I2C1;
     hi2c1.Init.Timing = 0x40000A0B;
     hi2c1.Init.OwnAddress1 = 0;
     hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
     hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
     hi2c1.Init.OwnAddress2 = 0;
     hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
     hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
     hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
     if (HAL_I2C_Init(&hi2c1) != HAL_OK)
     {
     Error_Handler();
     }
    
     /** Configure Analogue filter
     */
     if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
     {
     Error_Handler();
     }
    
     /** Configure Digital filter
     */
     if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
     {
     Error_Handler();
     }
     /* USER CODE BEGIN I2C1_Init 2 */
    
     /* USER CODE END I2C1_Init 2 */
    
    }
    
    /**
     * @brief GPIO Initialization Function
     * @PAram None
     * @retval None
     */
    static void MX_GPIO_Init(void)
    {
     GPIO_InitTypeDef GPIO_InitStruct = {0};
    /* USER CODE BEGIN MX_GPIO_Init_1 */
    /* USER CODE END MX_GPIO_Init_1 */
    
     /* GPIO Ports Clock Enable */
     __HAL_RCC_GPIOB_CLK_ENABLE();
     __HAL_RCC_GPIOA_CLK_ENABLE();
    
     /*Configure GPIO pin Output Level */
     HAL_GPIO_WritePin(GPIOA, LED_1_Pin|LED_2_Pin|LED_3_Pin|LED_6_Pin
     |LED_5_Pin|LED_4_Pin, GPIO_PIN_RESET);
    
     /*Configure GPIO pins : LED_1_Pin LED_2_Pin LED_3_Pin LED_6_Pin
     LED_5_Pin LED_4_Pin */
     GPIO_InitStruct.Pin = LED_1_Pin|LED_2_Pin|LED_3_Pin|LED_6_Pin
     |LED_5_Pin|LED_4_Pin;
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
     /*Configure GPIO pins : PA4 PA5 */
     GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     GPIO_InitStruct.Alternate = GPIO_AF1_USART2;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
     /*Configure GPIO pins : PA11 PA12 */
     GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    /* USER CODE BEGIN MX_GPIO_Init_2 */
    /* USER CODE END MX_GPIO_Init_2 */
    }
    
    /* USER CODE BEGIN 4 */
    
    /* USER CODE END 4 */
    
    /**
     * @brief This function is executed in case of error occurrence.
     * @retval None
     */
    void Error_Handler(void)
    {
     /* USER CODE BEGIN Error_Handler_Debug */
     /* User can add his own implementation to report the HAL error return state */
     __disable_irq();
     while (1)
     {
     }
     /* USER CODE END Error_Handler_Debug */
    }
    
    #ifdef USE_FULL_ASSERT
    /**
     * @brief Reports the name of the source file and the source line number
     * where the assert_param error has occurred.
     * @PAram file: pointer to the source file name
     * @PAram line: assert_param error line source number
     * @retval None
     */
    void assert_failed(uint8_t *file, uint32_t line)
    {
     /* USER CODE BEGIN 6 */
     /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
     /* USER CODE END 6 */
    }
    #endif /* USE_FULL_ASSERT */

     

    and my new file STM32_IMU.c :

    /*
     * STM32_IMU.c
     *
     * Created on: Sep 2, 2024
     * Author: doudz
     */
    
    //#include "STM332_IMU.h"
    #include "STM332_IMU.h"
    
    
    #define IMU_addr_R 0xD0
    #define IMU_addr_W 0xD1
    
    #define IMU_REG_SMPLRT_DIV 0x19
    #define IMU_REG_CONFIG 0x1A
    #define IMU_REG_GYRO_CONFIG 0x1B
    #define IMU_REG_ACCEL_CONFIG 0x1C
    #define IMU_REG_PWR_MNGMT 0x6B
    
    #define IMU_TEMP_H 0x41
    #define IMU_TEMP_L 0x42
    #define IMU_GYRO_X_H 0x43
    #define IMU_GYRO_X_L 0x44
    #define IMU_GYRO_Y_H 0x45
    #define IMU_GYRO_Y_L 0x46
    #define IMU_GYRO_Z_H 0x47
    #define IMU_GYRO_Z_L 0x48
    
    I2C_HandleTypeDef hi2c1;
    
    uint8_t tx_buffer,rx_buffer,temp_H,temp_L;
    uint16_t temperature;
    uint16_t temp_degree;
    uint8_t Rx_gyro_values[6];
    
    
    int16_t Gyro_X_data = 0;
    int16_t Gyro_Y_data = 0;
    int16_t Gyro_Z_data = 0;
    
    
    void Read_IMU_temp()
    {
    	HAL_I2C_Mem_Read(&hi2c1, IMU_addr_R, IMU_TEMP_H, 1, temp_H, 1, 1000);
    
    	HAL_I2C_Mem_Read(&hi2c1, IMU_addr_R, IMU_TEMP_H, 1, temp_L, 1, 1000);
    
    	temperature = ((temp_H << 8) + temp_L);
    	temp_degree = ((temperature/340) + 36.53);
    }
    
    
    void Read_IMU_Gyro()
    {
    	HAL_I2C_Mem_Read(&hi2c1, IMU_addr_R, IMU_GYRO_X_H ,1, Rx_gyro_values, 6, 1000);
     Gyro_X_data = (int16_t)(Rx_gyro_values[0] << 8 | Rx_gyro_values [1]);
     Gyro_Y_data = (int16_t)(Rx_gyro_values[2] << 8 | Rx_gyro_values [3]);
     Gyro_Z_data = (int16_t)(Rx_gyro_values[4] << 8 | Rx_gyro_values [5]);
    }
    
    
    void init_IMU_MPU6050 ()
    {
    
    	if	(HAL_OK == HAL_I2C_IsDeviceReady(&hi2c1, IMU_addr_R, 1, 1000))
    
    		{
    			tx_buffer = 0x07;
    			HAL_I2C_Mem_Write(&hi2c1, IMU_addr_W, IMU_REG_SMPLRT_DIV, 1, tx_buffer, 1, 1000);
    			tx_buffer = 0xE0;
    			HAL_I2C_Mem_Write(&hi2c1, IMU_addr_W, IMU_REG_GYRO_CONFIG, 1, tx_buffer, 1, 1000);
    			tx_buffer = 0x00;
    			HAL_I2C_Mem_Write(&hi2c1, IMU_addr_W, IMU_REG_PWR_MNGMT, 1, tx_buffer, 1, 1000);
    			tx_buffer = 0x00;
    			HAL_I2C_Mem_Write(&hi2c1, IMU_addr_W, IMU_REG_ACCEL_CONFIG, 1, tx_buffer, 1, 1000);
    		}
    
    }

    and then my STM32_IMU.h :

    /*
     * STM332_IMU.h
     *
     * Created on: Sep 2, 2024
     * Author: doudz
     */
    
    #include "main.h"
    
    #ifndef INC_STM332_IMU_H_
    #define INC_STM332_IMU_H_
    
    
    
    #endif /* INC_STM332_IMU_H_ */
    
    
    void Read_IMU_temp();
    
    void Read_IMU_Gyro();
    
    void init_IMU_MPU6050();

     

    now it compiles properly i ve corrected something. But i haven't anything on i2c lines.

    Graduate II
    September 20, 2024

    In your main.c you don't change I2C_HandleTypeDef hi2c1; but leave it as is.

    You only add extern I2C_HandleTypeDef hi2c1; to your files that use the HAL I2C API's