2024-09-19 01:12 AM
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.
2024-09-19 12:41 PM
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 */
}
2024-09-19 01:09 PM
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
2024-09-19 06:32 PM - edited 2024-09-19 06:33 PM
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.
2024-09-20 07:07 AM
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.
2024-09-20 07:42 AM
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)
2024-09-20 07:54 AM - edited 2024-09-20 07:54 AM
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.
2024-09-20 08:06 AM
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.
2024-09-20 08:32 AM
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
2024-09-21 01:38 AM
i tried but it doesn't change anything.
2024-09-21 01:56 AM
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: