MPU-9250 (uClinux) 上的磁力计数据
Magnetometer data on MPU-9250 (uClinux)
我发现其他一些人问过这个问题,但他们都在 Arduino 中编码,我正在努力将其转化为我的项目。
我所在的研究团队正在开发用于发射的立方体卫星,我的职责是与外围设备通信,包括 IMU (MPU-9250)。我正在用 uClinux 交叉编译,用 C 编码。
到目前为止,我可以成功读取加速度计、陀螺仪和温度,但无法从磁力计读取读数。磁力计 (AK8963) 有自己的地址 (0x0C),我一直试图通过写入 I2C_SLV0_ADDR(0x25), 来与它通信I2C_SLV0_REG(0x26) 和 I2C_SLV0_CTRL(0x27)。一旦我似乎没有得到任何结果,我试图通过写入 FIFO Enable(0x23) 和 I2C Master Control(0x24 )
数据表和寄存器映射暗示从磁力计获取的值存储在寄存器外部传感器数据(0x49-0x60)中,但我在这些寄存器中没有得到任何东西当我尝试这个时注册。
下面是一些显示我正在写入寄存器的数据的代码:
write_register(0x23, 0x04);
write_register(0x24, 0b11110000);
write_register(0x25,0x8c);
write_register(0x26,0x00);
write_register(0x27,0b11110001);
所以我的问题是:
1. 我是以正确的方式进行这个过程,还是我完全偏离了?
- 如果我在正确的轨道上,我是否从正确的寄存器读取?
感谢大家的帮助!如果有任何需要澄清的地方,请告诉我!
好的!我想出了我自己的问题:)
1) 我确实以错误的方式进行了处理。有一种更简单的方法可以做到这一点,我将详细说明。
2) 我没有从正确的寄存器读取。我将在下面展示该怎么做。
因此,连接到磁力计非常简单,但一点也不直观。它确实像它自己的从机一样,有自己的从机地址,但该地址最初是不可访问的。
由于我正在与 uClinux 交叉编译,我可以使用 bash 命令 i2cdetect 0
(当筛选到我的 SmartFusion2 时)检查我的 i2C 0 总线上的所有从站。当我重置我的板后执行此命令时,我打印出以下地址映射:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
所以你可以看到只显示了 IMU(0x68) 的地址。为了正确显示磁力计,您必须在 INT_PIN_CFG(0x37) 上启用旁路位。我在下面附上了我的代码,以防有人需要复制它。
#include <stdio.h>
//#include <linux/i2c-dev.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define IMU_ADDR 0x68
#define IMU_WHO_AM_I 0x75
int file;
void i2c_init();
void write_register(uint8_t register_address, uint8_t value);
uint8_t read_register(uint8_t register_address);
void i2c_init(address){
int adapter_nr = 0;
char filename[20];
snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
file = open(filename, O_RDWR);
if(file < 0)
printf("Error: Failed to open file %s\n", filename);
int success= (ioctl(file, I2C_SLAVE, address));
if(file < 0) {
printf("Error: IMU I2C Failed to Open\n");
//return -1;
}
}
void write_register(uint8_t register_address, uint8_t value){
uint8_t data[]={register_address,value};
write(file, data,ARRAY_SIZE(data));
}
uint8_t read_register(uint8_t register_address){
uint8_t value;
if(write(file, ®ister_address, sizeof(register_address)) !=1)
{
printf("%d\n",write(file, ®ister_address, sizeof(register_address)));
printf("Failed to send data\n");
}
read(file, &value, sizeof(value));
return value;
}
int main(){
i2c_init(IMU_ADDR);
printf("\nNow testing the 'Who am I?' IMU register. Output should be 0x71\n");
printf("Register 0x75: 0x%02X \n", read_register(IMU_WHO_AM_I));
write_register(0x37, 0x22);
i2c_init(0x0C);
printf("\nNow testing the 'Who am I?' Magnetometer register. Output should be 0x48\n");
printf("Register 0x00: 0x%02x\n", read_register(0x00));
return 0;
}
代码编译完成后运行,命令i2cdetect 0
returns如下数据图。
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- 0c -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
程序还 returns 0x48,从磁力计的 'who am I?' 寄存器读取时的正确值。现在可以像读取任何其他寄存器一样读取磁力计。希望这对您有所帮助!!
我发现其他一些人问过这个问题,但他们都在 Arduino 中编码,我正在努力将其转化为我的项目。
我所在的研究团队正在开发用于发射的立方体卫星,我的职责是与外围设备通信,包括 IMU (MPU-9250)。我正在用 uClinux 交叉编译,用 C 编码。
到目前为止,我可以成功读取加速度计、陀螺仪和温度,但无法从磁力计读取读数。磁力计 (AK8963) 有自己的地址 (0x0C),我一直试图通过写入 I2C_SLV0_ADDR(0x25), 来与它通信I2C_SLV0_REG(0x26) 和 I2C_SLV0_CTRL(0x27)。一旦我似乎没有得到任何结果,我试图通过写入 FIFO Enable(0x23) 和 I2C Master Control(0x24 )
数据表和寄存器映射暗示从磁力计获取的值存储在寄存器外部传感器数据(0x49-0x60)中,但我在这些寄存器中没有得到任何东西当我尝试这个时注册。
下面是一些显示我正在写入寄存器的数据的代码:
write_register(0x23, 0x04);
write_register(0x24, 0b11110000);
write_register(0x25,0x8c);
write_register(0x26,0x00);
write_register(0x27,0b11110001);
所以我的问题是: 1. 我是以正确的方式进行这个过程,还是我完全偏离了?
- 如果我在正确的轨道上,我是否从正确的寄存器读取?
感谢大家的帮助!如果有任何需要澄清的地方,请告诉我!
好的!我想出了我自己的问题:)
1) 我确实以错误的方式进行了处理。有一种更简单的方法可以做到这一点,我将详细说明。
2) 我没有从正确的寄存器读取。我将在下面展示该怎么做。
因此,连接到磁力计非常简单,但一点也不直观。它确实像它自己的从机一样,有自己的从机地址,但该地址最初是不可访问的。
由于我正在与 uClinux 交叉编译,我可以使用 bash 命令 i2cdetect 0
(当筛选到我的 SmartFusion2 时)检查我的 i2C 0 总线上的所有从站。当我重置我的板后执行此命令时,我打印出以下地址映射:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
所以你可以看到只显示了 IMU(0x68) 的地址。为了正确显示磁力计,您必须在 INT_PIN_CFG(0x37) 上启用旁路位。我在下面附上了我的代码,以防有人需要复制它。
#include <stdio.h>
//#include <linux/i2c-dev.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define IMU_ADDR 0x68
#define IMU_WHO_AM_I 0x75
int file;
void i2c_init();
void write_register(uint8_t register_address, uint8_t value);
uint8_t read_register(uint8_t register_address);
void i2c_init(address){
int adapter_nr = 0;
char filename[20];
snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
file = open(filename, O_RDWR);
if(file < 0)
printf("Error: Failed to open file %s\n", filename);
int success= (ioctl(file, I2C_SLAVE, address));
if(file < 0) {
printf("Error: IMU I2C Failed to Open\n");
//return -1;
}
}
void write_register(uint8_t register_address, uint8_t value){
uint8_t data[]={register_address,value};
write(file, data,ARRAY_SIZE(data));
}
uint8_t read_register(uint8_t register_address){
uint8_t value;
if(write(file, ®ister_address, sizeof(register_address)) !=1)
{
printf("%d\n",write(file, ®ister_address, sizeof(register_address)));
printf("Failed to send data\n");
}
read(file, &value, sizeof(value));
return value;
}
int main(){
i2c_init(IMU_ADDR);
printf("\nNow testing the 'Who am I?' IMU register. Output should be 0x71\n");
printf("Register 0x75: 0x%02X \n", read_register(IMU_WHO_AM_I));
write_register(0x37, 0x22);
i2c_init(0x0C);
printf("\nNow testing the 'Who am I?' Magnetometer register. Output should be 0x48\n");
printf("Register 0x00: 0x%02x\n", read_register(0x00));
return 0;
}
代码编译完成后运行,命令i2cdetect 0
returns如下数据图。
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- 0c -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
程序还 returns 0x48,从磁力计的 'who am I?' 寄存器读取时的正确值。现在可以像读取任何其他寄存器一样读取磁力计。希望这对您有所帮助!!