使用HMC5883L-3轴数字罗盘传感器计算航向角
- 格式:docx
- 大小:199.10 KB
- 文档页数:3
电子罗盘调研2014-02-211 电子罗盘功能介绍1.1 名字解释电子罗盘,也叫数字指南针,是利用地磁场来定北极的一种方法。
古代称为罗经,现代利用先进加工工艺生产的磁阻传感器为罗盘的数字化提供了有力的帮助。
现在一般有用磁阻传感器和磁通门加工而成的电子罗盘。
电子罗盘具有以下特点:●三轴磁阻效应传感器测量平面地磁场,双轴倾角补偿。
●高速高精度A/D转换。
●内置温度补偿,最大限度减少倾斜角和指向角的温度漂移。
●内置微处理器计算传感器与磁北夹角。
●具有简单有效的用户标校指令。
●具有指向零点修正功能。
1.2 电子罗盘作用1.2.1 GPS导航定位的缺陷1) 虽然GPS在导航、定位、测速、定向方面有着广泛的应用,但由于其信号常被地形、地物遮挡,导致精度大大降低, 其信号可用性仅为60% ,甚至不能使用。
产生不精确定位的原因包括:①多路径效应:建筑物对GPS信号的反射②阴影:城市中高楼与高楼之间形成的“峡谷”内、浓密的植被下,信号接收效果较差③在隧道、地下停车厂造成的信号失锁④在接收信号差的地区延长了初始化时间⑤一些动态影响,如汽车大幅度增速与减速等。
以上原因都会导致GPS无法提供任何位置或者定位精度陡然下降。
2) 在静止的情况下,GPS也无法给出航向信息。
高精度电子罗盘可以对GPS信号进行有效补偿,保证导航定向信息100%有效,即使是在GPS信号失锁后也能正常工作,做到“丢星不丢向”。
3) 安全及可靠性风险。
美国出于自身利益上的考虑,从不承诺不实施SA干扰和区域关闭,这更给GPS用户带来很大疑惑和担心。
因此,将GPS与电子罗盘相结合,二者相互补充,组合使用是导航领域的理想选择。
例如:美国虽然其完全独立掌握GPS 的卫星资源,但为了使系统更加可靠,使导航信息100%有效,其M1坦克及其它一些重要装备上仍加装了C100电子罗盘。
1.2.2 电子罗盘主要用途电子罗盘主要用于辅助GPS导航及在静止状态获取航向,具体包括加速度和方向的定位、倾角测量等功能。
内容MID中的传感器1加速计2陀螺仪3地磁传感器4MID中的传感器——已商用的传感器◆触摸屏◆摄像头◆麦克风(ST:MEMS microphones……)◆光线传感器◆温度传感器◆近距离传感器◆压力传感器(ALPS:MEMS气压传感器……)◆陀螺仪(MEMS)◆加速度传感器(MEMS)◆地磁传感器(MEMS)集成电路(Integrated Circuit,IC)把电子元件/电路/电路系统集成到硅片(或其它半导体材料)上。
微机械(Micro-Mechanics)把机械元件/机械结构集成到硅片(或其它半导体材料)上。
微机电系统(Micro Electro Mechanical Systems,MEMS)MEMS = 集成电路+ 微机械陀螺仪(Gyroscope)•测量角速度•可用于相机防抖、视频游戏动作感应、汽车电子稳定控制系统(防滑)加速度传感器(Accelerometer)•测量线加速度•可用于运动检测、振动检测、撞击检测、倾斜和倾角检测地磁传感器(Geomagnetic sensor)•测量磁场强度•可用于电子罗盘、GPS导航陀螺仪+加速计+地磁传感器•电子稳像(EIS: Electronic Image Stabilization)•光学稳像(OIS: Optical Image Stabilization)•“零触控”手势用户接口•行人导航器•运动感测游戏•现实增强1、陀螺仪(角速度传感器)厂商:欧美:ADI、ST、VTI、Invensense、sensordynamics、sensonor日本:EPSON、Panasonic、MuRata、konix 、Fujitsu、konix、SSS国产:深迪2、加速度传感器(G-sensor)厂商:欧美:ADI、Freescale、ST、VTI、Invensense、Sensordynamics、Silicon Designs 日本:konix、Bosch、MSI、Panasonic、北陆电气国产:MEMSIC(总部在美国)3、地磁传感器(电子罗盘)厂商:欧美:ADI、Honeywell日本:aichi、alps、AsahiKASEI、Yamaha国产:MEMSIC(总部在美国)MID中的传感器——IPhone4陀螺仪:ST,L3G4200D加速计:ST,LIS331DLH地磁传感器:AsahiKASEI,AK8975内容MID中的传感器1陀螺仪2加速计3地磁传感器4地磁传感器——背景知识地球的磁场象一个条形磁体一样由磁南极指向磁北极。
hmc5883l工作原理HMC5883L是一种三轴磁力计,它能够测量地球磁场的强度和方向。
它采用了霍尔效应传感器来测量磁场,并且具有高精度和低功耗的特点。
在本文中,我们将详细介绍HMC5883L的工作原理。
一、霍尔效应传感器霍尔效应是指当电流通过一个导体时,如果该导体处于一个磁场中,那么该导体两侧会产生一定的电势差。
这种现象被称为霍尔效应。
基于霍尔效应原理的传感器被称为霍尔传感器。
HMC5883L采用了三个霍尔效应传感器来测量磁场,这三个传感器分别安装在不同的轴上(X、Y、Z轴),可以同时测量三个方向上的磁场强度。
二、I2C通信协议HMC5883L使用I2C通信协议与主控板进行通信。
I2C是一种串行通信协议,它只需要两根线(SDA和SCL)即可实现双向数据传输。
其中SDA线用于数据传输,SCL线用于时钟同步。
在I2C通信中,主控板负责产生时钟信号,从而控制数据传输的速率和时序。
HMC5883L作为从设备,接收主控板的指令,并返回相应的数据。
三、HMC5883L的寄存器HMC5883L内部有多个寄存器,用于存储配置信息和测量结果。
下面是一些重要的寄存器:1. Configuration Register A(0x00):用于配置测量模式、采样速率和增益。
2. Configuration Register B(0x01):用于配置磁场测量范围。
3. Mode Register(0x02):用于选择单次测量模式或连续测量模式。
4. Data Output X MSB Register(0x03):用于存储X轴磁场强度的高8位数据。
5. Data Output X LSB Register(0x04):用于存储X轴磁场强度的低8位数据。
6. Data Output Z MSB Register(0x05):用于存储Z轴磁场强度的高8位数据。
7. Data Output Z LSB Register(0x06):用于存储Z轴磁场强度的低8位数据。
三轴加速度计算欧拉角
三轴加速度计通常采用电容式感应方式来测量加速度。
它包含一个或多个微电子机械系统(MEMS)加速度传感器,传感器内部有一个质量可以在受力时移动的结构。
当物体受到外力作用时,传感器内部的质量结构会发生位移,由位移量可以计算得到物体的加速度。
为了得到物体的欧拉角,首先需要根据三轴加速度计的数据计算出物体的加速度值,然后再根据加速度值计算出物体的姿态角度。
具体的计算过程如下:
1.将三轴加速度计的数据转化为加速度的物理量。
三轴加速度计通常输出的是模拟电压值或数字数值,需要经过转换才能得到物体的加速度。
转换过程通常涉及到校准、放大或数字信号处理等步骤。
2. 根据加速度数据计算物体的倾斜角度。
三轴加速度计的数据包含了物体在X、Y、Z轴方向上的加速度值,可以通过计算向量和力的夹角来得到物体的倾斜角度。
根据三角函数的关系,有sinθ = Ax / g,cosθ = Ay / g,其中Ax和Ay是物体在X和Y轴方向上的加速度值,g是重力加速度。
通过计算反余弦函数可以得到物体的倾斜角度。
3. 根据倾斜角度计算物体的偏航角。
倾斜角度只能得到物体的俯仰(pitch)和横滚(roll)角度,要得到物体的偏航(yaw)角度还需要考虑物体的自旋(rotation)。
可以通过结合磁力计等其他传感器的数据来计算物体的偏航角度。
综上所述,三轴加速度计可以通过测量物体在三个方向上的加速度来计算物体的姿态角度。
计算欧拉角的过程主要包括将加速度数据转化为加速度的物理量、计算物体的倾斜角度和偏航角度。
电子技术• Electronic Technology110 •电子技术与软件工程 Electronic Technology & Software Engineering【关键词】三轴陀螺仪 飞行器 自动飞行四轴飞行器属于直升机范畴,拥有4个对称旋翼。
传感器技术逐步完善,特别微电子及微机械技术不断优化,最终使四轴飞行器达到自主飞行控制的效果。
四轴飞行器飞行性能可靠可多角度角度灵活移动,为消除外力影响,前方马达转速较快,进而确保水平,相同的是,其余几个方向受外力作用时,四轴也能借助此种动作来维持水平。
如果需对四轴向前飞实施控制,前方马达速度变得越来越慢,后方马达则则相反,如此四轴倾向前方,同样会向前方飞行。
其余飞姿态也能达到相同的效果。
1 总体设计思路主控芯片利用12C 总线对MPU6050的数据和HMC5883L 的数据实施读取,在互补滤波融合算法协助下实施解算,最终将载体的横滚角、俯仰角、偏航角给求解出来。
科学定义通信格式,在串行接口协助下,将协议数据单元的数据帧形式发送到姿态控制单元。
传感器的量程及更新速率组成了传感器的初始化。
滤波相关矩阵的初始化,以传感器特征为依据,构建四维对角方阵,过程激励噪声协方差矩阵、对角元素分别表示为Q 、0.1。
如果顺利读取陀螺仪数据,使滤波时间处在更新当中。
整理加速度传感器及磁阻传感器的数据,如果能够顺利读取,那么便能观测更新。
磁场观测更新算法、加速度观测更新的不同之处在于观测方差的尺,结合上述传感器的置信度来设立匹配的数值。
2 MPU6050软件的设计首先,初始化配置MPU6050。
全球首例整合性6轴运动处理组件MPU6050陀螺仪数据的得到:集成电路芯片单片机在两根线来通讯,的12C 串口配合下,发送器件地址,记下需要发送信号,接着获得所需读取的中央处理器内中寄存器地址,先找到发送器件地址,令集成电路芯片单片机读信号,应答,以依照地址顺序为参照,按照从低至高进行读取。
hmc5883l工作原理(一)HMC5883L工作原理概述HMC5883L是一款采用磁电阻原理测量磁场的数字式三轴磁力计,可测量X、Y、Z轴的磁场强度。
它广泛应用于电子罗盘、导航、定位等领域。
磁电阻原理磁电阻效应是指材料在磁场中具有电阻率的变化现象,其本质是材料内部磁矩的定向受到外部磁场的影响。
当外部磁场方向与材料内部磁矩方向相同时,电阻率最小,反之则最大。
利用磁电阻效应可以实现磁场测量。
HMC5883L结构HMC5883L内部由磁电阻元件、前置放大器、AD转换器、数字信号处理器等组成。
其结构示意图如下:•磁电阻元件:负责测量外部磁场的大小和方向;•前置放大器:将测量结果进行放大;•AD转换器:将模拟信号转换为数字信号;•数字信号处理器:处理并输出数字信号。
工作原理HMC5883L三个轴的磁场强度受物体周围磁场的影响,导致其磁电阻元件产生电阻值变化。
该变化信号通过前置放大器,被转换成模拟电压信号,并被送入AD转换器转换成数字信号。
数字信号处理器将这些数字信号处理后,输出计算得出的三轴磁场数据。
结束语本文简单介绍了HMC5883L的工作原理,以及使用磁电阻原理测量磁场的基本原理。
HMC5883L在实际应用中,可以根据需要对不同轴的磁场进行测量和调整,是一款功能强大的磁力计。
使用注意事项使用HMC5883L时,需要注意以下事项:•HMC5883L对磁场干扰较为敏感,应注意周围环境中的磁场干扰;•HMC5883L在工作时,应注意温度和外部电磁干扰对其测量结果的影响;•HMC5883L输出的磁场数据需要校准,以提高其精度和准确性。
总结HMC5883L是一款广泛使用的数字式三轴磁力计,采用磁电阻原理测量磁场,可应用于电子罗盘、导航和定位等领域。
了解HMC5883L的工作原理和注意事项,有助于更好地应用和使用该设备。
基于MSP430F149的电子罗盘设计陈学锋;张会永【摘要】文章提出了以三轴磁阻传感器HMC5883L和三轴加速度传感器ADXL345负责采集信号,16位超低功耗微控制器MSP430F149负责处理传感器采集的信号,进行相应的补偿然后输出显示航向的电子罗盘.【期刊名称】《科技创业月刊》【年(卷),期】2016(029)012【总页数】2页(P135-136)【关键词】HMC5883L;ADXL345;MSP430F149;电子罗盘【作者】陈学锋;张会永【作者单位】河南工学院河南新乡 453000;唐河中等职业学校河南南阳473400【正文语种】中文【中图分类】TP368.1电子罗盘是通过测量地球磁场水平方向分量进而推算出地磁北极方向从而得到电子罗盘载体前进方向的一种工具。
其中电子罗盘所在平面上与轴向方向(X方向)垂直的方向(Y方向)和电子罗盘在水平面上的投影的夹角称为翻滚角θ,电子罗盘的轴向方向(X方向)和它在水平面上的投影的夹角叫做俯仰角φ(见图1)。
测量电子罗盘的翻滚角和俯仰角能够经过三轴加速度传感器分别求出三个轴向上的重力加速度分量gX、gY、gZ进而计算出翻滚角和俯仰角。
翻滚角和俯仰角计算公式见式(1)、(2)。
已知电子罗盘的翻滚角θ和俯仰角φ,根据三轴磁阻传感器测得三个轴向上的地球磁场强度分量HX、HY、HZ,其中HX、HY两个分量在水平坐标系水平面上的投影分别为H*X、H*Y,水平磁场强度分量H*X、H*Y的计算公式见式(3)、(4)。
根据求出的水平磁场强度分量H*X、H*Y,可以计算出电子罗盘载体的地磁航向角。
地磁航向角指的是电子罗盘纵轴方向在水平面上的投影与地磁北极间的夹角,地磁航向角α计算公式见式(5)。
考虑到反正切函数的值域以及地磁航向角的范围,地磁航向角α在不同象限的取值分别为:当H*X<0时,α=180°-arctan当H*X>0,时,α=arctan当H*X>0,H*Y>0时,α=360°-arctan当H*X=0,H*Y>0,时,α=270°当H*X=0,H*Y<0,时,α=90°由于地磁北极和地理北极并不重合,他们之间有一个夹角,该夹角叫做磁偏角Y。
三轴加速度计算角度
三轴加速度计可以用来计算姿态角,其中包括俯仰角、横滚角、偏航角。
以下是计算三轴加速度计角度的步骤:
1. 计算合加速度
首先,我们需要计算出三个轴向上的加速度分量,也就是垂直于地面方向的运动加速度,这里假设三轴分别为x, y, z轴,则加速度计测得的合加速度计算公式为:
a = sqrt(ax^2 + ay^2 + az^2)
2. 计算俯仰角和横滚角
俯仰角(Pitch)和横滚角(Roll)是以重力方向为基础的,俯仰角表示相对于水平面的旋转角度,横滚角表示绕飞行器前后轴的旋转角度。
俯仰角的计算公式为:
Pitch = atan2(-ax, sqrt(ay^2 + az^2))
横滚角的计算公式为:
Roll = atan2(ay, az)
3. 计算偏航角
偏航角(Yaw)表示相对于地磁北极方向的旋转角度。
由于三轴加速度计不能直接测量偏航角,所以需要结合其他传感器数据一起计算。
在使用组合导航系统时,通常需要将陀螺仪和磁力计数据结合起来计算偏航角。
通过陀螺仪可以得到飞行器的旋转速度,而磁力
计可以提供地磁场数据。
由于地磁场是满足规律性分布的,因此可以根据地磁场数据计算出飞行器当前所在方位,从而计算出偏航角。
以上是计算三轴加速度计角度的基本步骤,需要结合其他传感器数据以实现更精确的测量。
同时,也需要注意处理好数据的误差和噪声,以保证计算结果的准确性。
数字电子指南针的设计摘要:指南针是一种重要的导航工具,可运用在多种场合。
早起指南针采用磁化指针和方向盘相结合的方式,整个指南针从灵敏度,便携性上都有一定的不足。
电子指南针内部结构固定,没有移动部分,可以简单的和其他电子系统接口,因此可以代替旧的磁指南针。
以精度高,稳定性好而得到广泛的运用。
本文将详细介绍磁阻(MR)传感器HMC5883L的工作原理,以此为基础利用该芯片采集磁场数据,通过高速微控制器(MCU)完成数据的加工处理,最后以液晶显示器12864完成方位显示功能。
关键字:电子指南针;MR;HMC5883L;MCU(MSP430F149)Abstract: The compass is a kind of important navigation tool,which can be used in many occasions. The early compass magnetized pointer and the steering wheel combination way , the entire compass from sensitivity ,portability has certain insufficiency. Electronic compass internal structure is fixed , no moving parts ,can be simple and other electronic system interface ,so it can replace the old magnetic compass .with high precision ,good stability and wide use .This paper introduces the magneto-resistive (MR) sensor working principle HMC5883L , with this as a foundation with the chip collecting field data ,via a high speed microprocessor control unit (MCU) data processing finally to 12864 LCD complete azimuth display function .Keyword:electronic compass; MR; HMC5883L ; MCU1 引言1.1 课题背景指南针的发明是我国汉族人民在长期的实践中对物体认识的结果。
1.原理图2.程序[1] 头文件1/****************************************Copyright (c)************************************************** **** ****--------------File Info-------------------------------------------------------------------------------** File name: 24C02.h** Descriptions: 24C02 操作函数库****------------------------------------------------------------------------------------------------------** Created by: A VRman** Created date: 2010-10-29** V ersion: 1.0** Descriptions: The original version****------------------------------------------------------------------------------------------------------** Modified by:** Modified date:** V ersion:** Descriptions:********************************************************************************************************/ #ifndef __HMC5883L_H#define __HMC5883L_H/* Includes ------------------------------------------------------------------*/#include "stm32f10x_lib.h"#include "GrobalV ariable.h"/* Private define ------------------------------------------------------------*/#define A T24C01A /* 24C01A,I2C时序和往后的24C02一样*///#define A T24C01 /* 24C01,I2C的时序和普通的有点不同*/#define ADDR_24LC02 0xA0#define I2C_P AGESIZE 4 /* 24C01/01A页缓冲是4个*//* Private function prototypes -----------------------------------------------*/void I2C_Configuration(void);u8 I2C_Read(I2C_TypeDef *I2Cx,u8 I2C_Addr,u8 addr,u8 *buf,u16 num);u8 I2C_Write(I2C_TypeDef *I2Cx,u8 I2C_Addr,u8 addr,u8 *buf,u16 num);///void HMC5883L_test(void);void Axia3AngInit(void) ;void Detect3AxiaAng(void);#endif/********************************************************************************************************* END FILE*********************************************************************************************************/ [2] 头文件2/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************* File Name : stm32f10x_i2c.h* Author : MCD Application T eam* V ersion : V2.0.1* Date : 06/13/2008* Description : This file contains all the functions prototypes for the* I2C firmware library.********************************************************************************* THE PRESENT FIRMW ARE WHICH IS FOR GUIDANCE ONL Y AIMS A T PROVIDING CUSTOMERS* WITH CODING INFORMA TION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SA VE TIME.* AS A RESUL T, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE* CONTENT OF SUCH FIRMW ARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING* INFORMA TION CONT AINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.*******************************************************************************//* Define to prevent recursive inclusion -------------------------------------*/#ifndef __STM32F10x_I2C_H#define __STM32F10x_I2C_H/* Includes ------------------------------------------------------------------*/#include "stm32f10x_map.h"/* Exported types ------------------------------------------------------------*//* I2C Init structure definition */typedef struct{u16 I2C_Mode;u16 I2C_DutyCycle;u16 I2C_OwnAddress1;u16 I2C_Ack;u16 I2C_AcknowledgedAddress;u32 I2C_ClockSpeed;}I2C_InitTypeDef;/* Exported constants --------------------------------------------------------*/#define IS_I2C_ALL_PERIPH(PERIPH) (((*(u32*)&(PERIPH)) == I2C1_BASE) || \((*(u32*)&(PERIPH)) == I2C2_BASE))/* I2C modes */#define I2C_Mode_I2C ((u16)0x0000)#define I2C_Mode_SMBusDevice ((u16)0x0002)#define I2C_Mode_SMBusHost ((u16)0x000A)#define IS_I2C_MODE(MODE) (((MODE) == I2C_Mode_I2C) || \((MODE) == I2C_Mode_SMBusDevice) || \((MODE) == I2C_Mode_SMBusHost))/* I2C duty cycle in fast mode */#define I2C_DutyCycle_16_9 ((u16)0x4000)#define I2C_DutyCycle_2 ((u16)0xBFFF)#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DutyCycle_16_9) || \((CYCLE) == I2C_DutyCycle_2))/* I2C cknowledgementy */#define I2C_Ack_Enable ((u16)0x0400)#define I2C_Ack_Disable ((u16)0x0000)#define IS_I2C_ACK_ST A TE(ST A TE) (((ST A TE) == I2C_Ack_Enable) || \((ST A TE) == I2C_Ack_Disable))/* I2C transfer direction */#define I2C_Direction_Transmitter ((u8)0x00)#define I2C_Direction_Receiver ((u8)0x01)#define IS_I2C_DIRECTION(DIRECTION) (((DIRECTION) == I2C_Direction_Transmitter) || \((DIRECTION) == I2C_Direction_Receiver))/* I2C acknowledged address defines */#define I2C_AcknowledgedAddress_7bit ((u16)0x4000)#define I2C_AcknowledgedAddress_10bit ((u16)0xC000)#define IS_I2C_ACKNOWLEDGE_ADDRESS(ADDRESS) (((ADDRESS) == I2C_AcknowledgedAddress_7bit) || \((ADDRESS) == I2C_AcknowledgedAddress_10bit))/* I2C registers */#define I2C_Register_CR1 ((u8)0x00)#define I2C_Register_CR2 ((u8)0x04)#define I2C_Register_OAR1 ((u8)0x08)#define I2C_Register_OAR2 ((u8)0x0C)#define I2C_Register_DR ((u8)0x10)#define I2C_Register_SR1 ((u8)0x14)#define I2C_Register_SR2 ((u8)0x18)#define I2C_Register_CCR ((u8)0x1C)#define I2C_Register_TRISE ((u8)0x20)#define IS_I2C_REGISTER(REGISTER) (((REGISTER) == I2C_Register_CR1) || \((REGISTER) == I2C_Register_CR2) || \((REGISTER) == I2C_Register_OAR1) || \((REGISTER) == I2C_Register_OAR2) || \((REGISTER) == I2C_Register_DR) || \((REGISTER) == I2C_Register_SR1) || \((REGISTER) == I2C_Register_SR2) || \((REGISTER) == I2C_Register_CCR) || \((REGISTER) == I2C_Register_TRISE))/* I2C SMBus alert pin level */#define I2C_SMBusAlert_Low ((u16)0x2000)#define I2C_SMBusAlert_High ((u16)0xDFFF)#define IS_I2C_SMBUS_ALERT(ALERT) (((ALERT) == I2C_SMBusAlert_Low) || \((ALERT) == I2C_SMBusAlert_High))/* I2C PEC position */#define I2C_PECPosition_Next ((u16)0x0800)#define I2C_PECPosition_Current ((u16)0xF7FF)#define IS_I2C_PEC_POSITION(POSITION) (((POSITION) == I2C_PECPosition_Next) || \((POSITION) == I2C_PECPosition_Current))/* I2C interrupts definition */#define I2C_IT_BUF ((u16)0x0400)#define I2C_IT_EVT ((u16)0x0200)#define I2C_IT_ERR ((u16)0x0100)#define IS_I2C_CONFIG_IT(IT) ((((IT) & (u16)0xF8FF) == 0x00) && ((IT) != 0x00))/* I2C interrupts definition */#define I2C_IT_SMBALERT ((u32)0x10008000)#define I2C_IT_TIMEOUT ((u32)0x10004000)#define I2C_IT_PECERR ((u32)0x10001000)#define I2C_IT_OVR ((u32)0x10000800)#define I2C_IT_AF ((u32)0x10000400)#define I2C_IT_ARLO ((u32)0x10000200)#define I2C_IT_BERR ((u32)0x10000100)#define I2C_IT_TXE ((u32)0x00000080)#define I2C_IT_RXNE ((u32)0x00000040)#define I2C_IT_STOPF ((u32)0x60000010)#define I2C_IT_ADD10 ((u32)0x20000008)#define I2C_IT_BTF ((u32)0x60000004)#define I2C_IT_ADDR ((u32)0xA0000002)#define I2C_IT_SB ((u32)0x20000001)#define IS_I2C_CLEAR_IT(IT) (((IT) == I2C_IT_SMBALERT) || ((IT) == I2C_IT_TIMEOUT) || \((IT) == I2C_IT_PECERR) || ((IT) == I2C_IT_OVR) || \((IT) == I2C_IT_AF) || ((IT) == I2C_IT_ARLO) || \((IT) == I2C_IT_BERR) || ((IT) == I2C_IT_STOPF) || \((IT) == I2C_IT_ADD10) || ((IT) == I2C_IT_BTF) || \((IT) == I2C_IT_ADDR) || ((IT) == I2C_IT_SB))#define IS_I2C_GET_IT(IT) (((IT) == I2C_IT_SMBALERT) || ((IT) == I2C_IT_TIMEOUT) || \((IT) == I2C_IT_PECERR) || ((IT) == I2C_IT_OVR) || \((IT) == I2C_IT_AF) || ((IT) == I2C_IT_ARLO) || \((IT) == I2C_IT_BERR) || ((IT) == I2C_IT_TXE) || \((IT) == I2C_IT_RXNE) || ((IT) == I2C_IT_STOPF) || \((IT) == I2C_IT_ADD10) || ((IT) == I2C_IT_BTF) || \((IT) == I2C_IT_ADDR) || ((IT) == I2C_IT_SB))/* I2C flags definition */#define I2C_FLAG_DUALF ((u32)0x00800000)#define I2C_FLAG_SMBHOST ((u32)0x00400000)#define I2C_FLAG_SMBDEF AUL T ((u32)0x00200000)#define I2C_FLAG_GENCALL ((u32)0x00100000)#define I2C_FLAG_TRA ((u32)0x00040000)#define I2C_FLAG_BUSY ((u32)0x00020000)#define I2C_FLAG_MSL ((u32)0x00010000)#define I2C_FLAG_SMBALERT ((u32)0x10008000)#define I2C_FLAG_TIMEOUT ((u32)0x10004000)#define I2C_FLAG_PECERR ((u32)0x10001000)#define I2C_FLAG_OVR ((u32)0x10000800)#define I2C_FLAG_AF ((u32)0x10000400)#define I2C_FLAG_ARLO ((u32)0x10000200)#define I2C_FLAG_BERR ((u32)0x10000100)#define I2C_FLAG_TXE ((u32)0x00000080)#define I2C_FLAG_RXNE ((u32)0x00000040)#define I2C_FLAG_STOPF ((u32)0x60000010)#define I2C_FLAG_ADD10 ((u32)0x20000008)#define I2C_FLAG_BTF ((u32)0x60000004)#define I2C_FLAG_ADDR ((u32)0xA0000002)#define I2C_FLAG_SB ((u32)0x20000001)#define IS_I2C_CLEAR_FLAG(FLAG) (((FLAG) == I2C_FLAG_SMBALERT) || ((FLAG) == I2C_FLAG_TIMEOUT) || \((FLAG) == I2C_FLAG_PECERR) || ((FLAG) == I2C_FLAG_OVR) || \((FLAG) == I2C_FLAG_AF) || ((FLAG) == I2C_FLAG_ARLO) || \((FLAG) == I2C_FLAG_BERR) || ((FLAG) == I2C_FLAG_STOPF) || \((FLAG) == I2C_FLAG_ADD10) || ((FLAG) == I2C_FLAG_BTF) || \((FLAG) == I2C_FLAG_ADDR) || ((FLAG) == I2C_FLAG_SB))#define IS_I2C_GET_FLAG(FLAG) (((FLAG) == I2C_FLAG_DUALF) || ((FLAG) == I2C_FLAG_SMBHOST) || \((FLAG) == I2C_FLAG_SMBDEF AUL T) || ((FLAG) == I2C_FLAG_GENCALL) || \((FLAG) == I2C_FLAG_TRA) || ((FLAG) == I2C_FLAG_BUSY) || \((FLAG) == I2C_FLAG_MSL) || ((FLAG) == I2C_FLAG_SMBALERT) || \((FLAG) == I2C_FLAG_TIMEOUT) || ((FLAG) == I2C_FLAG_PECERR) || \((FLAG) == I2C_FLAG_OVR) || ((FLAG) == I2C_FLAG_AF) || \((FLAG) == I2C_FLAG_ARLO) || ((FLAG) == I2C_FLAG_BERR) || \((FLAG) == I2C_FLAG_TXE) || ((FLAG) == I2C_FLAG_RXNE) || \((FLAG) == I2C_FLAG_STOPF) || ((FLAG) == I2C_FLAG_ADD10) || \((FLAG) == I2C_FLAG_BTF) || ((FLAG) == I2C_FLAG_ADDR) || \((FLAG) == I2C_FLAG_SB))/* I2C Events *//* EV1 */#define I2C_EVENT_SLA VE_TRANSMITTER_ADDRESS_MA TCHED ((u32)0x00060082) /* TRA, BUSY, TXE and ADDR flags */#define I2C_EVENT_SLA VE_RECEIVER_ADDRESS_MA TCHED ((u32)0x00020002) /* BUSY and ADDR flags */#define I2C_EVENT_SLA VE_TRANSMITTER_SECONDADDRESS_MA TCHED ((u32)0x00860080) /* DUALF, TRA, BUSY and TXE flags */#define I2C_EVENT_SLA VE_RECEIVER_SECONDADDRESS_MA TCHED ((u32)0x00820000) /* DUALF and BUSY flags */#define I2C_EVENT_SLA VE_GENERALCALLADDRESS_MA TCHED ((u32)0x00120000) /* GENCALL and BUSY flags *//* EV2 */#define I2C_EVENT_SLA VE_BYTE_RECEIVED ((u32)0x00020040) /* BUSY and RXNE flags *//* EV3 */#define I2C_EVENT_SLA VE_BYTE_TRANSMITTED ((u32)0x00060084) /* TRA, BUSY, TXE and BTF flags *//* EV4 */#define I2C_EVENT_SLA VE_STOP_DETECTED ((u32)0x00000010) /* STOPF flag *//* EV5 */#define I2C_EVENT_MASTER_MODE_SELECT ((u32)0x00030001) /* BUSY, MSL and SB flag *//* EV6 */#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((u32)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */#define I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ((u32)0x00030002) /* BUSY, MSL and ADDR flags *//* EV7 */#define I2C_EVENT_MASTER_BYTE_RECEIVED ((u32)0x00030040) /* BUSY, MSL and RXNE flags *//* EV8 */#define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((u32)0x00070084) /* TRA, BUSY, MSL, TXE and BTF flags *//* EV9 */#define I2C_EVENT_MASTER_MODE_ADDRESS10 ((u32)0x00030008) /* BUSY, MSL and ADD10 flags *//* EV3_2 */#define I2C_EVENT_SLA VE_ACK_F AILURE ((u32)0x00000400) /* AF flag */#define IS_I2C_EVENT(EVENT) (((EVENT) == I2C_EVENT_SLA VE_TRANSMITTER_ADDRESS_MA TCHED) || \((EVENT) == I2C_EVENT_SLA VE_RECEIVER_ADDRESS_MA TCHED) || \((EVENT) == I2C_EVENT_SLA VE_TRANSMITTER_SECONDADDRESS_MA TCHED) || \((EVENT) == I2C_EVENT_SLA VE_RECEIVER_SECONDADDRESS_MA TCHED) || \((EVENT) == I2C_EVENT_SLA VE_GENERALCALLADDRESS_MA TCHED) || \((EVENT) == I2C_EVENT_SLA VE_BYTE_RECEIVED) || \((EVENT) == (I2C_EVENT_SLA VE_BYTE_RECEIVED | I2C_FLAG_DUALF)) || \((EVENT) == (I2C_EVENT_SLA VE_BYTE_RECEIVED | I2C_FLAG_GENCALL)) || \((EVENT) == I2C_EVENT_SLA VE_BYTE_TRANSMITTED) || \((EVENT) == (I2C_EVENT_SLA VE_BYTE_TRANSMITTED | I2C_FLAG_DUALF)) || \((EVENT) == (I2C_EVENT_SLA VE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL)) || \((EVENT) == I2C_EVENT_SLA VE_STOP_DETECTED) || \((EVENT) == I2C_EVENT_MASTER_MODE_SELECT) || \((EVENT) == I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) || \((EVENT) == I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) || \((EVENT) == I2C_EVENT_MASTER_BYTE_RECEIVED) || \((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTED) || \((EVENT) == I2C_EVENT_MASTER_MODE_ADDRESS10) || \((EVENT) == I2C_EVENT_SLA VE_ACK_F AILURE))/* I2C own address1 -----------------------------------------------------------*/#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x3FF)/* I2C clock speed ------------------------------------------------------------*/#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) >= 0x1) && ((SPEED) <= 400000))/* Exported macro ------------------------------------------------------------*//* Exported functions ------------------------------------------------------- */void I2C_DeInit(I2C_TypeDef* I2Cx);void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct);void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct);void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState);void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);void I2C_GenerateST ART(I2C_TypeDef* I2Cx, FunctionalState NewState);void I2C_GenerateSTOP(I2C_T ypeDef* I2Cx, FunctionalState NewState);void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, u8 Address);void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);void I2C_ITConfig(I2C_TypeDef* I2Cx, u16 I2C_IT, FunctionalState NewState);void I2C_SendData(I2C_TypeDef* I2Cx, u8 Data);u8 I2C_ReceiveData(I2C_TypeDef* I2Cx);void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, u8 Address, u8 I2C_Direction);u16 I2C_ReadRegister(I2C_TypeDef* I2Cx, u8 I2C_Register);void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, u16 I2C_SMBusAlert);void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState);void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, u16 I2C_PECPosition);void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState);u8 I2C_GetPEC(I2C_TypeDef* I2Cx);void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, u16 I2C_DutyCycle);u32 I2C_GetLastEvent(I2C_TypeDef* I2Cx);ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, u32 I2C_EVENT);FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, u32 I2C_FLAG);void I2C_ClearFlag(I2C_TypeDef* I2Cx, u32 I2C_FLAG);ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, u32 I2C_IT);void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, u32 I2C_IT);#endif /*__STM32F10x_I2C_H *//******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/[3] 源文件1/****************************************Copyright (c)****************************************************** ****--------------File Info-------------------------------------------------------------------------------** File name: 24C02.c** Descriptions: 24C02 操作函数库****------------------------------------------------------------------------------------------------------** Created by: A VRman** Created date: 2010-10-29** V ersion: 1.0** Descriptions: The original version****------------------------------------------------------------------------------------------------------** Modified by:** Modified date:** V ersion:** Descriptions:********************************************************************************************************//* Includes ------------------------------------------------------------------*/#include "HMC5883L.h"#include "Grobalfunction.h"/******************************************************************************** Function Name : I2C_Configuration* Description : EEPROM管脚配置* Input : None* Output : None* Return : None* Attention : None*******************************************************************************/void I2C_Configuration(void){I2C_InitTypeDef I2C_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE);/* Configure I2C1 pins: PB6->SCL and PB7->SDA */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;///6,7->8,9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;GPIO_Init(GPIOB, &GPIO_InitStructure);I2C_DeInit(I2C1);I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = 0x30;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed = 100000; /* 100K速度*/I2C_Cmd(I2C1, ENABLE);I2C_Init(I2C1, &I2C_InitStructure);/*允许1字节1应答模式*/I2C_AcknowledgeConfig(I2C1, ENABLE);}/******************************************************************************* * Function Name : I2C_delay* Description : 延迟时间* Input : None* Output : None* Return : None* Attention : None*******************************************************************************/ static void I2C_delay(u16 cnt){while(cnt--);}/******************************************************************************* * Function Name : I2C_AcknowledgePolling* Description : 等待获取I2C总线控制权判断忙状态* Input : - I2Cx:I2C寄存器基址* - I2C_Addr:从器件地址* Output : None* Return : None* Attention : None*******************************************************************************/ static void I2C_AcknowledgePolling(I2C_TypeDef *I2Cx,u8 I2C_Addr){vu16 SR1_Tmp;do{I2C_GenerateST ART(I2Cx, ENABLE); /*起始位*//*读SR1*/SR1_Tmp = I2C_ReadRegister(I2Cx, I2C_Register_SR1);/*器件地址(写)*/#ifdef A T24C01AI2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);#elseI2C_Send7bitAddress(I2Cx, 0, I2C_Direction_Transmitter);#endif}while(!(I2C_ReadRegister(I2Cx, I2C_Register_SR1) & 0x0002));I2C_ClearFlag(I2Cx, I2C_FLAG_AF);I2C_GenerateSTOP(I2Cx, ENABLE); /*停止位*/}/******************************************************************************** Function Name : I2C_Read* Description : 通过指定I2C接口读取多个字节数据* Input : - I2Cx:I2C寄存器基址* - I2C_Addr:从器件地址* - addr:预读取字节存储位置* - *buf:读取数据的存储位置* - num:读取字节数* Output : None* Return : 成功返回0* Attention : None*******************************************************************************/u8 I2C_Read(I2C_TypeDef *I2Cx,u8 I2C_Addr,u8 addr,u8 *buf,u16 num){///u16 angle;if(num==0)return 1;while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));/*允许1字节1应答模式*/I2C_AcknowledgeConfig(I2Cx, ENABLE);/* 发送起始位*/I2C_GenerateST ART(I2Cx, ENABLE);while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,主模式*////#ifdef A T24C01A/*发送器件地址(写)*/I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));/*发送地址*/I2C_SendData(I2Cx, addr);while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));/*数据已发送*/ /*起始位*/I2C_GenerateST ART(I2Cx, ENABLE);while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));/*器件读*/I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Receiver);/// while(1);while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));///#else/*发送器件地址(读)24C01*//// I2C_Send7bitAddress(I2Cx, addr<<1, I2C_Direction_Receiver);/// while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));///#endifwhile (num){if(num==1){I2C_AcknowledgeConfig(I2Cx, DISABLE); /* 最后一位后要关闭应答的*/ I2C_GenerateSTOP(I2Cx, ENABLE); /* 发送停止位*/return 0;}/*器件读*//// I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Receiver);while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */*buf = I2C_ReceiveData(I2Cx);buf++;/* Decrement the read bytes counter */num--;/// I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Receiver);/// while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));}/* 再次允许应答模式*/I2C_AcknowledgeConfig(I2Cx, ENABLE);return 0;}/******************************************************************************** Function Name : I2C_WriteOneByte* Description : 通过指定I2C接口写入一个字节数据* Input : - I2Cx:I2C寄存器基址* - I2C_Addr:从器件地址* - addr:预写入字节地址* - value:写入数据* Output : None* Return : 成功返回0* Attention : None*******************************************************************************/u8 I2C_WriteOneByte(I2C_TypeDef *I2Cx,u8 I2C_Addr,u8 addr,u8 value){/* 起始位*/I2C_GenerateST ART(I2Cx, ENABLE);while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));///#ifdef A T24C01A/* 发送器件地址(写)*/I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));/*发送地址*/I2C_SendData(I2Cx, addr);while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));///#else/// I2C_Send7bitAddress(I2Cx, addr<<1, I2C_Direction_Transmitter);/// while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); ///#endif/* 写一个字节*/I2C_SendData(I2Cx, value);while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));/* 停止位*/I2C_GenerateSTOP(I2Cx, ENABLE);I2C_AcknowledgePolling(I2Cx,I2C_Addr);I2C_delay(1000);return 0;}/******************************************************************************** Function Name : I2C_Write* Description : 通过指定I2C接口写入多个字节数据* Input : - I2Cx:I2C寄存器基址* - I2C_Addr:从器件地址* - addr:预写入字节地址* - *buf:预写入数据存储位置* - num:写入字节数* Output : None* Return : 成功返回0* Attention : None*******************************************************************************/u8 I2C_Write(I2C_TypeDef *I2Cx,u8 I2C_Addr,u8 addr,u8 *buf,u16 num){u8 err=0;while(num--){if(I2C_WriteOneByte(I2Cx, I2C_Addr,addr++,*buf++)){err++;}}if(err)return 1;elsereturn 0;}//初始化HMC5883,根据需要请参考pdf进行修改****void Init_HMC5883(){///Single_Write_HMC5883(0x02,0x00); //I2C_WriteOneByte(I2C1,0x3c,0x02,0);}/************************************************************************************************************/ /******************************************************************************** Function Name : void Axia3AngInit(void).* Description : Read 3 axia angle data from HMC5883 then process the data.* Input : - I2Cx:I2C寄存器基址* - I2C_Addr:从器件地址* - addr:预写入字节地址* - value:写入数据* Output : None* Return : 成功返回0* Attention : None*******************************************************************************/void Axia3AngInit(void){I2C_Configuration();Init_HMC5883();}/************************************************************************************************************//************************************************************************************************************/ /******************************************************************************** Function Name : Detect3AxiaAng();* Description : Read 3 axia angle data from HMC5883 then process the data.* Input : - I2Cx:I2C寄存器基址* - I2C_Addr:从器件地址* - addr:预写入字节地址* - value:写入数据* Output : None* Return : 成功返回0* Attention : None*******************************************************************************/void Detect3AxiaAng(void){I2C_Read(I2C1,0x3C,0x03,BUF,7);//Axia3Ang_x=BUF[0] << 8 | BUF[1]; //Combine MSB and LSB of X Data output registerAxia3Ang_z=BUF[2] << 8 | BUF[3]; //Combine MSB and LSB of Z Data output registerAxia3Ang_y=BUF[4] << 8 | BUF[5]; //Combine MSB and LSB of Y Data output register/*//Get float dataAxia3Ang_xF=Axia3Ang_x*0.0 BUF[0] << 8 | BUF[1]; //Combine MSB and LSB of X Data output registerAxia3Ang_zF=Axia3Ang_x* BUF[2] << 8 | BUF[3]; //Combine MSB and LSB of Z Data output registerAxia3Ang_yF=Axia3Ang_x* BUF[4] << 8 | BUF[5]; //Combine MSB and LSB of Y Data output register// delay_ms(500);*/}//*********************************************************//主程序********//*********************************************************void HMC5883L_test(void ){ // bit sign_bit;///unsigned int i;///int x,y,z;///double angle;I2C_Configuration();Init_HMC5883();while(1) //循环{///// Multiple_Read_HMC5883(); //连续读出数据,存储在BUF中///loop1:I2C_Read(I2C1,0x3C,0x03,BUF,7);////---------显示X轴delay_ms(10);/// goto loop1;/// while(1);Axia3Ang_x=BUF[0] << 8 | BUF[1]; //Combine MSB and LSB of X Data output registerAxia3Ang_z=BUF[2] << 8 | BUF[3]; //Combine MSB and LSB of Z Data output registerAxia3Ang_y=BUF[4] << 8 | BUF[5]; //Combine MSB and LSB of Y Data output registerdelay_ms(500);/// angle= atan2((double)y,(double)x) * (180 / 3.14159265) + 180; // angle in degrees/// angle*=10;///conversion(angle); //计算数据和显示///for (i=0;i<10000;i++); //延时}}/********************************************************************************************************* END FILE*********************************************************************************************************/[4] 源文件4/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************* File Name : stm32f10x_i2c.c* Author : MCD Application T eam* V ersion : V2.0.1* Date : 06/13/2008* Description : This file provides all the I2C firmware functions.********************************************************************************* THE PRESENT FIRMW ARE WHICH IS FOR GUIDANCE ONL Y AIMS A T PROVIDING CUSTOMERS* WITH CODING INFORMA TION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SA VE TIME. * AS A RESUL T, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE * CONTENT OF SUCH FIRMW ARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING* INFORMA TION CONT AINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.*******************************************************************************//* Includes ------------------------------------------------------------------*/#include "stm32f10x_i2c.h"#include "stm32f10x_rcc.h"/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*//* I2C SPE mask */#define CR1_PE_Set ((u16)0x0001)#define CR1_PE_Reset ((u16)0xFFFE)/* I2C ST ART mask */#define CR1_ST ART_Set ((u16)0x0100)#define CR1_ST ART_Reset ((u16)0xFEFF)/* I2C STOP mask */#define CR1_STOP_Set ((u16)0x0200)#define CR1_STOP_Reset ((u16)0xFDFF)/* I2C ACK mask */#define CR1_ACK_Set ((u16)0x0400)#define CR1_ACK_Reset ((u16)0xFBFF)/* I2C ENGC mask */#define CR1_ENGC_Set ((u16)0x0040)#define CR1_ENGC_Reset ((u16)0xFFBF)/* I2C SWRST mask */#define CR1_SWRST_Set ((u16)0x8000)#define CR1_SWRST_Reset ((u16)0x7FFF)/* I2C PEC mask */#define CR1_PEC_Set ((u16)0x1000)#define CR1_PEC_Reset ((u16)0xEFFF)/* I2C ENPEC mask */#define CR1_ENPEC_Set ((u16)0x0020)#define CR1_ENPEC_Reset ((u16)0xFFDF)/* I2C ENARP mask */#define CR1_ENARP_Set ((u16)0x0010)#define CR1_ENARP_Reset ((u16)0xFFEF)/* I2C NOSTRETCH mask */#define CR1_NOSTRETCH_Set ((u16)0x0080)。
AHRS姿态解算说明(加速度陀螺仪磁力计原理及原始数据分析)给51黑论坛的朋友们分享关于MPU6050的超好文章,介绍姿态解算的入门知识,非常通俗易懂.AHRS俗称航姿参考系统,AHRS由加速度计,磁场计,陀螺仪构成,AHRS的真正参考来自于地球的重力场和地球的磁场~~他的静态终精度取决于对磁场的测量精度和对重力的测量精度,而则陀螺决定了他的动态性能。
这就是AHRS~在这种前提下。
说明AHRS离开了地球这种有重力和磁场环境的时候是没法正常工作的~~本章旨在讲解以下内容1.加速度2.陀螺仪3.磁力计一直想写篇文章关于姿态解算原理的,使用尽量通俗的语句说明如何从加速度计和陀螺仪的数据,融合得到载体的姿态角。
无奈自己的水平有限,一直搁置。
淡泊以明志,宁静以致远.人总是要逼自己做些事,才过得心安理得。
那就拿点时间把这方面的资料整合一下吧。
这篇文章的大部分内容都不是本人原创的,感谢网络上无私奉献的人.在此介绍一下实验的姿态板,新一代的mini AHRS,采用STM32F103单片机进行姿态解算,板子上集成有1.MPU6050,三轴的加速度和陀螺仪2.HMC5883 三轴的磁力计3.BMP180 高精度气压高度计这些传感器都通过I2C接口连接到主控制器STM32.不需要额外的ADC电路,直接通过数字接口就可以读取传感器的当前输出.Mini AHRS硬件框图1 加速度计加速度计顾名思义,就是测量加速度的.那么,我们如何认识这个加速度呢?在此用一个盒子形状的立方体来做模型,认识加速度,如下,盒子内的图像。
如果我们把盒子形状的立方体放在一个没引力场的地方,球会保持在盒子的中间.你可以想象,这个盒子是在外太空,远离任何天体,很难找到这样的地方,就想象飞船轨道围绕地球飞,一切都是在失重状态下。
那么六个壁面感受到的压力都是0.如果我们突然将立方体向左侧移动(我们加快加速,1G =9.8米/ S ^ 2),皮球打在了墙上X-。
摘要作为我国古代四大发明之一的指南针,为世界各族人民生活带来了很大的便利,它是一种重要的导航工具,为世界的航海事业做出了不可抹灭的贡献。
然而在当今的指南针家族中,数字指南针以其内部结构固定,没有移动部分,可以简单地和其它电子系统接口,因此很多地方代替了旧的磁指南针。
并以精度高、稳定性好等特点得到了广泛运用。
本文介绍了目前用于定位系统中的数字指南针的工作原理,详细论述了磁场传感器芯片HMC5883L的工作原理,给出了用HMC58832L 磁场传感器设计数字指南针的总体设计方案和电路,同时也给出了在12864液晶显示设计方案。
符号说明1.系统方案设计1.1设计任务基于STC89C52单片机,霍尼韦尔公司生产的磁场传感器芯片HMC5883L设计一个数字指南针,并在液晶显示屏12864上显示指南针。
其次,指南针反应速度应该和普通磁石指南针相近。
1.2方案论证与选择方案一:采用Philips公司生产的KMZ52感应磁场KMZ52是Philips公司生产的一种磁阻传感器,是利用坡莫合金薄片的磁阻效应测量磁场的高灵敏度磁阻传感器。
该磁阻传感器内置两个正交磁敏电阻桥、完整的补偿线圈和设置/复位线圈。
补偿线圈的输出与当前测量结果形成闭环反馈,使传感器的灵敏度不受地域限制。
这种磁阻传感器主要应用于导航、通用地磁测量和交通检测。
该磁阻传感器在金属铝的表面沉积了一定厚度的高磁导率的坡莫合金,在翻转线圈和外界磁场两个力的作用下,电子改变运动方向,使得磁敏电阻的阻值发生变化。
同时KMZ52的斑马条电阻成45°放置,这使得电子在正反向磁场力作用下有较好的对称性。
由于加入了翻转磁场,KMZ52的变化曲线与普通的磁敏电阻不同,更加线性化。
KMZ52磁阻传感器的核心部分是惠斯通电桥,是由4个磁敏感元件组成的磁阻桥臂。
磁敏感元件由长而薄的坡莫合金薄膜制成。
在外加磁场的作用下,磁阻的变化引起输出电压的变化。
方案二:采用美国PNI 磁通传感器SEN-S65SEN-S65是PNI公司开发的磁感技术磁传感器。
HMC5883L3轴数字罗盘IC--采用霍尼韦尔各向异性磁阻(AMR)技术物质在磁场中电阻率发生变化的现象称为磁阻效应,磁阻传感器利用磁阻效应制成。
磁场的测量可利用电磁效应,霍尔效应,磁阻效应等各种效应。
其中磁阻效应法发展最快,测量灵敏度最高。
磁阻传感器可用于直接测量磁场或磁场变化,如弱磁场测量,地磁场测量,各种导航系统中的罗盘,计算机中的磁盘驱动器,各种磁卡机等等。
也可以通过磁场变化测量其他物理量,如利用磁阻效应已制成各种位移、角度、转速传感器,各种接近开关,隔离开关,广泛用于汽车、家电及各类需要自动检测与控制的领域。
磁阻元件的发展经历了半导体磁阻(MR),各向异性磁阻(AMR),巨磁阻(GMR),庞磁阻(CMR)等阶段。
各向异性磁阻传感器AMR(Anisotropic Magneto-Resistive sensors)由沉积在硅片上的坡莫合金薄膜形成电阻,沉积时外加磁场,形成易磁化轴方向。
铁磁材料的电阻与电流方向和磁化方向的夹角有关,电流与磁化方向平行是电阻Rmax最大,电流与磁化方向垂直是电阻Rmin最小,电流与磁化方向成θ角时,电阻可表示为:在磁阻传感器中,为消除温度等外界因素对输出的影响,有4个相同的磁阻元件构成惠斯通电桥。
AMR各向异性磁电阻效应指铁磁金属或合金中,磁场平行电流和垂直电流方向电阻率发生变化的效应。
AMR各向异性传感器的基本单元是用一种长而薄的坡莫(Ni-Fe)合金用半导体工艺沉积在以硅衬底上制成的,沉积的时候薄膜以条带的形式排布,形成一个平面的线阵以增加磁阻的感知磁场的面积。
外加磁场使得磁阻内部的磁畴指向发生变化,进而与电流的夹角θ发生变化,就表现为磁阻电阻各向异性的变化。
(1)服从式(1)中:Rmin为电流方向与磁化方向垂直时的电阻值;Rmax为电流方向与磁化方向平行时的电流值。
从图1可以清楚地看到,当电流方向与磁化方向平行时,传感器最敏感。
而一般磁阻都工作于图中45°线性区附近,这样可以实现输出的线性特性。
六轴传感器计算航向的方法
六轴传感器可以用来测量物体的姿态和运动状态,包括三个轴的角速度和三个轴的加速度。
这些数据可以通过一定的算法处理来计算物体的航向。
以下是基于六轴传感器计算航向方法的基本步骤:
1.角速度积分:首先,对三轴角速度数据进行积分,得到每个轴的旋转角度。
积分时需要考虑到累积误差的影响,可以使用滤波器或融合算法来减小误差。
2.四元数表示:然后,使用四元数来表示物体的姿态。
四元数可以用来描述3D旋转,其优点在于不需要进行奇异值分解,计算较为稳定。
将积分得到的旋转角度转换为四元数。
3.磁力计数据融合:磁力计可以测量地球的磁场强度,通过磁力计数据可以进一步校准姿态测量结果,尤其是在没有明显的线速度变化的情况下。
4.航向角计算:使用四元数来表示和计算航向角。
通常来说,航向角是指北向和物体旋转轴之间的夹角。
具体的计算方法依赖于具体的应用场景和数据表示方式。
5.数据滤波和融合:最后,利用卡尔曼滤波或其他算法对姿态数据进行滤波和融合,以提高航向计算的准确性和稳定性。
需要注意的是,六轴传感器计算航向的方法受到许多因素的影响,包括传感器的精度、噪声、积分误差等。
在实际应用中,可能需要对算法进行优化和调整,以适应具体的应用场景和需求。
罗盘测量方位角的使用方法罗盘是一种用来测量方位角的工具,它是导航和定位中不可或缺的设备之一。
在航海、探险、徒步旅行等活动中,正确使用罗盘可以帮助我们确定方向,避免迷失和走错路。
下面将介绍一些关于罗盘测量方位角的使用方法。
一、罗盘的构造和工作原理罗盘由一个磁针和一个刻度盘组成。
磁针是一个带有磁性的指针,可以自由地转动。
刻度盘上标有方位角的刻度,通常以360度表示一个完整的圆周。
罗盘的工作原理是基于地球的地磁场,磁针会受到地磁场的作用而指向地磁北极。
二、校准罗盘在使用罗盘之前,需要先校准罗盘。
校准的目的是确保罗盘的指向准确。
校准过程中,需要注意远离金属物体和电子设备,因为它们可能干扰罗盘的指向。
具体的校准方法可以参考罗盘的使用说明书。
三、确定起点和目标点在使用罗盘测量方位角之前,首先需要确定起点和目标点。
起点是我们当前所处的位置,目标点是我们想要到达的位置。
可以使用地图、导航软件等工具来确定起点和目标点的坐标。
四、保持水平和稳定在使用罗盘时,需要保持罗盘水平和稳定。
如果罗盘倾斜或受到颠簸,磁针会受到干扰,导致测量结果不准确。
可以通过手持罗盘的方式来保持罗盘水平,或者使用支架将罗盘固定在一个平稳的位置上。
五、读取方位角在保持罗盘水平和稳定的情况下,可以读取罗盘上指针所指的刻度,这个刻度就是方位角。
方位角通常以度数表示,例如北方为0度,东方为90度,南方为180度,西方为270度。
根据指针所指的刻度,可以确定当前的方向。
六、校正磁偏角在实际使用罗盘时,需要注意地球的磁偏角。
磁偏角是指磁北极和地理北极之间的夹角,不同地区的磁偏角可能不同。
在读取罗盘上的方位角时,需要根据所处位置的磁偏角进行校正,以获得准确的方向。
七、使用罗盘进行导航通过测量起点和目标点之间的方位角,我们可以确定应该朝哪个方向前进。
如果目标点在正北方向,我们就需要朝着0度的方向前进;如果目标点在东北方向,我们就需要朝着45度的方向前进。
根据目标点的方位角,我们可以调整自己的行进方向,确保走在正确的路上。
使用HMC5883L-3轴数字罗盘传感器计算航向角
——中北大学:马政贵
图1 HMC5883L的电路图
HMC5883L-3轴数字罗盘采用IIC总线接口,内含12位AD转换器,能在8Ga的磁场
中实现5mGa的分辨率。
1. HMC5883L的初始化:
HMC5883L的磁场默认测量范围为1.3Ga,由于地磁场强度大约是0.5-0.6Ga,故使用
默认的量程即可,此外还需进行采样平均数、数据输出速率、测量模式的初始化配置即可。
/*******************************************************************************
功能:对HMC5883L进行初始化
参数:无
返回值:无
*******************************************************************************/
void HMC5883_Init(void)
{
HMC_GPIO_Config(); //GPIO配置
HMC_I2C_Write(0x00,0x78); //(配置寄存器A)采样平均数8;数据输出速率75Hz;正常测量配置模式
HMC_I2C_Write(0x02,0x00); //(模式寄存器)连续测量模式
}
备注:void HMC_I2C_Write(u8 address,u8 data)为寄存器写入函数,第一个参数address
为要写入的寄存器地址,第二个参数data为要写入寄存器的值。
2. HMC5883L自测:
HMC5883L-3轴数字罗盘内含自测模式。
HMC_I2C_Write(0x00,0x79); //(配置寄存器A)采样平均数8;数据输出速率75Hz;正偏压自测模式
HMC_I2C_Write(0x02,0x01); //
(模式寄存器)单一测量模式
通过将配置寄存器A的最低位(MS1和MS0)从00更改为01,然后再配置为单一测量模式,
即可进入自测模式。自测模式下会在内部创建一个标准的自测磁场,从而支持传感器的比例
因子校准。标准磁场的理论值与实际测量值的比值,即可得出传感器的比例因子:
calibration[0] = fabs(951.0 / Compass_Data[0]);
calibration[1] = fabs(951.0 / Compass_Data[1]);
calibration[2] = fabs(886.0 / Compass_Data[2]);
其中,calibration[n]为比例因子,Compass_Data[n]为罗盘的原始数据,951是自测模式下在
X、Y轴的标准输出值,886是自测模式下在Z轴的标准输出值。
3. HMC5883L的硬磁失真校正及倾角补偿:
HMC5883L-3轴数字罗盘在工作过程中,由于不可避免的受周围电磁场的干扰,如电路
走线、其他电子器件工作时的电磁干扰等,从而造成罗盘XYZ轴测得的地磁场强度发生不同
程度的偏移变形。一般我们将干扰的影响分为硬磁失真和软磁失真两类,从影响效果上来看,
硬磁失真会造成磁场输出曲线图的圆心偏移,而软磁失真会把理论上为圆形的地磁场拉伸为
椭圆。前期的标定过程中,只对硬磁失真进行了校正,通过分别绕每个轴旋转360°,求另
外两个轴的最大值和最小值的和的平均值作为零点偏移量,从而使圆心回到原点:
offset[n] = -(max[n]+min[n])/2; // calculate offsets
MagVec[n] = (Compass_Data[n]*calibration[n]+offset[n]);
其中,offset[n]为零点偏移量,MagVec[n]为最终用于计算的罗盘数据。
图2 电子罗盘三维数学模型
此外,由于罗盘不是一直处于水平位置,因此需要使用姿态角(横滚角和俯仰角)对罗
盘进行倾角补偿,根据矢量三角形,有:
Head_X = Head_X*cos(pitch)+Head_Y*sin(roll)*sin(pitch)-Head_Z*cos(roll)*sin(pitch);
Head_Y = Head_Y*cos(roll)+Head_Z*sin(roll);
4. 航向角计算:
可使用反三角函数atanf()进行航向角度的计算,需要注意的是,因为角度的4个象限
(atanf()返回值为),为了使航向角的范围为0~360°,需要进行不同象限下的相应
转换处理。
2/
由于地磁北和地理北存在大约11.5°的偏差角度,因此在解算出来的航向角上,还需要
进行该偏差角度的补偿作为最终的航向角。
if(Head_X>0 && Head_Y<0)
{
Heading = - atanf(Head_Y/Head_X) * 180/M_PI;
}
if(Head_X<0.05 && Head_X>-0.05 && Head_Y<0)
{
Heading=90;
}
if(Head_X<0)
{
Heading=180 - atanf(Head_Y/Head_X) * 180/M_PI;
}
if(Head_X<0.05 && Head_X>-0.05 && Head_Y>0)
{
Heading=270;
}
if(Head_X>0 && Head_Y>0)
{
Heading=360 - atanf(Head_Y/Head_X) * 180/M_PI;
}
Heading = Heading - 11.5; //地磁北和地理北的偏差角度:11.5
if(Heading < 0)
{
Heading = 360 + Heading;
}
参看:
1、Honeywell-《3-Axis Digital Compass IC HMC5883L》
2、范寒柏,陈邵权,王涛,王磊-《电子罗盘倾角补偿和干扰补偿的理论分析及实验验证》