失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > HMC5883L 电子指南针

HMC5883L 电子指南针

时间:2021-01-12 05:40:49

相关推荐

HMC5883L  电子指南针

电子指南针也称为电子罗盘,是一种重要的导航工具,能实时提供移动物体的航向和姿态。随着半导体工艺的进步和手机操作系统的发展,集成了越来越多传感器的智能手机变得功能强大,很多手机上都实现了电子罗盘的功能。而基于电子罗盘的应用(如Android的Skymap)在各个软件平台上也流行起来。

霍尼韦尔 HMC5883L是一种表面贴装的高集成模块,并带有数字接口的弱磁传感器芯片,应用于低成本罗盘和磁场检测领域。HMC5883L 包括最先进的高分辨率HMC118X系列磁阻传感器,并附带霍尼韦尔专利的集成电路包括放大器、自动消磁驱动器、偏差校准、能使罗盘精度控制在1°~2°的12 位模数转换器.简易的I2C 系列总线接口。HMC5883L 是采用无铅表面封装技术,带有16 引脚,尺寸为3.0X3.0X0.9mm。HMC5883L 的所应用领域有手机、笔记本电脑、消费类电子、汽车导航系统和个人导航系统。

HMC5883L 采用霍尼韦尔各向异性磁阻(AMR)技术,该技术的优点是其他磁传感器技术所无法企及。这些各向异性传感器具有在轴向高灵敏度和线性高精度的特点.传感器带有的对于正交轴低敏感行的固相结构能用于测量地球磁场的方向和大小,其测量范围从毫高斯到 8 高斯(gauss)。 霍尼韦尔的磁传感器在低磁场传感器行业中是灵敏度最高和可靠性最好的传感器。

我们采用CC2540作为单片机,通过模拟I2C与HMC5883L通信,代码如下

#include<ioCC2540.h>#include <math.h> #include <stdio.h>#include "hmc5883l.h"#define uchar unsigned char#define uint unsigned int#defineSCL P1_0//IIC时钟引脚定义#defineSDA P1_1//IIC数据引脚定义#defineSlaveAddress 0x3C //定义器件在IIC总线中的从地址typedef unsigned char BYTE;typedef unsigned short WORD;void delay(unsigned int k);void Init_HMC5883(void); //初始化5883void WriteDataLCM(uchar dataW);void WriteCommandLCM(uchar CMD,uchar Attribc);void DisplayOneChar(uchar X,uchar Y,uchar DData);void conversion(uint temp_data);void Single_Write_HMC5883(uchar REG_Address,uchar REG_data); //单个写入数据uchar Single_Read_HMC5883(uchar REG_Address); //单个读取内部寄存器数据void Multiple_Read_HMC5883(); //连续的读取内部寄存器数据//以下是模拟iic使用函数-------------void Delay5us();void Delay5ms();void HMC5883_Start();void HMC5883_Stop();void HMC5883_SendACK(unsigned char ack);unsigned char HMC5883_RecvACK();void HMC5883_SendByte(BYTE dat);BYTE HMC5883_RecvByte();void HMC5883_ReadPage();void HMC5883_WritePage();//-----------------------------------/*******************************/void delay(unsigned int k){unsigned int i,j;for(i=0;i<k;i++){for(j=0;j<1210;j++){;}}}/**************************************延时5微秒(STC90C52RC@12M)不同的工作环境,需要调整此函数,注意时钟过快时需要修改当改用1T的MCU时,请调整此延时函数**************************************/void Delay5us(){unsigned char count_i;for(count_i=0; count_i<30; count_i++);}/**************************************延时5毫秒(STC90C52RC@12M)不同的工作环境,需要调整此函数当改用1T的MCU时,请调整此延时函数**************************************/void Delay5ms(){WORD n = 5600;while (n--);}/**************************************起始信号**************************************/void HMC5883_Start(){P1DIR |= 0x02; SDA = 1;//拉高数据线SCL = 1;//拉高时钟线Delay5us(); //延时SDA = 0;//产生下降沿Delay5us(); //延时SCL = 0;//拉低时钟线}/**************************************停止信号**************************************/void HMC5883_Stop(){P1DIR |= 0x02; SDA = 0;//拉低数据线SCL = 1;//拉高时钟线Delay5us(); //延时SDA = 1;//产生上升沿Delay5us(); //延时}/**************************************发送应答信号入口参数:ack (0:ACK 1:NAK)**************************************/void HMC5883_SendACK(unsigned char ack){P1DIR |= 0x02; SDA = ack; //写应答信号SCL = 1;//拉高时钟线Delay5us(); //延时SCL = 0;//拉低时钟线Delay5us(); //延时}/**************************************接收应答信号**************************************/unsigned char HMC5883_RecvACK(){P1DIR &= 0xfd; SCL = 1;//拉高时钟线Delay5us(); //延时CY = SDA; //读应答信号SCL = 0;//拉低时钟线Delay5us(); //延时return CY;}/**************************************向IIC总线发送一个字节数据**************************************/void HMC5883_SendByte(BYTE dat){BYTE i;P1DIR |= 0x02;for (i=0; i<8; i++) //8位计数器{dat <<= 1; //移出数据的最高位SDA = CY;//送数据口SCL = 1;//拉高时钟线Delay5us(); //延时SCL = 0;//拉低时钟线Delay5us(); //延时}HMC5883_RecvACK();}/**************************************从IIC总线接收一个字节数据**************************************/BYTE HMC5883_RecvByte(){BYTE i;BYTE dat = 0;P1DIR |= 0x02;SDA = 1;//使能内部上拉,准备读取数据,P1DIR &= 0xfd;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(unsigned char *pBuf){ uchar i;HMC5883_Start();//起始信号HMC5883_SendByte(SlaveAddress); //发送设备地址+写信号HMC5883_SendByte(0x03); //发送存储单元地址,从0x3开始HMC5883_Start();//起始信号HMC5883_SendByte(SlaveAddress+1); //发送设备地址+读信号for (i=0; i<6; i++) //连续读取6个地址数据,存储中BUF{*(pBuf+i) = HMC5883_RecvByte();//BUF[0]存储数据if (i == 5){HMC5883_SendACK(1);//最后一个数据需要回NOACK}else{HMC5883_SendACK(0);//回应ACK}}HMC5883_Stop();//停止信号Delay5ms();}//初始化HMC5883,根据需要请参考pdf进行修改****void Init_HMC5883(void){P1DIR |= 0x03; Single_Write_HMC5883(0x02,0x00); //}

下面是所采集的在坐标轴上的数据

所得到的数据为在各个坐标轴上的磁场强度,测试发现,计算出的磁场角度并不准确,这个淘宝上买的GY-273模块自身应该有少许的干扰,需要进行校准。

如果觉得《HMC5883L 电子指南针》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。