基于STM32的三轴数字罗盘HMC5883L模块的测试方案

发布者:快乐飞跃最新更新时间:2018-03-12 来源: 互联网关键字:HMC5883L  数字罗盘  STM32 手机看文章 扫描二维码
随时随地手机看文章

最近买了个数字罗盘模块,调通后发现很不错,非常灵敏,测试的时候精度在1°以内。连续测量模式下,最快测量、输出速率可达75hz,模块每次测量完毕并将数据更新至寄存器后,其DRDY引脚便产生一个低电平脉冲(可以配置一个外部中断捕获DRDY引脚的下降沿,并在中断服务程序中读取数据),在STM32中可以设置一个下降沿触发的外部中断,并在中断服务程序中调用角度数据读取函数。以下为操作该模块的主要步骤。


一、IIC协议相关操作(单片机作为主机控制时钟线)


  宏定义:

  //这里用到了STM32的位带区操作,方便实现对一个位的操作

  //PB13配置为OD输出,同时外部给上拉电阻,这样既可输出信号给从机,也能

  //在PB13为漏极开路状态时接收从机的信号(STM32的IO配置为输出模式时,

  //IO口的电平也会不断地被捕获到输入寄存器中)

  //PB14配置为推挽输出,PB15配置为浮空输入

  #defineR_SDAIPB13//PB13输入寄存器

  #defineW_SDAOPB13//PB13输出寄存器

  #defineW_SCLOPB14//PB14输出寄存器

  #defineR_DRDYIPB15//PB15输入寄存器

  #defineXmsb0//X轴数字量的高8位

  #defineXlsb1//X轴数字量的低8位

  #defineZmsb2//Z轴数字量的高8位

  #defineZlsb3//Z轴数字量的低8位

  #defineYmsb4//Y轴数字量的高8位

  #defineYlsb5//Y轴数字量的低8位

  附位带宏定义:

  #defineGPIOB_ODR_Addr(GPIOB_BASE+12)//0x40010C0C

  #defineGPIOB_IDR_Addr(GPIOB_BASE+8)//0x40010C08

  #defineBITBAND_Addr(Addr,num)((volaTIleunsignedlong*)(0x42000000+32*(Addr-0x40000000)+4*num))

  #defineIPB13*BITBAND_Addr(GPIOB_IDR_Addr,13)

  #defineOPB13*BITBAND_Addr(GPIOB_ODR_Addr,13)

  #defineOPB14*BITBAND_Addr(GPIOB_ODR_Addr,14)

  #defineIPB15*BITBAND_Addr(GPIOB_IDR_Addr,15)

  启动IIC传输:

  void_iic_Start()

  {

  W_SCL=1;

  W_SDA=1;

  _delay();

  W_SDA=0;//SCL高时,拉低SDA,表示开始IIC传输,占用总线

  _delay();

  W_SCL=0;//控制SCL

  _delay();

  }

  停止IIC传输:

  void_iic_Stop()

  {

  W_SCL=1;//释放SCL(由于没有其他主器件,SCL无需开漏)

  W_SDA=0;

  发送一个字节:

  uint8_t_iic_SendByte(uint8_tdat)

  {

  uint8_TI;

  for(i=0;i《8;i++)

  {

  _delay();

  W_SDA=dat》》7;//SCL拉高之前写SDA

  dat=dat《《1;

  _delay();

  W_SCL=1;//拉高SCL,从器件开始读取SDA

  _delay();

  W_SCL=0;//重新拉低SCL

  }

  W_SDA=1;//释放SDA

  W_SCL=1;//拉高SCL,读取从器件应答信号

  //等待应答

  i=100;

  while(i&&R_SDA){i--;_delay();}

  if(i==0)//无应答

  {

  W_SCL=0;//重新拉低SCL

  return0;

  }

  else{//有应答

  _delay();

  W_SCL=0;//重新拉低SCL

  return1;

  }

  }

  _delay();

  W_SDA=1;//SCL为高时,拉高SDA表示结束ICC传输,释放总线

  }

  接收一个字节:

  uint8_t_iic_ReadByte(uint8_tAck)

  {

  uint8_ttemp,i;

  W_SDA=1;//释放SDA

  _delay();

  for(i=0;i《8;i++)

  {

  _delay();

  W_SCL=1;//拉高SCL开始读取SDA

  temp=temp《《1;

  temp|=R_SDA;//SCL拉高之后读取SDA

  W_SCL=0;//拉低SCL,从器件开始放置数据

  }

  //发送应答信号

  if(Ack)W_SDA=0;//拉低SDA表示应答

  W_SCL=1;//拉高SCL,从器件接收应答信号

  _delay();

  W_SCL=0;//重新拉低SCL

  W_SDA=1;//释放SDA

  returntemp;

  }


  二、配置HMC5883L模块

  voidHMC5883L_Init()

  {

  _iic_Start();

  _iic_SendByte(0x3c);//写操作

  _iic_SendByte(0x00);//指针指向00,配置寄存器A

  _iic_SendByte(0x78);//数据测量、输出速率75hz

  _iic_Start();//指针定位到02,模式寄存器

  _iic_SendByte(0x3c);

  _iic_SendByte(0x02);

  _iic_SendByte(0x00);//连续测量模式

  _iic_Stop();

  }

  三、读取角度数据

  接收三轴数据,处理X,Y轴的数据并计算角度:

  int16_tHMC5883L_ReadAngle()

  {

  staTIcuint8_TI;

  staticuint8_tXYZ_Data[6];//用来存储三个轴输出的数字量

  _iic_Start();

  _iic_SendByte(0x3c);//发送HMC5883L的器件地址0x3c,写操作

  _iic_SendByte(0x03);//指针指向03,Xmsb寄存器

  _iic_Start();

  _iic_SendByte(0x3d);//改为读操作

  //依次读取三个轴的数字量

  for(i=0;i《5;i++)//前5次读取发送应答信号

  {

  XYZ_Data[i]=_iic_ReadByte(1);

  }

  XYZ_Data[5]=_iic_ReadByte(0);//不应答

  _iic_Stop();

  returnatan2((double)((int16_t)((XYZ_Data[Ymsb]《《8)+XYZ_Data[Ylsb])),(double)((int16_t)((XYZ_Data[Xmsb]《《8)+XYZ_Data[Xlsb])))*(180/3.14159265)+180;//计算角度,需要包含math.h头文件

  }


  配置好IO口,调用HMC5883L_Init()后,便可调用HMC5883L_ReadAngle()读取角度值,0~360°。以下为测试时的截图:


  测试时,模块比较灵敏且精确,稍微旋转模块便有精确的变化。由于该模块是基于对地磁场的测量,此模块容易受到其他磁场的干扰,比如将该模块靠近直流电机时,便会因为电机内的磁场而降低精度甚至失灵(之前做智能小车时就遇到这个问题,要将电机内的磁场屏蔽起来才行)。

关键字:HMC5883L  数字罗盘  STM32 引用地址:基于STM32的三轴数字罗盘HMC5883L模块的测试方案

上一篇:2018年5月28日国际太阳能光伏展,福禄克与您不见不散
下一篇:中兴通讯成功地完成一款支持下行Cat-18终端的研发

推荐阅读最新更新时间:2024-03-30 23:36

STM32串口通信的重要性
刚开始学单片机的你,是不是会因用程序把LED点亮而感到高兴,会因用程序把数码管点亮而感到高兴。这是好事,这也是想继续学习下去的动力。 但是数据相关的实验是学习单片机和STM32的一道坎,此时就需要用好本文要说的串口这个调试工具。 串口通信介绍 关于串口通信的介绍,也可以点击阅读之前发的一篇文章。 STM32串口通信基本原理 串口通信是指外设和计算机间,通过数据信号线 、地线、控制线等,按位进行传输数据的一种通讯方式。..。..这种太过理论了,看似懂了,但又不懂。还是用我笔者自己的话来说吧。 串口通信就是可以把程序在单片机或者STM32芯片中运行的结果发送到电脑的一种通信方式。 如何使用串口通讯,你需要知道的几个重要的知识点
[单片机]
STM32 RTC设置日期失败(重启后生效)的解决方法
调试STM32F429的RTC时钟时遇到了如下问题: RTC设置日期时会延迟一段时间(几秒)或重启后才生效。 分析过程: 1、分析发现原程序在RTC的WAKEUP中断里读取时间和日期,后关闭此中断,在while循环中轮询读取,再设置日期,发现可以立即生效。所以猜测在WAKEUP中断里读取日期会对日期设置产生影响。 2、重新打开WAKEUP中断,并删除其中的日期读取函数,发现可以正常设置日期。 解决方法: 1、使用WAKEUP中断读取时间,轮询读取日期。 2、不使用WAKEUP中断,轮询读取时间和日期。
[单片机]
stm32启动方式+上(下)拉电阻 二合一
最近做stm32项目,纠结过其启动方式。 看到篇不错的文章,转载一下。原文格式不太好,内容也有很多奇怪的地方(尤其是第二篇,就先认为原文是原创,只是作者的思路我不懂吧),都一一删改。想看原文的朋友链接如下: http://www.ithao123.cn/content-3065243.html Duanxx的STM32学习: 启动模式,BOOT0和BOOT1详解 http://bluefish.blog.51cto.com/214870/1239098 上拉电阻与下拉电阻的作用 所谓启动,一般来说就是指我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存。用户可以通过设置BOOT1和BOOT0引脚的
[单片机]
STM32精确延迟1us和1ms的函数
延迟1us: 1 /***************************************************** 2 * 函 数 名 : delay_us 3 * 函数功能 : 延时函数,延时us 4 * 输 入 : i 5 * 输 出 : 无 6 *******************************************************************************/ 7 void delay_us(u32 i) 8 { 9 u32 temp; 10 SysTick-LOAD=
[单片机]
STM32开发板中如何点亮一个LCD
网络上配套STM32开发板有很多LCD例程,主要是TFT LCD跟OLED的。从这些例程,大家都能学会如何点亮一个LCD。但这代码都有下面问题: 分层不清晰,通俗讲就是模块化太差。 接口乱。只要接口不乱,分层就会好很多了。 可移植性差。 通用性差。 为什么这样说呢?如果你已经了解了LCD的操作,请思考如下情景: 1、代码空间不够,只能保留9341的驱动,其他LCD驱动全部删除。能一键(一个宏定义)删除吗?删除后要改多少地方才能编译通过? 2、有一个新产品,收银设备。系统有两个LCD,都是OLED,驱动IC相同,但是一个是128x64,另一个是128x32像素,一个叫做主显示,收银员用;一个叫顾显,顾客看金额。怎么办?这些例
[单片机]
STM32 USB学习笔记2
主机环境:Windows 7 SP1 开发环境:MDK5.14 目标板:STM32F103C8T6 开发库:STM32F1Cube库和STM32_USB_Device_Library STM32Cube库中提供了一些有关USB的例程,在其工程目录下的Applications目录中,这里打开STM3210E_EVAL目录,可以看到如下例程: 这里选取一个简单的例子CDC_Standalone,为一个USB通信例程,具体实现是一个USB转串口的功能,相当于USB串口线。把示例里面的inc和src目录下的文件拷贝到新建工程中,这里是把跟usb通信相关的文件放到了vcp目录下。文件目录结构如下:
[单片机]
<font color='red'>STM32</font> USB学习笔记2
一文全面掌握stm32的GPIO知识
1 初学者重要提示 本文主要是以stm32H7系列为主。 对于不使用的引脚,推荐设置为模拟模式,悬空即可。 GPIO的速度等级高的时候,最好使能IO补偿单元。 2 GPIO功能简介 STM32H7的GPIO特性如下: 输出状态:开漏/推挽 + 上拉/下拉电阻。 通过输出数据寄存器(GPIOx_ODR)或者外设(GPIO设置为复用模式时)输出数据。 GPIO速度等级设置。 输入状态:浮空,上拉/下拉,模拟。 通过输入数据寄存器(GPIOx_IDR)或者外设(GPIO设置为复用模式)输入数据。 通过寄存器GPIOx_BSRR实现对寄存器GPIOx_ODR的位操作。 通过配置寄存器GPIOx_LCKR的锁机制,实现冻结IO口配置。
[单片机]
一文全面掌握<font color='red'>stm32</font>的GPIO知识
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
最新测试测量文章
换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved