MPU6050 не отвечает на адрес 0x68, но отображается в отсканированных адресах I2C

Когда я запускаю сканер I2C на STM32F303, я вижу, что оба устройства подключены к шине. Называет устройство по адресу 0x3C (OLED) и адресу (0x68) MPU6050. Оба адреса, в частности, согласуются с тем, что написано в таблице данных.

Однако, когда я пытаюсь прочитать регистр WHO_AM_I по адресу 0x68 с помощью HAL_I2C_IsDeviceReady, я понимаю, что это даже время ожидания.

int main(void)
{
    HAL_Init();
    SystemClock_Config();

    MX_GPIO_Init();
    MX_I2C1_Init();
    MX_SPI1_Init();
    MX_TIM6_Init();
    MX_USART1_UART_Init();

    I2C_Scanner();
    SSD1306_Init();

    HAL_Delay (2000);

    MPU6050_Init();

    while (1)
    {

    }
}

Функция (MPU6050_Init) для проверки готовности устройства

static void MPU6050_Init(void)
{
    HAL_Delay(1);
    SSD1306_Clear();
    SSD1306_GotoXY (0, 0);
    char OutputArray[50] = {0};

    if(HAL_I2C_IsDeviceReady(&hi2c1, MPU6050_I2C_ADDR, 10, HAL_MAX_DELAY) != HAL_OK)
    {
        sprintf(OutputArray, "0x%02x : Not ready", MPU6050_I2C_ADDR);
    }
    else
    {
        HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_SET);

        uint8_t check;

        HAL_I2C_Mem_Read(&hi2c1, MPU6050_I2C_ADDR, WHO_AM_I_REG, 1, &check, 1, HAL_MAX_DELAY);

        sprintf(OutputArray,"0x%02x", (uint16_t)check);
    }
    HAL_Delay(1);
    SSD1306_Puts (OutputArray, &Font_7x10, SSD1306_COLOR_WHITE);
    SSD1306_UpdateScreen();
}

Функция (I2C_Scanner) для сканирования шины I2C для доступных устройств

static void I2C_Scanner(void)
{
    HAL_StatusTypeDef result;
    uint8_t i;
    for (i = 1; i < 128; i++)
    {
        result = HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(i << 1), 1, HAL_MAX_DELAY);
        char* period = ".";
        char OutputArray[5];

        if (result != HAL_OK) // HAL_ERROR or HAL_BUSY or HAL_TIMEOUT
        {
              HAL_UART_Transmit(&huart1, (uint8_t*)period, sizeof(period), HAL_MAX_DELAY);
        }

        if (result == HAL_OK)
        {
            sprintf(OutputArray, "0x%02x", i); // Received an ACK at that address
            HAL_UART_Transmit(&huart1, (uint8_t*)OutputArray, sizeof(OutputArray), HAL_MAX_DELAY);
        }

        HAL_Delay(1);
    }
}

Функция (MC_I2C1_Init) для инициализации I2C

static void MX_I2C1_Init(void)
{
    hi2c1.Instance = I2C1;
    hi2c1.Init.Timing = 0x0000020B;
    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();
    }

    if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
    {
        Error_Handler();
    }

    if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
    {
        Error_Handler();
    }
}

Ожидаемые результаты заключаются в том, чтобы проверить, что устройство доступно, готово и передать обратно содержимое регистра WHO_AM_I.


person Hakim Marley    schedule 05.11.2019    source источник


Ответы (1)


Нашел решение. Проблема заключалась в том, что я определил адрес MPU6050 следующим образом

#define MPU6050_I2C_ADDR    0x68

Правильное определение должно было быть

#define MPU6050_I2C_ADDR    0x68 << 1

В результате получилось 0xD0

person Hakim Marley    schedule 06.11.2019