QMC5883L的驱动

简介

本篇文章的代码已经上传到了github上面,开源代码

作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。

参考资料

QMC5883L磁场传感器驱动

QMC5883L磁力计介绍(硬件+软件)(附STM32程序~~~)

移植

这个具体的文件在路径Core/Src/Hardware/Magnetic/QMC5883下面,里面也有对应的说明文件

更改底层通信

你需要更改下面的这些函数, 也就是常规的底层通信,替换成你的IIC驱动函数。这里我使用的是软件IIC,具体的文件在Core/Src/Conmunication/IIC_moni路径下,这个路径下面还有具体的说明和使用文件

cpp 复制代码
uint8_t QMC5883L_ReadOneReg(uint8_t RegAddr, uint8_t *pData){
uint8_t ret = 0;
#if QMC_HARD==1//硬件I2C

#else//软件I2C
ret = iic[QMC5883_IIC].ReadReg(QMC5883_IIC, (QMC5883L_CHIPID << 1 | 0), (RegAddr), pData, 1);
#endif
return ret;
}

uint8_t QMC5883L_ReadMultReg(uint8_t RegAddr, uint8_t RegNum, uint8_t DataBuff[]){
uint8_t ret = 0;
#if QMC_HARD==1//硬件I2C

#else//软件I2C
ret = iic[QMC5883_IIC].ReadReg(QMC5883_IIC, (QMC5883L_CHIPID << 1 | 0), RegAddr, DataBuff, RegNum);
#endif
return ret;
}

uint8_t QMC5883L_WriteOneReg(uint8_t RegAddr,uint8_t data){
uint8_t ret = 0;
#if QMC_HARD==1//硬件I2C

#else//软件I2C
ret = iic[QMC5883_IIC].WriteReg(QMC5883_IIC, (QMC5883L_CHIPID << 1 | 0), RegAddr, &data, 1);
#endif
return ret;
}

更改初始化函数

因为我是用的软件IIC 所以iic_attach需要重新指定引脚和下标QMC5883_IIC

cpp 复制代码
uint8_t QMC5883L_init(void){
#if QMC_HARD==1//硬件I2C

#else//软件I2C
    iic_attach(QMC5883_IIC,
               QMC5883L_I2C_SCL_Port,
               QMC5883L_I2C_SCL_Pin,
               QMC5883L_I2C_SDA_Port,
               QMC5883L_I2C_SDA_Pin,
               QMC_HARD);
#endif

    u8 tempreg;
    if(QMC5883L_ReadOneReg(QMC5883L_CHIPID, &tempreg) == FALSE){
        printf("QMC5883L初始化失败,读取芯片ID失败\r\n");
        return FALSE;
    }
    if(tempreg != QMC5883L_ID){
        printf("QMC5883L初始化失败,无效的ID:0x%X\r\n", tempreg);
        return FALSE;
    }
    printf("QMC5883L初始化成功,ID:0x%X\r\n", tempreg);

    QMC5883L_WriteOneReg(QMC5883L_CONTROL2_REG, 0X80);			//复位,要延时一定时间
    delay_ms(100);
    QMC5883L_WriteOneReg(QMC5883L_SET_RESET_PERIOD, 0X01);		//复位后必须写入0x01,否则温度为0,磁场数据也不对
    QMC5883L_SetMode(QMC5883L_MODE_CONTINUOUS, QMC5883L_ODR_50HZ, QMC5883L_RNG_2G, QMC5883L_OSR_64);//设置工作模式
    return 1;
}

同时你也可以替换QMC5883L_SetMode 的参数替换各种不同的控制模式,具体定义在qmc5883.h中, 而对于这些模式分别有什么作用,具体看芯片手册的最后几页,都有详细的说明,我也上传到了我的仓库当中

cpp 复制代码
//QMC5883L工作模式
typedef enum
{
    QMC5883L_MODE_STANDBY		=	0x00,	//待机模式
    QMC5883L_MODE_CONTINUOUS	=	0x01,	//连续工作模式
}QMC5883L_MODE;


//QMC5883L输出速率
typedef enum
{
    QMC5883L_ODR_10HZ			=	0x00,	//10Hz
    QMC5883L_ODR_50HZ			=	0x01,	//50Hz
    QMC5883L_ODR_100HZ			=	0x02,	//100Hz
    QMC5883L_ODR_200HZ			=	0x03,	//200Hz
}QMC5883L_ODR;

//QMC5883L测量范围
typedef enum
{
    QMC5883L_RNG_2G				=	0x00,	//2G
    QMC5883L_RNG_8G				=	0x01,	//8G
}QMC5883L_RNG;

//QMC5883L过采样
typedef enum
{
    QMC5883L_OSR_512			=	0x00,	//512
    QMC5883L_OSR_256			=	0x01,	//256
    QMC5883L_OSR_128			=	0x02,	//128
    QMC5883L_OSR_64				=	0x03,	//64
}QMC5883L_OSR;

使用

后续就不用太纠结了,可以直接使用我声明在qmc5883.c 文件下的一个结构体变量qmc5883

cpp 复制代码
QMC5883L_HANDLE qmc5883 = {
        0,
        0,
        0,
        QMC5883L_init,
        QMC5883_GetData,
        QMC5883L_GetTemper
};

在路劲Core/Src/Hardware/use.c 下有使用示例:

只需要三个函数 init(), getYaw(), getTemp()即可获取全部的参数

cpp 复制代码
// todo QMC5883
#include "Magnetic/QMC5883/qmc5883.h"
void use_qmc5883(void){
    qmc5883.init();
    for(;;){

        printf("qmc:%d, %d\r\n", qmc5883.getYaw(), qmc5883.getTemp());
        HAL_Delay(10);
    }
}

不过还有具体的计算函数,我并没有对原始的数据进行滤波,仅仅是根据原始数据求了一个反三角函数而已,但是即便如此采集的数据依然不错,数据范围为 0, 360,0和360度的边界会直接跳变int16_t QMC5883_GetData(void){

cpp 复制代码
int16_t QMC5883_GetData(void){
    int16_t X, Y,Z;
    QMC5883L_GetMagneticData(&X, &Y, &Z);
    qmc5883.yaw = (atan2(Y,X) * (180 / 3.14159265) + 180);
    return qmc5883.yaw;
}
相关推荐
国产化创客30 分钟前
创客开发入门(三)Arduino IDE 开发环境
ide·单片机·嵌入式硬件·课程设计·智能硬件
CedarQR31 分钟前
LubanCat-2 (RK3568) Debian 下让 H3C Magic USB 无线网卡(AIC8800)联网全记录
linux·网络·单片机·嵌入式硬件·debian·3568·h3c
sukalot4 小时前
windows 驱动实例分析系列: HidHide驱动分析-HidHideClient 篇(中)
windows·驱动开发
T1mzhou10 小时前
ARM64 Linux 6.10内核启动流程7-ioremap和readl writel
linux·服务器·c语言
芯片人00711 小时前
纯硬件一键开关机ASIC芯片,为什么比 MCU 方案更适合更可靠
人工智能·单片机·嵌入式硬件·物联网·芯片
染予12 小时前
Ka 阵面星历下发与执行逻辑说明
stm32·嵌入式硬件
芯片人00713 小时前
武汉广昇科技的GMUX1308A模拟开关芯片成功导入中国台湾上市企业联昌电子,助力汽车电子供应链自主可控
科技·嵌入式硬件·物联网·汽车·芯片
未来之窗软件服务15 小时前
计算机二级[英文]-C 字符串移动—东方仙盟
c语言·开发语言·仙盟创梦ide·东方仙盟
恒锐丰科技林技术员16 小时前
EG2181D 半桥栅极驱动芯片详解:高压 MOS/IGBT 驱动实用器件
经验分享·嵌入式硬件·硬件工程
国科安芯16 小时前
面向卫星测控应答机的抗辐射MCU信号采集与定时控制研究
单片机·嵌入式硬件·mcu·架构·卫星·商业航天·抗辐射