HMC5883L和QMC5883P磁力计的区别及简单验证代码
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–3 | 0 | 保留,固定为 0 |
2 | LOCK | 数据锁存位。 当一个轴的数据输出寄存器被读出时,其他两个轴的数据会锁存,直到它们也被读出或发生新的测量更新。此位为 1 表示在读取过程中有新数据到来,旧数据被锁存;0 表示没有锁存。 |
1 | RDY | 数据准备完成标志。 当有新数据写入输出寄存器时置 1,表示三轴数据已更新,可以读取。 读取一次数据后会自动清零。 |
0 | 0 | 保留 |
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的磁场方向对应手册里或者上面磁场方向图片看就行。
需要代码和对应资料的可以在评论区留言邮箱获取哦!