Verbinden Sie STM32F103 mit MPU9250 über I2C mit HAL (ERROR)

Meine Erfahrung in der Programmierung von MCU ist nur Arduino (auch STM32F103 über Arduino). Ich habe jetzt begonnen, den STM32CUBEIDE und einen ST-Link V2 zu verwenden, um meinen STM32f103 zu programmieren.

Ich habe die Funktionen ausprobiert:

  • HAL_I2C_IsDeviceReady
  • HAL_I2C_Master_Transmit
  • HAL_I2C_Master_Receive
  • HAL_I2C_Mem_Read

und der Rückgabewert von 'HAL_StatusTypeDef' ist immer '1' beim ersten Aufruf und '2' bei den folgenden Aufrufen (einer der oben aufgeführten Funktionen).

1 bedeutet ERROR und 2 bedeutet BUSY. 3 würde TIMEOUT bedeuten und 0 würde OK bedeuten, soweit ich weiß.

Meine Fragen sind: Selbst wenn ich die I2C-Adresse ändere, ist die Rückgabe beim ersten Aufruf immer noch 1 (ERROR) und niemals 3 (TIMEOUT). Warum?

Laut diesem: https://os.mbed.com/users/EricLew/code/STM32L4xx_HAL_Driver/docs/tip/stm32l4xx__hal__i2c_8c_source.html#l02221

HAL_I2C_IsDeviceReadysollte nicht einmal 1 zurückgeben, nur 0 und 3 ...

Kann mir jemand sagen was ich falsch mache? Ich richte die Pins in STM32Cube (PB6 und PB7) richtig ein:

void MX_I2C1_Init(void)
{

  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 100000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  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();
  }

}

void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(i2cHandle->Instance==I2C1)
  {
  /* USER CODE BEGIN I2C1_MspInit 0 */

  /* USER CODE END I2C1_MspInit 0 */

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**I2C1 GPIO Configuration    
    PB6     ------> I2C1_SCL
    PB7     ------> I2C1_SDA 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* I2C1 clock enable */
    __HAL_RCC_I2C1_CLK_ENABLE();
  /* USER CODE BEGIN I2C1_MspInit 1 */

  /* USER CODE END I2C1_MspInit 1 */
  }
}

Und die initialize-Funktion aufgerufen (so wie die IDE im Code-Setup für mich vorbereitet hat):

/* USER CODE BEGIN 0 */
HAL_StatusTypeDef ret;
unsigned char buf[2];
uint16_t val;
int16_t valt;
float temp_c;
float RoomTemp_Offset = 0;
float Temp_Sensitivity = 321;
/* USER CODE END 0 */

int main(void)
{

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
  DWT_Delay_Init();
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_SPI1_Init();
  /* USER CODE BEGIN 2 */

  ret = HAL_I2C_IsDeviceReady(&hi2c1, MPU9250_ADDR, 10, 100);
  printf("Is Ready: %d \n", ret);
  /* USER CODE END 2 */

  /* Infinite loop */

  while (1)
  {
       // Tell MPU9250 that we want to read from the temperature register
      val = read_register(0x41);
      valt = ((int16_t)val << 4) | (val >> 4);
      temp_c = ((valt - RoomTemp_Offset)/Temp_Sensitivity) + 21;
      printf("reading...\n");
      printf("%.6f \n", temp_c);
  }
}

und die read_registerFunktion ist hier definiert:

uint16_t read_register(uint16_t register_pointer)
{
    HAL_StatusTypeDef status = HAL_OK;
    uint16_t return_value = 0;
    status = HAL_I2C_Mem_Read(&hi2c1, MPU9250_ADDR, (uint16_t)register_pointer, I2C_MEMADD_SIZE_8BIT, &return_value, 2, 100);
    printf("read HAL_RET: %d \n", status);
    /* Check the communication status */
    if(status != HAL_OK)
    {
        Error_Handler();
    }

    return return_value;
}

und die Gesamtausgabe des Skripts ower SWO:

Is Ready: 1 
read HAL_RET: 2 
reading...

read HAL_RET: 2 
reading...

read HAL_RET: 2 
reading...

read HAL_RET: 2 
Sind Sie sicher, dass Ihre Hardware richtig angeschlossen ist? Welche Klimmzüge verwendest du?

Antworten (1)

Okay, danke Brhans für deinen Kommentar. Ich dachte, ich hätte mich darum gekümmert, aber die Taktlinie wurde auf 3v3 hochgezogen, jetzt funktioniert es. Vielen Dank!

Auch diese Zeile habe ich geändert

valt = ((int16_t)val << 4) | (val >> 4);

Zu

valt = ((int16_t)buf[0] << 8) | (buf[1]);