You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用指针读取MPU9250寄存器失败,求原因解析

为什么用空指针读取MPU9250 WHO_I_AM寄存器会得到错误值?

我尝试用Asukiaaa的Arduino库通过I2C读取MPU9250的WHO_I_AM寄存器,库中readId函数的定义如下:

uint8_t MPU9250_asukiaaa::readId(uint8_t *id) {
  beginWireIfNull();
  return i2cRead(address, MPU9250_ADDR_WHOAMI, 1, id);
}

根据芯片 datasheet,该寄存器的预期返回值为0x71。

错误写法(返回0x61)

尝试用空指针存储寄存器值的代码:

#include <MPU9250_asukiaaa.h>
#include <Adafruit_BMP280.h>

Adafruit_BMP280 bmp; // I2C
MPU9250_asukiaaa mySensor;
uint8_t *Id=NULL;

void setup() {
  Serial.begin(9600);
  while (!Serial);

#ifdef _ESP32_HAL_I2C_H_ // For ESP32
  Wire.begin(SDA_PIN, SCL_PIN);
  mySensor.setWire(&Wire);
#else
  Wire.begin();
  mySensor.setWire(&Wire);
#endif
  
  bmp.begin(0x76);
  mySensor.beginAccel();
  mySensor.beginGyro();
  mySensor.beginMag();

}

void loop() {
  mySensor.readId(Id);
  Serial.print(*Id,HEX);
}

正确写法(返回0x71)

改用普通变量并传入其地址的代码:

#include <MPU9250_asukiaaa.h>
#include <Adafruit_BMP280.h>

Adafruit_BMP280 bmp; // I2C
MPU9250_asukiaaa mySensor;
uint8_t Id=0;

void setup() {
  Serial.begin(9600);
  while (!Serial);

#ifdef _ESP32_HAL_I2C_H_ // For ESP32
  Wire.begin(SDA_PIN, SCL_PIN);
  mySensor.setWire(&Wire);
#else
  Wire.begin();
  mySensor.setWire(&Wire);
#endif
  
  bmp.begin(0x76);
  mySensor.beginAccel();
  mySensor.beginGyro();
  mySensor.beginMag();

}

void loop() {
  mySensor.readId(&Id);
  Serial.print(Id,HEX);
}

差异原因

核心问题是空指针uint8_t *Id=NULL;没有指向有效且可写入的内存空间:

  • 错误写法中,调用mySensor.readId(Id)时,函数内部的i2cRead尝试将寄存器值写入Id指向的地址,但Id是NULL(空地址),这属于C/C++中的未定义行为——程序可能崩溃,也可能误写入随机内存地址,你读出的0x61就是该随机地址中的垃圾值。
  • 正确写法里,uint8_t Id=0;定义了一个实际的uint8_t变量,它在内存中占据1字节的有效空间。调用mySensor.readId(&Id)时,传入的是这个变量的真实内存地址,i2cRead可以安全地将寄存器值写入该地址,因此能得到正确的0x71。

总结:指针仅用于存储内存地址,必须先让它指向一块真实存在的内存区域,才能用来存储数据。空指针没有指向任何有效内存,写入操作完全无效,读取结果自然错误。

内容的提问来源于stack exchange,提问作者AF2021

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 22:17:43