这个芯片复位跟一般芯片不一样,高电平复位,低电平有效。
下面代码接收显示,得到的应该是xyz的磁感强度,还需要自己算法做方位算法校准算法等
qmi8610
//main.cpp
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <ctype.h>
#include <math.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <memory.h>
#include "main.h"
// unsigned int Linux_IICNum = 0;//使用海思的那个iic
int Rd_I2C(int Linux_IICNum, unsigned int chipAddr, unsigned int regAddr)
{
int retval = 0;
int fd = -1, tmp, i;
char file_name[0x10];
unsigned char buf[4];
unsigned int i2c_num, dev_addr, reg_addr, reg_addr_end;
unsigned int reg_width = 1, data_width = 1, reg_step = 1;
int cur_addr;
static struct i2c_rdwr_ioctl_data rdwr;
static struct i2c_msg msg[2];
unsigned int data;
memset(buf, 0x0, 4);
i2c_num = Linux_IICNum;
dev_addr = chipAddr;
reg_addr = regAddr;
reg_addr_end = regAddr;
dev_addr = dev_addr >> 1;
#ifdef DEBUG
printf("i2c_num:0x%x, dev_addr:0x%x; reg_addr:0x%x; reg_addr_end:0x%x; \
reg_width: %d; data_width: %d; reg_step: %d. \n\n",
i2c_num, dev_addr << 1, reg_addr, reg_addr_end,
reg_width, data_width, reg_step);
#endif // DEBUG
sprintf(file_name, "/dev/i2c-%u", i2c_num);
fd = open(file_name, O_RDWR);
if (fd < 0)
{
printf("Open %s error!\n", file_name);
retval = -1;
goto end0;
}
retval = ioctl(fd, I2C_SLAVE_FORCE, dev_addr);
if (retval < 0)
{
printf("CMD_SET_I2C_SLAVE error!\n");
retval = -1;
goto end1;
}
msg[0].addr = dev_addr;
msg[0].flags = 0;
msg[0].len = reg_width;
msg[0].buf = buf;
msg[1].addr = dev_addr;
msg[1].flags = 0;
msg[1].flags |= I2C_M_RD;
msg[1].len = data_width;
msg[1].buf = buf;
rdwr.msgs = &msg[0];
rdwr.nmsgs = (__u32)2;
for (cur_addr = reg_addr; cur_addr <= reg_addr_end; cur_addr += reg_step)
{
if (reg_width == 2)
{
buf[0] = (cur_addr >> 8) & 0xff;
buf[1] = cur_addr & 0xff;
}
else
buf[0] = cur_addr & 0xff;
retval = ioctl(fd, I2C_RDWR, &rdwr);
if (retval != 2)
{
printf("CMD_I2C_READ error!\n");
retval = -1;
goto end1;
}
if (data_width == 2)
{
data = buf[1] | (buf[0] << 8);
}
else
data = buf[0];
// printf("0x%x: 0x%x\n", cur_addr, data);
}
retval = data;
end1:
close(fd);
end0:
return retval;
}
int Wr_I2C(int Linux_IICNum, unsigned int chipAddr, unsigned int regAddr, unsigned int pData)
{
int retval = 0;
int fd = -1;
int index = 0, tmp, i;
char file_name[0x10];
unsigned char buf[4];
unsigned char i2c_num, dev_addr, reg_addr, data;
unsigned int reg_width = 1, data_width = 1;
i2c_num = Linux_IICNum;
dev_addr = chipAddr;
reg_addr = regAddr;
data = pData;
dev_addr = dev_addr >> 1;
#ifdef DEBUG
printf("i2c_num:0x%x, dev_addr:0x%x; reg_addr:0x%x; data:0x%x; reg_width: %d; data_width: %d.\n",
i2c_num, dev_addr << 1, reg_addr, data, reg_width, data_width);
#endif
sprintf(file_name, "/dev/i2c-%u", i2c_num);
fd = open(file_name, O_RDWR);
if (fd < 0)
{
printf("Open %s error!\n", file_name);
retval = -1;
goto end0;
}
retval = ioctl(fd, I2C_SLAVE_FORCE, dev_addr);
if (retval < 0)
{
printf("set i2c device address error!\n");
retval = -1;
goto end1;
}
if (reg_width == 2)
{
buf[index] = (reg_addr >> 8) & 0xff;
index++;
buf[index] = reg_addr & 0xff;
index++;
}
else
{
buf[index] = reg_addr & 0xff;
index++;
}
if (data_width == 2)
{
buf[index] = (data >> 8) & 0xff;
index++;
buf[index] = data & 0xff;
index++;
}
else
{
buf[index] = data & 0xff;
index++;
}
for (int i = 0; i < 2; i++)
{
retval = write(fd, buf, (reg_width + data_width));
if (retval < 0)
{
printf("i2c write error! i2c_num:0x%x, dev_addr:0x%x; reg_addr:0x%x; data:0x%x; reg_width: %d; data_width: %d.\n",
i2c_num, dev_addr << 1, reg_addr, data, reg_width, data_width);
retval = -1;
}
else
{
retval = 0;
break;
}
}
end1:
close(fd);
end0:
return retval;
}
int main(int argc, char *argv[])
{
while (1)
{
unsigned int mxyz[10][3] = {0};
unsigned int avermxyz[3] = {0};
unsigned int buffer[6] = {0};
static float magGaussData[3] = {0.0};
static unsigned char cnt = 0;
buffer[0]=Rd_I2C(4,0x96,0x19);
buffer[1]=Rd_I2C(4,0x96,0x1A);
buffer[2]=Rd_I2C(4,0x96,0x1B);
buffer[3]=Rd_I2C(4,0x96,0x1C);
buffer[4]=Rd_I2C(4,0x96,0x1D);
buffer[5]=Rd_I2C(4,0x96,0x1E);
printf("Xl=%d,Xh=%d,Yl=%d,Yh=%d,Zl=%d,Zh=%d\r\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
mxyz[cnt][0] = (int16_t)(buffer[1] << 8 | buffer[0]);
mxyz[cnt][1] = (int16_t)(buffer[3] << 8 | buffer[2]);
mxyz[cnt][2] = (int16_t)(buffer[5] << 8 | buffer[4]);
usleep(1000 * 300);
}
return 0;
}
qmc5883
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <ctype.h>
#include <math.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <memory.h>
#include "main.h"
// unsigned int Linux_IICNum = 0;//使用海思的那个iic
int Rd_I2C(int Linux_IICNum, unsigned int chipAddr, unsigned int regAddr)
{
int retval = 0;
int fd = -1, tmp, i;
char file_name[0x10];
unsigned char buf[4];
unsigned int i2c_num, dev_addr, reg_addr, reg_addr_end;
unsigned int reg_width = 1, data_width = 1, reg_step = 1;
int cur_addr;
static struct i2c_rdwr_ioctl_data rdwr;
static struct i2c_msg msg[2];
unsigned int data;
memset(buf, 0x0, 4);
i2c_num = Linux_IICNum;
dev_addr = chipAddr;
reg_addr = regAddr;
reg_addr_end = regAddr;
dev_addr = dev_addr >> 1;
#ifdef DEBUG
printf("i2c_num:0x%x, dev_addr:0x%x; reg_addr:0x%x; reg_addr_end:0x%x; \
reg_width: %d; data_width: %d; reg_step: %d. \n\n",
i2c_num, dev_addr << 1, reg_addr, reg_addr_end,
reg_width, data_width, reg_step);
#endif // DEBUG
sprintf(file_name, "/dev/i2c-%u", i2c_num);
fd = open(file_name, O_RDWR);
if (fd < 0)
{
printf("Open %s error!\n", file_name);
retval = -1;
goto end0;
}
retval = ioctl(fd, I2C_SLAVE_FORCE, dev_addr);
if (retval < 0)
{
printf("CMD_SET_I2C_SLAVE error!\n");
retval = -1;
goto end1;
}
msg[0].addr = dev_addr;
msg[0].flags = 0;
msg[0].len = reg_width;
msg[0].buf = buf;
msg[1].addr = dev_addr;
msg[1].flags = 0;
msg[1].flags |= I2C_M_RD;
msg[1].len = data_width;
msg[1].buf = buf;
rdwr.msgs = &msg[0];
rdwr.nmsgs = (__u32)2;
for (cur_addr = reg_addr; cur_addr <= reg_addr_end; cur_addr += reg_step)
{
if (reg_width == 2)
{
buf[0] = (cur_addr >> 8) & 0xff;
buf[1] = cur_addr & 0xff;
}
else
buf[0] = cur_addr & 0xff;
retval = ioctl(fd, I2C_RDWR, &rdwr);
if (retval != 2)
{
printf("CMD_I2C_READ error!\n");
retval = -1;
goto end1;
}
if (data_width == 2)
{
data = buf[1] | (buf[0] << 8);
}
else
data = buf[0];
// printf("0x%x: 0x%x\n", cur_addr, data);
}
retval = data;
end1:
close(fd);
end0:
return retval;
}
int Wr_I2C(int Linux_IICNum, unsigned int chipAddr, unsigned int regAddr, unsigned int pData)
{
int retval = 0;
int fd = -1;
int index = 0, tmp, i;
char file_name[0x10];
unsigned char buf[4];
unsigned char i2c_num, dev_addr, reg_addr, data;
unsigned int reg_width = 1, data_width = 1;
i2c_num = Linux_IICNum;
dev_addr = chipAddr;
reg_addr = regAddr;
data = pData;
dev_addr = dev_addr >> 1;
#ifdef DEBUG
printf("i2c_num:0x%x, dev_addr:0x%x; reg_addr:0x%x; data:0x%x; reg_width: %d; data_width: %d.\n",
i2c_num, dev_addr << 1, reg_addr, data, reg_width, data_width);
#endif
sprintf(file_name, "/dev/i2c-%u", i2c_num);
fd = open(file_name, O_RDWR);
if (fd < 0)
{
printf("Open %s error!\n", file_name);
retval = -1;
goto end0;
}
retval = ioctl(fd, I2C_SLAVE_FORCE, dev_addr);
if (retval < 0)
{
printf("set i2c device address error!\n");
retval = -1;
goto end1;
}
if (reg_width == 2)
{
buf[index] = (reg_addr >> 8) & 0xff;
index++;
buf[index] = reg_addr & 0xff;
index++;
}
else
{
buf[index] = reg_addr & 0xff;
index++;
}
if (data_width == 2)
{
buf[index] = (data >> 8) & 0xff;
index++;
buf[index] = data & 0xff;
index++;
}
else
{
buf[index] = data & 0xff;
index++;
}
for (int i = 0; i < 2; i++)
{
retval = write(fd, buf, (reg_width + data_width));
if (retval < 0)
{
printf("i2c write error! i2c_num:0x%x, dev_addr:0x%x; reg_addr:0x%x; data:0x%x; reg_width: %d; data_width: %d.\n",
i2c_num, dev_addr << 1, reg_addr, data, reg_width, data_width);
retval = -1;
}
else
{
retval = 0;
break;
}
}
end1:
close(fd);
end0:
return retval;
}
int main(int argc, char *argv[])
{
Wr_I2C(3, 0x58, 0x0b, 0x00);
Wr_I2C(3, 0x58, 0x0a, 0xC3);
Wr_I2C(3, 0x58, 0x0d, 0x40);
while (1)
{
unsigned int mxyz[10][3] = {0};
unsigned int avermxyz[3] = {0};
unsigned int buffer[6] = {0};
static float magGaussData[3] = {0.0};
static unsigned char cnt = 0;
buffer[0]=Rd_I2C(3,0x58,0x01);
buffer[1]=Rd_I2C(3,0x58,0x02);
buffer[2]=Rd_I2C(3,0x58,0x03);
buffer[3]=Rd_I2C(3,0x58,0x04);
buffer[4]=Rd_I2C(3,0x58,0x05);
buffer[5]=Rd_I2C(3,0x58,0x06);
printf("Xl=%d,Xh=%d,Yl=%d,Yh=%d,Zl=%d,Zh=%d\r\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
mxyz[cnt][0] = (int16_t)(buffer[1] << 8 | buffer[0]);
mxyz[cnt][1] = (int16_t)(buffer[3] << 8 | buffer[2]);
mxyz[cnt][2] = (int16_t)(buffer[5] << 8 | buffer[4]);
cnt++;
if (cnt >= 10)
{
cnt = 0;
for (unsigned char i = 0, j = 0; i < 3; i++)
{
for (j = 0; j < 10; j++)
{
avermxyz[i] += mxyz[j][i];
}
avermxyz[i] = avermxyz[i] / 10;
}
printf("average original data :x=%d,y=%d,z=%d\r\n", avermxyz[0], avermxyz[1], avermxyz[2]);
// for (unsigned char k = 0; k < 3; k++)
// {
// magGaussData[k] = magGaussData[k] - 32768; // 32768:Null Field Output
// magGaussData[k] = avermxyz[k] / 3000; // 3000:sensitivity, 3000 counts/G
// }
// printf("convert the raw data :x=%f,y=%f,z=%f\r\n", magGaussData[0], magGaussData[1], magGaussData[2]);
// printf("\r\n");
}
usleep(1000 * 300);
}
return 0;
}