MPU6050 在地址 0x68 上没有响应,但出现在 I2C 扫描地址中

MPU6050 not responding on address 0x68 but shows up in I2C Scanned addresses

当我 运行 STM32F303 上的 I2C 扫描器时,我看到两个设备都连接到总线。在地址 0x3C (OLED) 和地址 (0x68) MPU6050 上命名设备。这两个地址,特别同意数据表中的内容。

但是,当我尝试使用 HAL_I2C_IsDeviceReady 读取地址 0x68 上的 WHO_AM_I 寄存器时,我意识到它甚至会超时。

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 总线以查找可用设备的函数 (I2C_Scanner)

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);
    }
}

初始化I2C的函数(MC_I2C1_Init)

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 寄存器

的内容

找到解决办法。问题是我定义了 MPU6050 地址如下

#define MPU6050_I2C_ADDR    0x68

正确的定义应该是

#define MPU6050_I2C_ADDR    0x68 << 1

这导致 0xD0