简体   繁体   中英

I can't get data with I2C from mpu6050 on STM32F103

I am new I2C communication. I examined some running code. And I used function their used. But I can't get any data. I wonder if I2C have to do initial config? Where is the problem. This is function I wrote:

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
}

I created this project with CubeMX. This is initial I2C config and also GPIO_A clock line is activated in another function which I did not write:

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

First of all, better use DMA or IT data exchange. Polling is not good, but ok for testing.

You must put pointers to data, not the data itself. The good practice is something like this:

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

And then request data by function:

uint8_t accelData[6];

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

Thats ok for testing, but bad for production. Get the data and then rewrite to use I2C DMA or IT. Check errors at I2C bus and make some enum to return errors/states from function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM