【问题标题】:I can't get data with I2C from mpu6050 on STM32F103我无法通过 STM32F103 上的 mpu6050 使用 I2C 获取数据
【发布时间】:2019-12-19 05:11:40
【问题描述】:

我是新的 I2C 通信。我检查了一些正在运行的代码。我使用了他们使用的功能。但我无法获得任何数据。我想知道 I2C 是否必须进行初始配置?哪里有问题。这是我写的函数:

void GetI2CAccelerometer(uint8_t slaveAddress,uint8_t accelData[6])
{   
    // slaveAddress=0x68 (default address is written in datasheet)  
    HAL_I2C_Master_Transmit(&hi2c1,slaveAddress<<1,1,0x3B,1,200);
    HAL_I2C_Master_Receive(&hi2c1,slaveAddress<<1,accelData,6,200);
    HAL_I2C_Mem_Read(&hi2c1,(slaveAddress<<1)+1,0x3B,1,accelData,1,200);
    // i tried this function too but not working
}

我使用 CubeMX 创建了这个项目。这是初始 I2C 配置,GPIO_A 时钟线在另一个我没有写的函数中被激活:

static void MX_I2C1_Init(void) 
{
    hi2c1.Instance = I2C1;
    hi2c1.Init.ClockSpeed = 100000;
    hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
    hi2c1.Init.OwnAddress1 = 208;
    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();
    }
}

【问题讨论】:

  • I2C 和 GPIO 的初始化代码是什么?您是否为 I2C 连接了正确的上拉电阻。是否有数据从引脚输出或完全没有发生?
  • 我已经编辑了初始 I2C 代码。我在主函数中编写了这段代码:HAL_I2C_Init(&hi2c1); mpu6050直接连接到stm32。我没有使用任何电阻。我看的地方没有电阻。我应该连接吗?
  • @Alperen,是的,你必须使用上拉电阻。通常 3.3K 对于 3.3V 电源的短线是不错的选择。
  • 另外,HAL_I2C_Mem_Read 是干什么用的?这是与 I2C 内存芯片配合使用的特殊功能。
  • 尝试将速度降低到 88000。i2c 在 STM32s 上很古怪。

标签: stm32 i2c mpu6050


【解决方案1】:

首先,最好使用DMA或IT数据交换。轮询不好,但可以测试。

您必须放置指向数据的指针,而不是数据本身。好的做法是这样的:

void GetI2CAccelerometer(I2C_HandleTypeDef * hi2c, uint8_t slaveAddress, uint8_t * accelData, size_t size) {
    uint8_t request = 0x3B;

    // slaveAddress=0x68 (default address is written in datasheet)
    // HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
    while (HAL_I2C_Master_Transmit(hi2c, slaveAddress << 1, (uint8_t*)request, 1, 200) != HAL_OK) {
        // Use FreeRTOS vTaskDelay(1) and/or check errors here
        // And check timeout or you will hang over here
    }

    //HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
    while (HAL_I2C_Master_Receive(hi2c, slaveAddress << 1, accelData, size, 200) != HAL_OK) {
        // Use FreeRTOS vTaskDelay(1) and/or check errors here
        // And check timeout or you will hang over here
    }

    while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY) {
        // Use FreeRTOS vTaskDelay(1) and/or check errors here
        // And check timeout or you will hang over here
    }
}

然后通过函数请求数据:

uint8_t accelData[6];

GetI2CAccelerometer(&hi2c1, 0x68, accelData, 6);

这对于测试来说没问题,但对生产不利。获取数据,然后重写以使用 I2C DMA 或 IT。检查 I2C 总线上的错误并进行一些枚举以从函数返回错误/状态。

【讨论】:

  • 我使用了 5k 上拉电阻。 Vcc 为 5v。我把它们放在 vcc 到 sda、vcc 到 scl 之间。但是您的代码卡在这里: if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) { return HAL_BUSY; }
  • 在 HAL_I2C_Master_Transmit() 函数中
  • @Alperen,STM32和5V电源?
  • @Alperen,仔细检查连接。好像有人把线拉下来了。并检查设备地址,它由AD0 引脚设置。地址可能是 0x68 或 0x69。
  • 我刚试过 3.3v 和 3.2k 还是不行
猜你喜欢
  • 1970-01-01
  • 2018-04-05
  • 2020-04-24
  • 2020-06-17
  • 1970-01-01
  • 2016-11-14
  • 1970-01-01
  • 1970-01-01
  • 2015-05-26
相关资源
最近更新 更多