2021-12-10 11:48 PM
Hi everyone,
I'm really new to the whole concept of STM32, and I'm having trouble interfacing with my MPU-9250, which looks like:
The Breakout board does not actually do much to the Invensense MPU-9250 chip, only provides some basic power regulation and pull-ups.
My STM32 Board is the Nucleo F411RE, and I've hooked them up like this:
I found a library for the core chip of the InvenSense MPU-9250 for STM32 here: https://github.com/talhaSr/mpu9250
I'm also attaching the main.cpp file which I created for the project hoping it could show how I'm implementing the code. I've added the libraries (also declaring which I2C port to use in mpu9250.c as per the wiring diagram) from the github page as shown below:
The MPU-9250 breakout board doesn't seem to connect, as it returns a 0 during the whoAmI_Check function.
Any help on why the device is not connected would be greatly appreciated.
2021-12-11 07:28 AM
Use HAL_I2C_IsDeviceReady and ensure it returns HAL_OK to verify connectivity before you do anything else.
Your logic here is faulty. If the function returns HAL_OK, then data has not been populated and you shouldn't be checking it. If the function succeeds, you don't verify the value in your code.
HAL_StatusTypeDef whoAmI_Check(MPU9250_t *mpu9250)
{
uint8_t data;
/* MPU9250 Who Am I Register Check */
if (readByte(&hi2c2, mpu9250 -> I2C_Addr, WHO_AM_I, &data) != HAL_OK)
{
if (data != 0x71)
return HAL_ERROR;
}
/* AK8963 Who Am I Register Check */
if (readByte(&hi2c2, mpu9250 -> I2C_Addr_Mag, WIA, &data) != HAL_OK)
{
if (data != 0x48)
return HAL_ERROR;
}
return HAL_OK;
}
It's possible your slave address is incorrect. You haven't included enough code to verify. The slave address passed to HAL_I2C_* functions should be left-shifted.
Also need to verify the MPU9250 is in I2C mode and not SPI mode. I didn't check this.
2021-12-11 05:15 PM
Hi TDK,
Thank you for your reply. I have now uploaded the library source and header files (in the original post) that are currently in my project.
You were right, I believe that the Datasheet states that the address of the MPU-9250 should be (0x68) as pin AD0 is left floating by default:
I have now changed the address from 0x71 to 0x68 (still doesn't work).
Since I'm a super beginner, I'm not sure what you mean by the fault in logic. The tutorials I have seen have not helped me understand the function HAL_I2C_IsDeviceReady to a thorough extent. It's worth mentioning that this bit is from the library I downloaded from the GitHub page in my original link.
I'm also not sure what you mean by left-shifting the addresses, a single example would help me greatly.
I apologise for not being of any more help, I did however find this register map in an Arduino Library to connect to the MPU-9250. There are slight differences from the registers listed in mpu9250.h, though I'm not sure what this means. I can confirm that I've been able to connect to the MPU-9250 using my Arduino Due and the official Arduino library that I got these registers from.
Thanks again for your help
2021-12-15 03:32 AM
Hello,
>> I'm also not sure what you mean by left-shifting the addresses, a single example would help me greatly.
TDK means that the I²C address given in the datasheet is 7 bits long, when HAL_I2C_IsDeviceReady, and the other HAL functions are expecting it on 8 bits.
So if you have :
HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
and the datasheet says 0x68
DevAddress field should be 0x68 << 1 = 0xD0.
Bit 0 is the R/W bit, the HAL functions take care of that bit, leave it to 0.
2021-12-15 07:00 AM
>if (readByte(&hi2c2, mpu9250 -> I2C_Addr, WHO_AM_I, &data) != HAL_OK)
> {
> if (data != 0x71)
> return HAL_ERROR;
> }
> I'm not sure what you mean by the fault in logic
If readByte succeeds and returns HAL_OK, you don't check data for the correct value.