When it comes to read data from a target device by using Stm32F4 Hal library I2C functions, how to do it? In this example, MPU6050 sensor is used as target device. The sensor ID value in the WHO_AM_I register(0x75) should be read as 104 (decimal). MPU6050 AD0 pin is for slave address. If AD0 pin is connected to LOW(GND), slave address is 0xD0. If it is connected to HIGH(3.3V), slave adres is 0xD2.
In the sample code below;
HAL_I2C_IsDeviceReady() function is for controlling I2C device connection.
HAL_I2C_Master_Transmit() function is for transmitting slave device address and register.
HAL_I2C_Master_Receive() function is for reading the data regarding transmitted register from slave device.
HAL_UART_Transmit() function is for transmitting the received value of WHO_AM_I ID to serial buffer.
The connections between both Stm32F4 and MPU6050(I2C1);
| Stm32F4 | MPU6050 | 
| PB6 (SCL) | SCL | 
| PB7 (SDA) | SDA | 
| 3.3V | VCC | 
| GND | GND | 
| GND | AD0 | 
The sample code;
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275  | 
						/*I2C register data read*/ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "stm32f4xx_hal.h" /* USER CODE BEGIN Includes */ /*AD0 pin is connected GND. (if it is connected HIGH(3.3V), MPU address is 0xD2)*/ #define MPU_ADDRESS     0xD0  /*MPU6050 WHO_AM_I register address*/ #define WHO_AM_I_REG    0X75  uint8_t data; uint8_t device_address = MPU_ADDRESS; uint8_t register_address = WHO_AM_I_REG; /* USER CODE END Includes */ /* Private variables ---------------------------------------------------------*/ I2C_HandleTypeDef hi2c1; UART_HandleTypeDef huart2; DMA_HandleTypeDef hdma_usart2_rx; DMA_HandleTypeDef hdma_usart2_tx; /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_DMA_Init(void); static void MX_I2C1_Init(void); static void MX_USART2_UART_Init(void); /* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ /**   * @brief  The application entry point.   *   * @retval None   */ 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_DMA_Init();   MX_I2C1_Init();   MX_USART2_UART_Init();   /* USER CODE BEGIN 2 */ 	/* Checks if target device is ready for communication. */ 	/* 3 is number of trials, 1000ms is timeout */ 	if (HAL_I2C_IsDeviceReady(&hi2c1, device_address, 3, 1000) != HAL_OK) { 		/* Return error */ 		return HAL_ERROR; 	}   HAL_Delay(1000);   /* USER CODE END 2 */   /* Infinite loop */   /* USER CODE BEGIN WHILE */   while (1)   {   	/* Send WHO_AM_I register address */ 	while(HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)device_address, &register_address, 1, 1000) != HAL_OK){ 	/* Error_Handler() function is called when Timeout error occurs.        When Acknowledge failure occurs (Slave don't acknowledge it's address)        Master restarts communication */     if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)     {       Error_Handler();     } 	} 	/* Receieve data in the register */ 	while(HAL_I2C_Master_Receive(&hi2c1, device_address, &data, 1, 1000) != HAL_OK) { 	/* Error_Handler() function is called when Timeout error occurs.        When Acknowledge failure occurs (Slave don't acknowledge it's address)        Master restarts communication */     if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)     {       Error_Handler();     } 	} 	/* Send the data to serial buffer */         char tx[10]; 	HAL_UART_Transmit(&huart2, (uint8_t *)tx, sprintf(tx, "data: %d\n", data), 500);	 	HAL_Delay(100);	   }	 } /**   * @brief System Clock Configuration   * @retval None   */ void SystemClock_Config(void) {   RCC_OscInitTypeDef RCC_OscInitStruct;   RCC_ClkInitTypeDef RCC_ClkInitStruct;     /**Configure the main internal regulator output voltage      */   __HAL_RCC_PWR_CLK_ENABLE();   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);     /**Initializes the CPU, AHB and APB busses clocks      */   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;   RCC_OscInitStruct.HSIState = RCC_HSI_ON;   RCC_OscInitStruct.HSICalibrationValue = 16;   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;   RCC_OscInitStruct.PLL.PLLM = 8;   RCC_OscInitStruct.PLL.PLLN = 168;   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;   RCC_OscInitStruct.PLL.PLLQ = 4;   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)   {     _Error_Handler(__FILE__, __LINE__);   }     /**Initializes the CPU, AHB and APB busses clocks      */   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)   {     _Error_Handler(__FILE__, __LINE__);   }     /**Configure the Systick interrupt time      */   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);     /**Configure the Systick      */   HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);   /* SysTick_IRQn interrupt configuration */   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); } /* I2C1 init function */ static void MX_I2C1_Init(void) {   hi2c1.Instance = I2C1;   hi2c1.Init.ClockSpeed = 400000;   hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_16_9;   hi2c1.Init.OwnAddress1 = 0;   hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;   hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;   hi2c1.Init.OwnAddress2 = 0;   hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;   hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;   if (HAL_I2C_Init(&hi2c1) != HAL_OK)   {     _Error_Handler(__FILE__, __LINE__);   } } /* USART2 init function */ static void MX_USART2_UART_Init(void) {   huart2.Instance = USART2;   huart2.Init.BaudRate = 115200;   huart2.Init.WordLength = UART_WORDLENGTH_8B;   huart2.Init.StopBits = UART_STOPBITS_1;   huart2.Init.Parity = UART_PARITY_NONE;   huart2.Init.Mode = UART_MODE_TX_RX;   huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;   huart2.Init.OverSampling = UART_OVERSAMPLING_16;   if (HAL_UART_Init(&huart2) != HAL_OK)   {     _Error_Handler(__FILE__, __LINE__);   } } /**    * Enable DMA controller clock   */ static void MX_DMA_Init(void)  {   /* DMA controller clock enable */   __HAL_RCC_DMA1_CLK_ENABLE();   /* DMA interrupt init */   /* DMA1_Stream5_IRQn interrupt configuration */   HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);   HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);   /* DMA1_Stream6_IRQn interrupt configuration */   HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 0, 0);   HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn); } /** Pinout Configuration */ static void MX_GPIO_Init(void) {   /* GPIO Ports Clock Enable */   __HAL_RCC_GPIOA_CLK_ENABLE();   __HAL_RCC_GPIOB_CLK_ENABLE(); } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /**   * @brief  This function is executed in case of error occurrence.   * @param  file: The file name as string.   * @param  line: The line in file as a number.   * @retval None   */ void _Error_Handler(char *file, int line) {   /* USER CODE BEGIN Error_Handler_Debug */   /* User can add his own implementation to report the HAL error return state */   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,      tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */   /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */  |