cancel
Showing results for 
Search instead for 
Did you mean: 

I2C clock not working

Tendo
Associate II

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.

22 REPLIES 22
Tendo
Associate II

even with bad I2C function the clock should work, i activated I2C through the .ioc in CubeIDE.
that's why im wondering if i forgot to set something in the IDE. But this is the main =>

 

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 */
}
Tendo
Associate II

wait i think your answer is right but the thing is i can't use again =>

hi2c1;

 

in my sensor driver even if i include the main.h or whatever, i don't know why it doesn't know that it is already declared in the main.c

If you can build without errors, then your HAL_I2Cxx routines you call know how hi2c1 is defined.

You need to show your read function calls. No telling what you're doing in there.

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

Declaring it as extern in your new file and using that handle will work if done properly. Creating a new handle will not.

If you are still having issues, please show your corrected code along with any errors you're having.

If you feel a post has answered your question, please click "Accept as Solution".
Tendo
Associate II

i tried that but if i declare as extern in my new file like this :

 

extern I2C_HandleTypeDef hi2c1;

 

my main doesn't know hi2c1 i don't know why. see following :

 

 

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 */

}

 

the error is :

error: 'hi2c1' undeclared (first use in this function)

TDK
Guru

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.

If you feel a post has answered your question, please click "Accept as Solution".
Tendo
Associate II

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.

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

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

i tried but it doesn't change anything.

Perhaps you should just go back to basics, and keep it all in a single main.c file until you've got the I2C stuff working.

Once you have got the I2C working like that, then (and only then) move on to separating stuff out into separate files.

Don't add extra complications until you've got the I2C stuff working!

 

On how to separate stuff into separate files in C:

https://community.st.com/t5/stm32cubeide-mcus/adding-new-c-source-files-to-my-project-and-navigating-through/m-p/657455/highlight/true#M25847

https://community.st.com/t5/stm32cubeide-mcus/adding-new-c-source-files-to-my-project-and-navigating-through/m-p/658310/highlight/true#M25925