I2C接口读取MPU9250磁力数值

一开始拿到芯片手册云里雾里,根本没有找到关于磁力数据的寄存器,结果上网一查才知道,这芯片竟然是个胶水芯片。。。

MPU9250内部是MPU6050和AK8963两个芯片合并在一起的,感觉傻傻的。

内部的AK8963是负责三轴磁力传感器采样的芯片,它通过I2C总线与MPU9250连接在一起。

如上图所示,MPU9250还集成了一个I2C主机控制器。默认情况下MPU9250用它的I2C主机控制器与AK8963通信,把磁力值读到出放到指定的寄存器中,这需要设置一堆寄存器,真是麻烦得一逼!!!

幸好MPU9250还预留了I2C直通模式,这个模式相当于MPU9250和AK8963共同使用一条I2C总线,因为它们的通信地址不一样,

MPU9250的地址:0xD0/0xD1

AK8963的地址:0x18/0x19

在写驱动程序的时候,可以把它们当作硬件上分离的两个芯片挂在同一条I2C总线上。

直通模式需要设置MPU9250的第55号寄存器的Bit1写1即可开启。


有了直通模式我们就可以直接与AK8963通信了,AK8963的寄存器不多。

下面讲讲几个关键寄存器操作:

0x00:这个寄存器是芯片ID=0x48,能读出这个ID证明通信OK了。

0x0A:设置工作模式,建议上电后先写入0x0F,读取出芯片校准系数;然后再写0x01,进行单次采样。

0x02:状态寄存器,BIT0为1表示采样完成,可以读取采样数据了。网上有人说读不到数据,加上10毫秒延时就能读出数据,就是因为没有检查状态值。经过实验测试单次采样大概需要6-8毫秒。

0x03-0x08:数据寄存器,三个轴,每个轴的数据都分为高8位和低8位,组成16位的有符号整数。

0x10-0x12:校准寄存器,出厂设置的校准参数,当0x0A寄存器写入0x0F后才可以读出来。

手册上写了数据校准参数的用法:

Hadj是校准后的数据;

H是读出来的原始采样数据;

ASA是校准寄存器读出来的参数;


得到正确的三轴磁力数值后,就可以用来实现一个简单的电子指南针了。

在水平面的方向=180 + arctan(Y, X) * 180 / PI; 

由于环境干扰,还需要加入一个平面校准算法:将芯片在水平面原地转360度,记录三个轴的采样值的最大值和最小值,求得(最大值+最小值)除以2得到偏移值。将原始采样值减去偏移值之后,再送入上面的公式计算角度会更准确。

 

 

### AK8963 连续测量模式使用方法及配置 #### 配置连续测量模式 为了使AK8963进入连续测量模式,需要设置特定的寄存器位。这通常通过SPI或I2C接口完成。对于AK8963,在控制寄存器`CNTL1`中设定相应的位来启动连续测量模式。 ```c // 设置AK8963进入连续测量模式 (Mode 8) void setContinuousMeasurementMode() { uint8_t modeRegisterValue = 0x00; // 将模式设为连续测量模式(0b00010000),并启用16-bit传输(0b00000001) modeRegisterValue |= (1 << 4); // Mode 8: Continuous measurement mode with fuse ROM access disabled. modeRegisterValue |= (1 << 0); // Set to 16 bit data output writeByte(AK8963_I2C_ADDRESS, AK8963_CNTL1, modeRegisterValue); } ``` 此函数将设备置于连续测量模式,并确保数据输出采用16位格式[^1]。 #### 获取磁场强度数据 一旦传感器处于连续测量状态,则可以通过读取相应地址的数据寄存器获得实时更新的地磁矢量分量: ```c int16_t readMagData(uint8_t regAddress) { int16_t value; uint8_t buffer[2]; // 从指定寄存器开始读取两个字节的数据 readBytes(AK8963_I2C_ADDRESS, regAddress, sizeof(buffer), &buffer); // 合成高低字节形成完整的16位数值 value = ((int16_t)(buffer[0]) << 8) | buffer[1]; return value; } float getMagneticFieldStrengthXYZ(float *magX, float *magY, float *magZ){ static const float magSensitivity = 4900.0f / 32760.0f; *magX = readMagData(HXL) * magSensitivity; *magY = readMagData(HYL) * magSensitivity; *magZ = readMagData(HZL) * magSensitivity; return sqrt((*magX)*(*magX)+ (*magY)*(*magY)+ (*magZ)*(*magZ)); } ``` 上述代码片段展示了如何获取三轴地磁强度值以及计算总场强的方法。 #### 处理潜在问题 如果遇到初始化过程中无法正确识别器件ID的情况,可能是由于模块初始化顺序不当引起的。建议先尝试稳定电源供应再进行任何通信操作,并确保所有必要的延时都已加入程序逻辑之中[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值