浅谈HMC5883L和QMC5883P磁力计的区别及STM32F103驱动

HMC5883L和QMC5883P芯片区别

在这里插入图片描述

HMC5883L和QMC5883P两款都是磁力计芯片,HMC5883L是Honeywell生产的芯片,QMC5883P是QST公司生产的替代芯片,两者在硬件封装上是兼容的,都是LGA-16 3.0x3.0x0.9mm封装,引脚上也都是兼容的,但是引脚功能上HMC5883L比QMC5883P多了一个DRDY引脚,可以用于中断控制,还有软件驱动上是不兼容的,寄存器地址以及IIC地址都是不相同的,不过底层驱动原理都是相同的。
在这里插入图片描述
以上是两个芯片的一些重要参数的区别,还有一个重要的区别是两者的磁场方向上是有区别的,如下图:
在这里插入图片描述
进行计算的时候需要注意区分下。

HMC5883L获取ID及三轴磁力计数据

HMC5883L手册链接:HMC5883L手册

寄存器说明

这里先看下HMC5883L的寄存器表格:
在这里插入图片描述
首先注意下10/11/12寄存器这里用10进制来写了,实际代码中读取的寄存器地址应该分别是0A,0B,0C的寄存器地址。
在这里插入图片描述

Configuration Register A(00H):位CRA7保留;CRA6-CRA5配置采样平均次数;CRA4-CRA2配置输出速率(配置的是连续测量模式下的输出速率(如下表1)。如果是在单次测量模式下,可以通过监测 DRDY 中断引脚可以实现最高 160 Hz的输出速率);CRA1-CRA0:测量配置(主要用于正常测量启用正/负偏置自检(self-test):00 = Normal、01 = Positive bias (自检+)、10 = Negative bias (自检−)、11 = 保留/未定义,具体说明可以看下表2)。
输出速率表格
在这里插入图片描述
Configuration Register B(01H):前三位GN通过设置增益确定量程范围,如下表,剩下的位并未使用,需要配置为0。(对于B寄存器的具体说明可以看资料对应的章节说明,这里就不赘述了)
在这里插入图片描述
Mode Register(01H):这个寄存器最高位MR7是设置为1可以配置成高速IIC模式,MR6到MR2未使用配置为0,MR1和MR0是用来配置模式,配置00时连续测量模式,01是单次测量模式,剩下两个都是休眠模式。如下表:
在这里插入图片描述03-08H:分别是三轴数据的寄存器了,都是12bits数据。
09H:状态寄存器,只读寄存器,用来读取数据锁存位和数据完成标志位。

名称功能说明
7–30保留,固定为 0
2LOCK数据锁存位。
当一个轴的数据输出寄存器被读出时,其他两个轴的数据会锁存,直到它们也被读出或发生新的测量更新。此位为 1 表示在读取过程中有新数据到来,旧数据被锁存;0 表示没有锁存。
1RDY数据准备完成标志。
当有新数据写入输出寄存器时置 1,表示三轴数据已更新,可以读取。
读取一次数据后会自动清零。
00保留

0A-0CH:分别是存储3个ID身份的ASCII码,分别对应:0A-H,0B-4,0C-3
以上就是所有寄存器的简单介绍了,下面开始初始化模块和读取数据。

获取HMC5883L ID和磁力计三轴数据

这里展示的是STM32F103C8T6单片机通过软件IIC初始化HMC5883L模块以及读取三个标识ID寄存器和磁力计三轴数据,直接读取寄存器的值,未作校准,自己有更精准的数据需求的话,需要自行开发算法哦。
HMC5883L驱动代码部分展示

/** * 函    数:HMC5883L初始化*/
void HMC5883L_Init(void)
{
	MyI2C_Init();									//先初始化底层的I2C
     /* 配置寄存器A:配置为 0x70 (8-average, 15Hz, normal) 
       8-average: MA = 11 (bits 5-6)
       15 Hz: DO = 100 (bits 2-0)
       Normal measurement: MS = 00 (bits 1-0 of config A for measurement mode)*/
    HMC5883L_WriteReg(HMC5883L_REG_CONFIG_A, 0x70);
    /*配置寄存器B: Gain = default (1.3 Ga) -> 0x20 (可按需修改) */
    HMC5883L_WriteReg(HMC5883L_REG_CONFIG_B, 0x20);
    /* 模式: continuous-measurement mode (0x00) */
    HMC5883L_WriteReg(HMC5883L_REG_MODE, 0x00);
}

/**
  * 函    数:HMC5883L获取ID号
  * 参    数:无
  * 返 回 值:HMC5883L的ID号
  */
void HMC5883L_GetID(uint8_t *A, uint8_t *B, uint8_t *C)
{
	*A = HMC5883L_ReadReg(HMC5883L_REG_IDA);		//返回IDA寄存器的值
    *B = HMC5883L_ReadReg(HMC5883L_REG_IDB);		//返回IDB寄存器的值
    *C = HMC5883L_ReadReg(HMC5883L_REG_IDC);		//返回IDC寄存器的值
}


/**
  * 函    数:HMC5883L获取数据
  * 参    数:磁力计X、Y、Z轴的数据,使用输出参数的形式返回
  * 返 回 值:无
  */
void HMC5883L_GetData(int16_t *X, int16_t *Y, int16_t *Z)
{
	uint8_t DataH, DataL;								//定义数据高8位和低8位的变量
	
	DataH = HMC5883L_ReadReg(HMC5883L_REG_XOUT_H);		//读取磁力计X轴的高8位数据
	DataL = HMC5883L_ReadReg(HMC5883L_REG_XOUT_L);		//读取磁力计X轴的低8位数据
	*X = (DataH << 8) | DataL;						    //数据拼接,通过输出参数返回
	
	DataH = HMC5883L_ReadReg(HMC5883L_REG_YOUT_H);		//读取磁力计Y轴的高8位数据
	DataL = HMC5883L_ReadReg(HMC5883L_REG_YOUT_L);		//读取磁力计Y轴的低8位数据
	*Y = (DataH << 8) | DataL;						    //数据拼接,通过输出参数返回
	
	DataH = HMC5883L_ReadReg(HMC5883L_REG_ZOUT_H);		//读取磁力计Z轴的高8位数据
	DataL = HMC5883L_ReadReg(HMC5883L_REG_ZOUT_L);		//读取磁力计Z轴的低8位数据
	*Z = (DataH << 8) | DataL;						    //数据拼接,通过输出参数返回	
}

HMC5883L主函数

uint8_t IDA, IDB, IDC;					//定义用于存放ID号的变量
int16_t X, Y, Z;			            //定义用于存放各个数据的变量

int main(void)
{
	/*模块初始化*/
	OLED_Init();		                //OLED初始化
	HMC5883L_Init();		            //HMC5883L初始化
	/*显示ID号*/
	OLED_ShowString(1, 1, "ID:");		
	HMC5883L_GetID(&IDA, &IDB, &IDC);	//获取HMC5883L的ID号
	OLED_ShowHexNum(1, 4, IDA, 2);		//OLED显示ID号(hex)
	OLED_ShowHexNum(1, 7, IDB, 2);		
    OLED_ShowHexNum(1, 10, IDC, 2);		
    
    OLED_ShowString(2, 1, "ID:");		
    OLED_ShowChar(2, 4, (char)IDA);		//OLED显示ID号(ASCII码)
	OLED_ShowChar(2, 5, (char)IDB);		
    OLED_ShowChar(2, 6, (char)IDC);		
    
    
	while (1)
	{
		HMC5883L_GetData(&X, &Y, &Z);	//获取HMC5883L的数据
		OLED_ShowSignedNum(3, 1, X, 5);	//OLED显示数据
		OLED_ShowSignedNum(3, 9, Y, 5);
		OLED_ShowSignedNum(4, 1, Z, 5);
	}
}

输出结果

OLED输出数据
在这里插入图片描述

QMC5883P获取ID及三轴磁力计数据

QMC5883P手册链接:QMC5883P手册

寄存器说明

在这里插入图片描述
参数上和HMC5883L是大同小异的,这里不细说明了,可以自行查看手册里的说明。主要区别是两个芯片数据存放的寄存器位置不同,驱动的时候改下寄存器地址即可,还有QMC5883P的三轴数据是16bits,以及ID寄存器这里只用了一个寄存器(00H)去存放,不像HMC5883L用了三个寄存器存放ID。下面直接上代码驱动。

获取QMC5883P ID和磁力计三轴数据

这里展示的是STM32F103C8T6单片机通过软件IIC初始化QMC5883P模块以及读取ID寄存器和磁力计三轴数据,直接读取寄存器的值,未作校准,自己有更精准的数据需求的话,需要自行开发算法哦。
QMC5883P驱动代码部分展示

/**
  * 函    数:QMC5883P初始化
  * 参    数:无
  * 返 回 值:无
  */
void QMC5883P_Init(void)
{
	MyI2C_Init();									//先初始化底层的I2C

    /* 初始化 QMC: 
       配置寄存器1:连续模式 + 200Hz
       位 [7:6]=OSR2, [5:4]=OSR1, [3:2]=ODR, [1:0]=MODE
       这里写 0x0F => OSR2=00(滤波器), OSR1=00(过采样率), ODR=11(200Hz), MODE=11(连续发送模式Continuous Mode) */
	QMC5883P_WriteReg(QMC5883P_REG_CONTROL1, 0xFF);
    /* 配置寄存器2:这里写的参数是不软复位,不自检,量程30Guass,不更新偏移量 */
    QMC5883P_WriteReg(QMC5883P_REG_CONTROL2, 0x01);
}

/**
  * 函    数:QMC5883P获取ID号
  * 参    数:无
  * 返 回 值:QMC5883P的ID号
  */
uint8_t QMC5883P_GetID(void)
{
	return QMC5883P_ReadReg(QMC5883P_REG_CHIPID);		//返回CHIPID寄存器的值
}

/**
  * 函    数:QMC5883P获取数据
  * 参    数:X Y Z 磁力计X、Y、Z轴的数据,使用输出参数的形式返回
  * 返 回 值:无
  */
void QMC5883P_GetData(int16_t *X, int16_t *Y, int16_t *Z)
{
	uint8_t DataH, DataL;							//定义数据高8位和低8位的变量
	
	DataH = QMC5883P_ReadReg(QMC5883P_REG_XOUT_H);		//读取磁力计X轴的高8位数据
	DataL = QMC5883P_ReadReg(QMC5883P_REG_XOUT_L);		//读取磁力计X轴的低8位数据
	*X = (DataH << 8) | DataL;						//数据拼接,通过输出参数返回
	
	DataH = QMC5883P_ReadReg(QMC5883P_REG_YOUT_H);		//读取磁力计Y轴的高8位数据
	DataL = QMC5883P_ReadReg(QMC5883P_REG_YOUT_L);		//读取磁力计Y轴的低8位数据
	*Y = (DataH << 8) | DataL;						//数据拼接,通过输出参数返回
	
	DataH = QMC5883P_ReadReg(QMC5883P_REG_ZOUT_H);		//读取磁力计Z轴的高8位数据
	DataL = QMC5883P_ReadReg(QMC5883P_REG_ZOUT_L);		//读取磁力计Z轴的低8位数据
	*Z = (DataH << 8) | DataL;						//数据拼接,通过输出参数返回	
}

QMC5883P主函数

uint8_t ID;								//定义用于存放ID号的变量
int16_t X, Y, Z;			            //定义用于存放各个数据的变量

int main(void)
{
	/*模块初始化*/
	OLED_Init();		                //OLED初始化
	QMC5883P_Init();		            //QMC5883P初始化
	
	/*显示ID号*/
	OLED_ShowString(1, 1, "ID:");		//显示静态字符串
	ID = QMC5883P_GetID();				//获取QMC5883P的ID号
	OLED_ShowHexNum(1, 4, ID, 2);		//OLED显示ID号
	
	while (1)
	{
		QMC5883P_GetData(&X, &Y, &Z);	//获取QMC5883P的数据
		OLED_ShowSignedNum(2, 1, X, 5);	//OLED显示数据
		OLED_ShowSignedNum(3, 1, Y, 5);
		OLED_ShowSignedNum(4, 1, Z, 5);
	}
}

输出结果

QMC5883P——OLED测试现象
在这里插入图片描述

总结

由于两个模块的底板是兼容的,所以拿到手的时候磁场方向只有HMC5883L的磁场方向是对的,QMC5883P的磁场方向对应手册里或者上面磁场方向图片看就行。
需要代码和对应资料的可以在评论区留言邮箱获取哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值