QMI8610 QMC5883调试记录

该博客介绍了如何通过特定的I2C接口操作qmi8610和qmc5883芯片,着重于它们的非标准复位机制,并展示了从传感器获取磁感强度数据的过程,包括数据读取、校准算法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个芯片复位跟一般芯片不一样,高电平复位,低电平有效。

下面代码接收显示,得到的应该是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;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值