【模块学习】关于磁力计HMC5883L型号探索

article/2025/10/13 16:49:59

关于磁力计HMC5883L型号探索

一.序言

         在众多磁力计中,HMC5883L因为其廉价实用而受到大多数嵌入式开发小白的追捧。然而某宝上不仅仅有HMC5883L这一款,还有QMC5883HMC5983,常有商家搞不清芯片就出售,导致提供的数据手册不对应。同时,不同单片机对IIC的操作也略有差异,对小白而言也是件头疼的事情。

HMC5883LQMC5883L区别对比

         可以看到,QMC5883L的各寄存器地址与HMC5883L区别还是不小。这样,移植时候程序整体结构不用大改,把寄存器改掉即可。

(1)      修改I2C address

0x3C -> 0x1A

0x3D -> 0x1B

(2)      X/Y/Z Register

起始:0x03 -> 0x00

顺序:X-Z-Y -> X-Y-Z

(3)      Mode Register

0x02 -> 0x09

0x00 -> 0x01

二.HMC5983

         HMC5983HMC5883L的“加强版”,寄存器与5883基本一致,但同时支持I2CSPI两种通信模式,更加快捷。因此,使用方法与5883几乎没有差别。这里,本人将官方提供的测试程序修改为STC15系列单片机,主要移植I2C通信中时序函数。

         本人增加了一个定任意方向为0度的功能,主要为了解决各类机器人竞赛中场地不一定何种角度朝向的问题。不过由于时间仓促没有来的及写滤波。思路就是将坐标系进行转换。贴出程序,仅供参考。

 

1.电路图

2.所需元件

STC15W408AS    x1

HMC5983        x1

1k电阻          x1

独立按键        x1

排针           若干

洞洞板          x1

3.程序结构

4.源码

(1)user_config.h

/*-----------------------------------------用户配置文件-------------------------------------------*/
#ifndef _CONFIG_H_
#define _CONFIG_H_/*  宏定义  */
#define   uchar unsigned char
#define   uint  unsigned int	typedef unsigned char BYTE;
typedef unsigned short WORD;/*  包含头文件  */
#include <STC15F2K60S2.H>
#include  <math.h>    //Keil library  
#include  <stdio.h>   //Keil library	
#include  <INTRINS.H>
//USER Library
#include "HMC5983_Driver.h"
#include "HMC5983_Software.h"
#include "uart.h"
#include "delay.h"
#include "interrupt.h"//#include "LQ12864.h"//使用的端口,请按照以下接线
sbit	SCL=P3^2;      //IIC时钟引脚定义
sbit	SDA=P3^3;      //IIC数据引脚定义
sbit  KEY=P3^6;      //按键
//sfr INT_CLKO = 0x8f;	//外部中断与时钟输出控制寄存器//全局变量引入
extern BYTE BUF[8];
extern uchar ge,shi,bai,qian,wan;           //显示变量
extern int  dis_data;                       //变量
extern double angle_ch;
#endif


(2)HMC5983_Driver.h

/*------------------------------------HMC5983驱动文件-------------------------------------*/
#ifndef _HMC5983_DRIVER_H_
#define _HMC5983_DRIVER_H_#define	SlaveAddress   0x3C	  	  //定义器件5883在IIC总线中的从地址//************
//函数
//************void Init_HMC5883(void);            //初始化5883void  Single_Write_HMC5883(uchar REG_Address,uchar REG_data);   //单个写入数据
//uchar Single_Read_HMC5883(uchar REG_Address);                   //单个读取内部寄存器数据
void  Multiple_Read_HMC5883(void);                                  //连续的读取内部寄存器数据
//以下是模拟iic使用函数-------------
void HMC5883_Start(void);
void HMC5883_Stop(void);
void HMC5883_SendACK(bit ack);
bit  HMC5883_RecvACK(void);
void HMC5883_SendByte(BYTE dat);
BYTE HMC5883_RecvByte(void);
void HMC5883_ReadPage(void);
void HMC5883_WritePage(void);#endif

(3)interrupt.h

/*--------------------------中断服务头文件---------------------------*/
#ifndef _IT_H_
#define _IT_H_#define Init_INT2() INT_CLKO |= 0x10#endif


(4)uart.c

/*-----------------------------------串口配置STC15F408AS内置晶振波特率 9600 bps------------------------------------*/#include "user_config.h"BYTE BUF[8];                         //接收数据缓存区   //*********************************************
//串口初始化
//9600 bps @ 11.059 MHz 
void init_uart(void)
{SCON  = 0x50;AUXR |= 0x04;T2L   = 0xa0;T2H   = 0xfc;AUXR |= 0x10;TI    = 1;EA    = 1;	
}//*********串口数据发送******************
void SeriPushSend(uchar send_data)
{SBUF = send_data;  while(!TI);TI=0;	  
}


(5)interrupt.c

/*-----------------------------中断服务-----------------------------*/
#include "user_config.h"double angle_ch = 0;void KEY_DOWN(void) interrupt 10
{Delay5ms();if(KEY == 0){while(!KEY);angle_ch = Angle_Update();}
}


(6)HMC5983_Driver.c

//***************************************
// HMC5883 51串口测试程序
// 使用单片机STC89C51 
// 晶振:11.0592M
// 显示:PC串口
// 编译环境 Keil uVision2
// 参考宏晶网站24c04通信程序
// 时间:2011年3月1日
//****************************************#include "user_config.h"
#include "HMC5983_Driver.h"int  dis_data;                       //变量//-----------------------------------/**************************************
起始信号
**************************************/
void HMC5883_Start(void)
{SDA = 1;                    //拉高数据线SCL = 1;                    //拉高时钟线Delay5us();                 //延时SDA = 0;                    //产生下降沿Delay5us();                 //延时SCL = 0;                    //拉低时钟线
}/**************************************
停止信号
**************************************/
void HMC5883_Stop(void)
{SDA = 0;                    //拉低数据线SCL = 1;                    //拉高时钟线Delay5us();                 //延时SDA = 1;                    //产生上升沿Delay5us();                 //延时
}/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void HMC5883_SendACK(bit ack)
{SDA = ack;                  //写应答信号SCL = 1;                    //拉高时钟线Delay5us();                 //延时SCL = 0;                    //拉低时钟线Delay5us();                 //延时
}/**************************************
接收应答信号
**************************************/
bit HMC5883_RecvACK(void)
{SCL = 1;                    //拉高时钟线Delay5us();                 //延时CY = SDA;                   //读应答信号SCL = 0;                    //拉低时钟线Delay5us();                 //延时return CY;
}/**************************************
向IIC总线发送一个字节数据
**************************************/
void HMC5883_SendByte(BYTE dat)
{BYTE i;for (i=0; i<8; i++)         //8位计数器{dat <<= 1;              //移出数据的最高位SDA = CY;               //送数据口SCL = 1;                //拉高时钟线Delay5us();             //延时SCL = 0;                //拉低时钟线Delay5us();             //延时}HMC5883_RecvACK();
}/**************************************
从IIC总线接收一个字节数据
**************************************/
BYTE HMC5883_RecvByte(void)
{BYTE i;BYTE dat = 0;SDA = 1;                    //使能内部上拉,准备读取数据,for (i=0; i<8; i++)         //8位计数器{dat <<= 1;SCL = 1;                //拉高时钟线Delay5us();             //延时dat |= SDA;             //读数据               SCL = 0;                //拉低时钟线Delay5us();             //延时}return dat;
}//***************************************************void Single_Write_HMC5883(uchar REG_Address,uchar REG_data)
{HMC5883_Start();                  //起始信号HMC5883_SendByte(SlaveAddress);   //发送设备地址+写信号HMC5883_SendByte(REG_Address);    //内部寄存器地址,请参考中文pdf HMC5883_SendByte(REG_data);       //内部寄存器数据,请参考中文pdfHMC5883_Stop();                   //发送停止信号
}/*
//********单字节读取内部寄存器*************************
uchar Single_Read_HMC5883(uchar REG_Address)
{uchar REG_data;HMC5883_Start();                          //起始信号HMC5883_SendByte(SlaveAddress);           //发送设备地址+写信号HMC5883_SendByte(REG_Address);                   //发送存储单元地址,从0开始	HMC5883_Start();                          //起始信号HMC5883_SendByte(SlaveAddress+1);         //发送设备地址+读信号REG_data=HMC5883_RecvByte();              //读出寄存器数据HMC5883_SendACK(1);   HMC5883_Stop();                           //停止信号return REG_data; 
}
*/
//******************************************************
//
//连续读出HMC5883内部角度数据,地址范围0x3~0x5
//
//******************************************************
void Multiple_read_HMC5883(void)
{   uchar i;HMC5883_Start();                          //起始信号HMC5883_SendByte(SlaveAddress);           //发送设备地址+写信号HMC5883_SendByte(0x03);                   //发送存储单元地址,从0x3开始	HMC5883_Start();                          //起始信号HMC5883_SendByte(SlaveAddress+1);         //发送设备地址+读信号for (i=0; i<7; i++)                      //连续读取6个地址数据,存储中BUF{BUF[i] = HMC5883_RecvByte();          //BUF[0]存储0x32地址中的数据if (i == 6){HMC5883_SendACK(1);                //最后一个数据需要回NOACK}else{HMC5883_SendACK(0);                //回应ACK}}HMC5883_Stop();                          //停止信号Delay5ms();
}//初始化HMC5883,根据需要请参考pdf进行修改****
void Init_HMC5883(void)
{Single_Write_HMC5883(0x02,0x00);  //Single_Write_HMC5883(0x01,0xE0);  //
}


(7)HMC5983_Software.c

/*---------------------------------HMC5983  角度变换将任意角度变为0度-----------------------------------*/
#include "user_config.h"uchar ge,shi,bai,qian,wan;           //显示变量double Angle_Update(void)
{int x,y,z,t;Multiple_Read_HMC5883();      //连续读出数据,存储在BUF中x = BUF[0] << 8 | BUF[1]; z = BUF[2] << 8 | BUF[3]; y = BUF[4] << 8 | BUF[5]; t = atan2((double)y,(double)x) * (180 / 3.14159265) + 180; // angle in degreeswhile(abs(t-45) <= 0.001){Multiple_Read_HMC5883();      //连续读出数据,存储在BUF中x = BUF[0] << 8 | BUF[1]; z = BUF[2] << 8 | BUF[3]; y = BUF[4] << 8 | BUF[5]; t = atan2((double)y,(double)x) * (180 / 3.14159265) + 180; // angle in degrees}return t;
}void conversion(uint temp_data)  
{  wan=temp_data/10000+0x30 ;temp_data=temp_data%10000;   //取余运算qian=temp_data/1000+0x30 ;temp_data=temp_data%1000;    //取余运算bai=temp_data/100+0x30   ;temp_data=temp_data%100;     //取余运算shi=temp_data/10+0x30    ;temp_data=temp_data%10;      //取余运算ge=temp_data+0x30; 	
}double Change_Target(void)
{double angle_now = Angle_Update();if(angle_now >= angle_ch) return angle_now-angle_ch;else return 360-angle_ch+angle_now;
}


(8)main.c

/*----------------------------------------------------------基于HMC5983智能电子罗盘2017/10/24		Listen C@ 型号:STC15F408AS@ 晶振:内置33.1776MHz@ 通信:IIC@ 显示:0.96 OLED@ 串口:9600 bps------------------------------------------------------------*/#include <STC15F2K60S2.H>
#include "user_config.h"//*********************************************************
//                  主程序
//*********************************************************void main(void)
{ // bit sign_bit;unsigned int i;double angle;delay(100);Init_INT2();init_uart();Init_HMC5883();while(1)            //循环{ angle = Change_Target();conversion(angle);       //计算数据和显示Delay5ms(); SeriPushSend(0x0d);SeriPushSend(0x0a);SeriPushSend(bai);SeriPushSend(shi);SeriPushSend(ge);}
} 


三.QMC5883LArduino上使用

         arduino中,I2C address用的是7位地址而不是8位,所以需要对应将address改掉。

比如QMC58830x1a,则二进制为0001_1010。而换算为7位,右移一位二进制为0000_1101

则十六进制为0x0d

源码如下:

#include <Wire.h>#define address 0x0d void setup() {//put your setup code here, to run once:Serial.begin(9600);delay(500);Wire.begin();Wire.beginTransmission(address);Wire.write(0x09);Wire.write(0x01);Wire.endTransmission();}void loop() {//put your main code here, to run repeatedly:intx,y,z;Wire.beginTransmission(address);Wire.write(0x00);Wire.endTransmission();Wire.requestFrom(address,6);if(Wire.available() >= 6){x= Wire.read() << 8;x |= Wire.read();y = Wire.read() << 8;y |= Wire.read();z= Wire.read() << 8;z |= Wire.read();}Serial.print("x: ");Serial.print(x);Serial.print("   y: ");Serial.print(y);Serial.print("   z: ");Serial.println(z);delay(250);}

网盘链接:http://pan.baidu.com/s/1gfEje8r 密码:dbvr


http://chatgpt.dhexx.cn/article/UkbPIc4I.shtml

相关文章

HMC5883Lnbsp;磁力计校准

原文地址&#xff1a;HMC5883L 磁力计校准 作者&#xff1a;WalkAnt 这里针对 HMC5883L 磁力计 的校准&#xff0c;做一个简单讲解。欢迎交流&#xff0c;新浪长沙WalkAnt。 先看看这篇文章&#xff1a;http://blog.sina.com.cn/s/blog_8240cbef0101i7gn.html 如果磁力计在含有…

【51单片机快速入门指南】4.4:I2C 读取HMC5883L / QMC5883L 磁力计

目录 硬知识简介操作模式HMC5883L连续测量模式单次测量模式闲置模式 QMC5883L连续测量模式待命模式 主要差异寄存器寄存器列表HMC5883LQMC5883L 配置寄存器HMC5883L配置寄存器 A配置寄存器 B模式寄存器 QMC5883L控制寄存器1控制寄存器2SET/RESET Period Register 数据输出寄存器…

ESP32设备驱动-HMC5883L磁场传感器驱动

HMC5883L磁场传感器驱动 1、HMC5883L介绍 霍尼韦尔 HMC5883L 是一款表面贴装、多芯片模块,专为低场磁场传感而设计,具有数字接口,适用于低成本罗盘和磁力计等应用。 HMC5883L 包括我们先进的高分辨率 HMC118X 系列磁阻传感器和一个 ASIC,该 ASIC 包含放大、自动消磁带驱动…

STM32读取HMC5883L的偏航角数据

HMC5883L是一种IIC通信的电子罗盘芯片&#xff0c;输出与北的角度偏差&#xff0c;数值是0-360度&#xff0c;靠西方向增长&#xff0c;可以理解为逆时针为正。配合GPS模块简直就是四轴飞行器的铁杆标配。 5883的初始化 HMC5883L也是一个IIC器件&#xff0c;具体的操作方式和…

HMC5883L 磁力计校准

原文地址&#xff1a; http://blog.sina.com.cn/s/blog_402c071e0102v8ie.html 这里针对 HMC5883L 磁力计 的校准&#xff0c;做一个简单讲解。欢迎交流&#xff0c;新浪长沙WalkAnt。 先看看这篇文章&#xff1a;http://blog.sina.com.cn/s/blog_8240cbef0101i7gn.html 如果磁…

使用Arduino和HMC5883L磁力计的数字罗盘

原文&#xff1a;https://circuitdigest.com/microcontroller-projects/digital-compass-with-arduino-and-hmc5883l-magnetometer 使用Arduino和HMC5883L磁力计的数字罗盘 ARDUINO的 经过**阿斯温斯拉吉(Aswinth Raj)** 2018年11月6日 人脑由复杂的结构层构成&#xff0c…

地磁计HMC5883L

信方式&#xff1a;IIC 工作电压&#xff1a;2.16~3.6V 工作电流&#xff1a;100uA 罗盘航向精度&#xff1a;1~2 当达到预定的最大输出频率&#xff0c;才需要监控DRDY中断引脚 I2C接口 装置包含一个7-bits串行地址&#xff0c;并且支持标注和快速模式&#xff08;100kHZ和400…

3轴数字罗盘IC HMC5883L介绍

3轴数字罗盘IC HMC5883L简介 霍尼韦尔 HMC5883L 是一种表面贴装的高集成模块&#xff0c;并带有数字接口的弱磁传感器芯片&#xff0c;应用于低成本罗盘和磁场检测领域。HMC5883L 包括最先进的高分辨率HMC118X 系列磁阻传感器&#xff0c;并附带霍尼韦尔专利的集成电路包括放大…

HMC5883L

霍尼韦尔 HMC5883L 是一种表面贴装的高集成模块&#xff0c;并带有数字接口的弱磁传感器芯片&#xff0c;应用于低成本罗盘和磁场检测领域。HMC5883L 包括最先进的高分辨率 HMC118X 系列磁阻传感器&#xff0c;并附带霍尼韦尔专利的集成电路包括放大器、自动消磁驱动器、偏差校…

STM32模拟I2C协议获取HMC5883L电子罗盘磁角度数据 (HAL)

STM32模拟I2C协议获取HMC5883L电子罗盘磁角度数据(HAL) HMC5883L 传感器采用霍尼韦尔各向异性磁阻(AMR)技术&#xff0c;应用于罗盘和三轴磁场角度检测领域&#xff0c;常用于水平物体转动的角度识别。HMC5883L 采用I2C总线接口&#xff0c;2.16~3.6V供电范围&#xff0c;带有…

[11]ESP32+三轴磁罗盘HMC5883L移植与调试

文章目录 一、开发笔记二、初始化与工作流程1. 设置测量模式2. 设置采样率&#xff08;默认15Hz&#xff09;3. 设置测量范围4. 校准5. 开始测量6. 自测试操作&#xff08;可选&#xff09; 三、寄存器表1. 00-配置寄存器A2. 01-配置寄存器B3. 02-模式寄存器4. 09-状态寄存器5.…

STM32 HAL I2C读取HMC5883L磁偏角的实践

STM32 HAL I2C读取HMC5883L磁偏角的实践 源由成果代码头文件 G85HAL.h子文件 G85HAL.C主程序调用配置I2C引脚参考链接 源由 用传统的方式编写I2C总线数据读取&#xff0c;程序代码细碎&#xff0c;不好维护&#xff0c;移植性不好。CUBE MX配置方便灵活&#xff0c;程序架构好…

(二十六)树莓派3B+ 获取HMC5883L的磁场数据

模块介绍 霍尼韦尔 HMC5883L 是一种表面贴装的高集成模块&#xff0c;并带有数字接口的弱磁传感器芯片&#xff0c;应用于低成本罗盘和磁场检测领域。HMC5883L 包括最先进的高分辨率 HMC118X 系列磁阻传感器&#xff0c;并附带霍尼韦尔专利的集成电路包括放大器、自动消磁驱动…

HMC5883L校准

HMC5883L 磁力计校准 (2015-02-14 11:48:21) 转载▼ 标签&#xff1a; hmc5883 磁力计 校准 分类&#xff1a; 电子技术 这里针对 HMC5883L 磁力计 的校准&#xff0c;做一个简单讲解。欢迎交流&#xff0c;新浪长沙WalkAnt。 先看看这篇文章&#xff1a;http://blo…

STC 51单片机53——电子指南针HMC5883l

#include <REG51.H> #include <math.h> //Keil library #include <stdio.h> //Keil library #include <INTRINS.H> #define uchar unsigned char #define uint unsigned int //使用的端口&#xff0c;请按照以下接线 sbit …

HMC5883l磁力计数据读取

1.数据手册地址 2.芯片介绍 设备的7位地址为0x1e&#xff0c;读地址为0x3d&#xff0c;写地址为0x3c。如图 2.主要需要配置的寄存器有3个。分别是配置寄存器A&#xff08;0x00&#xff09;&#xff0c;配置寄存器B&#xff08;0x01&#xff09;和模式寄存器&#xff08;0x03&…

ESP8266-Arduino编程实例-HMC5883L磁场传感器

HMC5883L磁场传感器 1、HMC5883L介绍 霍尼韦尔 HMC5883L 是一款表面贴装、多芯片模块,专为低场磁场传感而设计,具有数字接口,适用于低成本罗盘和磁力计等应用。 HMC5883L 包括我们先进的高分辨率 HMC118X 系列磁阻传感器和一个 ASIC,该 ASIC 包含放大、自动消磁带驱动器、…

HMC5883L电子罗盘原理及应用,全网最详细~

寄存器配置部分 HMC5883L模块具有两个配置寄存器&#xff0c;配置寄存器A用来配置该装置设置的数据输出速率和测量配置&#xff1b;配置寄存器 B 设置装置的增益。 模式寄存器则是用来设定装置的操作模式&#xff0c;有连续测量模式&#xff0c;单一测量模式和闲置模式等。具…

HMC5883L磁力计使用

一、器件简介 HMC5883L是一款三轴磁场传感器&#xff0c;电子指南针罗盘模块。采用IIC通讯协议。 二、工作原理 传统罗盘用一根被磁化的磁针来感应地球磁场&#xff0c;地球磁场与磁针之间的磁力时磁针转动&#xff0c;直至磁针的两端分别指向地球的磁南极与磁北极。电子罗盘也…

HMC5883L电子罗盘/指南针实现,附带校准方法(附STM32 源码)

HMC5883L电子罗盘/指南针实现&#xff0c;附带校准方法&#xff08;附STM32 源码&#xff09; 前言一、寄存器详解1.配置寄存器A2.配置寄存器B3.模式寄存器4.数据寄存器5.状态寄存器6.识别寄存器 二、使用步骤1.STM32CubeMX设置2.初始化3.读取原始数据 三、校准程序四、方位角计…