我发现有几个人问过这个问题,但是他们都在用Arduino编码,我很难把它翻译成我的项目。
我是一个研究小组开发一个立方体卫星发射,我的职责是与外围设备,包括IMU (MPU-9250)通信。我正在与uClinux交叉编译,用C语言编写代码。
到目前为止,我可以成功地读取加速度计,陀螺仪和温度,但无法从磁强计中获得读数。磁强计(AK8963)有它自己的地址(0x0C),我一直试图通过写信给I2C_SLV0_ADDR(0x25),I2C_SLV0_REG(0x26),和I2C_SLV0_CTRL(0x27).与它通信当我没有得到任何结果时,我试图通过写信给FIFO启用(0x23)和I2C主控制(0x24)来解决这个问题。
数据表和寄存器映射意味着,从磁强计获取的值存储在寄存器外部传感器数据(0x49-0x60)中,但是当我尝试这样做时,我不会在这些寄存器中得到任何信息。
下面是一些代码,显示我正在写入寄存器的数据:
write_register(0x23, 0x04);
write_register(0x24, 0b11110000);
write_register(0x25,0x8c);
write_register(0x26,0x00);
write_register(0x27,0b11110001);所以我的问题是: 1.我是以正确的方式进行这个过程,还是完全失控?
谢谢大家的帮助!如果有什么我需要澄清的,请告诉我!
发布于 2017-05-12 16:14:53
好了!我想出了自己的问题:)
( 1)我确实走错了路。有一种更容易做到的方法,我将详细说明。
2)我没有从正确的登记簿上阅读。下面我来演示一下该怎么做。
因此,连接到磁强计是非常容易的,但一点也不直观。它的行为就像它自己的从地址,但是这个地址最初是无法访问的。
由于我与uClinux交叉编译,所以我可以使用bash命令i2cdetect 0 (在筛选到i2cdetect 0中时)检查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返回以下数据and。
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: -- -- -- -- -- -- -- -- 该程序还返回0x48,这是从磁强计的“I是谁?”中读取的正确值。注册。磁强计现在可以像任何其他寄存器一样被读取。希望这能帮上忙!
https://stackoverflow.com/questions/43920137
复制相似问题