搜索
bottom↓
回复: 44

HMC5883L读取数据问题

[复制链接]

出0入0汤圆

发表于 2012-7-31 21:29:46 | 显示全部楼层 |阅读模式
本帖最后由 xaper 于 2012-7-31 21:33 编辑

初始化:
  1. void  Init_HMC5883L(void)
  2. {
  3.         Single_Write(HMC5883L_Addr,0x00,0x14);   
  4.         Single_Write(HMC5883L_Addr,0x02,0x00);   
  5. }
复制代码
读取程序:
void read_hmc5883l(void)
{
        Single_Write(HMC5883L_Addr,0x00,0x14);  
        Single_Write(HMC5883L_Addr,0x02,0x00);
   
        delay5ms();
        BUF[0]=Single_Read(HMC5883L_Addr,0x00);//OUT_X_L_A
        delay5ms();
        BUF[1]=Single_Read(HMC5883L_Addr,0x03);//OUT_X_L_A
        delay5ms();
        BUF[2]=Single_Read(HMC5883L_Addr,0x04);//OUT_X_H_A
        delay5ms();

        BUF[3]=Single_Read(HMC5883L_Addr,0x07);//OUT_Y_L_A
        delay5ms();
        BUF[4]=Single_Read(HMC5883L_Addr,0x08);//OUT_Y_H_A
        delay5ms();

        for(uint8 i=0;i<5;i++)
        {
                uart_send1(UART5,BUF);//串口输出寄存器的值
        }
        x=(BUF[1] << 8) | BUF[2]; //Combine MSB and LSB of X Data output register
        y=(BUF[3] << 8) | BUF[4]; //Combine MSB and LSB of Z Data output register

        if(x>0x7fff)x-=0xffff;          
        if(y>0x7fff)y-=0xffff;          
        angle= atan2(y,x) * (180 / 3.14159265) + 180; // angle in degrees
}
如果把红色部分去掉,无论器件怎么放,数据保持一个值不变;不过,改变位置后再重启就变一次。加上红色部分后,数据有变化了,但是感觉变化很迟钝(就是读取出很多次一样的,然后才变化,我是差不多40ms读一次,设置30ms器件连续测)。这是正常的吗?

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2012-7-31 21:56:26 | 显示全部楼层
本帖最后由 js200300953 于 2012-7-31 21:58 编辑

Single_Write、Single_Read的细节也贴出来吧。

出0入0汤圆

发表于 2012-7-31 22:12:22 | 显示全部楼层
汗 你看下手册呗   那两个是初始化设置呀   没有设置初始化 肯定不行啊                                                            

出0入0汤圆

 楼主| 发表于 2012-7-31 23:35:16 | 显示全部楼层
Name_006 发表于 2012-7-31 22:12
汗 你看下手册呗   那两个是初始化设置呀   没有设置初始化 肯定不行啊                                   ...

手册看了呀,设置连续模式应该就可以有变化的数据读出啊。我在程序里有初始化啊,但是不知道为什么要每次初始化,数据才会变化。大家都是怎么配置的啊?

出0入0汤圆

 楼主| 发表于 2012-7-31 23:36:28 | 显示全部楼层
js200300953 发表于 2012-7-31 21:56
Single_Write、Single_Read的细节也贴出来吧。

Single_Write、Single_Read就是分别对某个寄存器进行写或读。

出0入0汤圆

发表于 2012-8-1 07:57:19 | 显示全部楼层
我初始化为:A=0b01111000,B=0b00000000,M=0b00000000。
然后不断读就可以了。

出0入0汤圆

 楼主| 发表于 2012-8-1 10:47:02 | 显示全部楼层
js200300953 发表于 2012-8-1 07:57
我初始化为:A=0b01111000,B=0b00000000,M=0b00000000。
然后不断读就可以了。

奇怪,我按照你这样配置,数据还是不变。

如下图,每行前三个字节和最后三个字节是读取寄存器0x00,0x01,0x02的值


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-8-1 19:27:47 | 显示全部楼层
额  你的意思是不是掉电重启啊  掉电之后肯定不保存了   再重新配置才行啊                                   

出0入0汤圆

 楼主| 发表于 2012-8-4 10:49:45 | 显示全部楼层
不知道为为什么,我在初始化前延时一会儿吗,后来就好了

出0入0汤圆

发表于 2012-8-30 18:40:03 | 显示全部楼层
我的识别寄存器读出是对的,但是读数据寄存器一直变动,自测试也不准,这是咋回事????

出0入0汤圆

发表于 2012-9-6 22:01:37 | 显示全部楼层
楼主是如何解决的?  我也遇到同样问题!!

出0入0汤圆

 楼主| 发表于 2012-9-12 19:52:04 | 显示全部楼层
绝对零度 发表于 2012-9-6 22:01
楼主是如何解决的?  我也遇到同样问题!!

每次读取之前延时会儿就好了。

出0入0汤圆

发表于 2012-9-18 17:47:32 | 显示全部楼层
xaper 发表于 2012-8-1 10:47
奇怪,我按照你这样配置,数据还是不变。

如下图,每行前三个字节和最后三个字节是读取寄存器0x00,0x01, ...

MDK软件有界面显示数据的功能么? 你用的哪个软件显示传感器数据的?

出0入0汤圆

发表于 2012-9-18 18:48:29 | 显示全部楼层
都需要先初始化再读的吧?

出0入0汤圆

发表于 2012-11-7 11:08:36 | 显示全部楼层

出0入0汤圆

发表于 2012-11-8 11:08:52 | 显示全部楼层
xaper 发表于 2012-8-1 10:47
奇怪,我按照你这样配置,数据还是不变。

如下图,每行前三个字节和最后三个字节是读取寄存器0x00,0x01, ...

0x00设置为71,而后面的对于0x01设置为00;
其为正偏置的测试,内部产生的磁场大小是1.06Gauss;
而你所设置0x01为00,则量程只有0.88Gauss;

出0入0汤圆

发表于 2012-11-8 11:09:38 | 显示全部楼层
xlong0628 发表于 2012-8-30 18:40
我的识别寄存器读出是对的,但是读数据寄存器一直变动,自测试也不准,这是咋回事???? ...

C1&C2电容上可以先去考虑一下

出0入0汤圆

发表于 2012-11-21 17:07:46 | 显示全部楼层
我用HMC5883L的X Y轴数据正常,Z轴数据总是0保持不变,求解释,xy都可以,为什么z不行呢???

出0入0汤圆

发表于 2012-11-22 14:29:58 | 显示全部楼层
这个片子怎么会有这么多的疑难杂症呢

出0入0汤圆

发表于 2012-12-14 17:16:36 | 显示全部楼层
dragondslj 发表于 2012-11-21 17:07
我用HMC5883L的X Y轴数据正常,Z轴数据总是0保持不变,求解释,xy都可以,为什么z不行呢??? ...

手工焊接的么?
配置一下其内置的self-test一下,看读数的情况怎么样;
我怀疑你的Z axis损坏了

出0入0汤圆

发表于 2013-1-1 17:24:33 | 显示全部楼层
这么多人看数据手册不认真阿!!! ,你回去看下数据手册LOCK位。我这里就不给搂住点透了。。。。。。

出0入0汤圆

发表于 2013-1-2 11:55:04 | 显示全部楼层
新手学习中!请问自己做一个,最低成本是多少呢?

出0入0汤圆

发表于 2013-1-2 20:44:05 | 显示全部楼层
这个我也遇到了,今天认认真真看了手册。上电后要等65ms才可以正常工作。启动后I2C接口初始化,延时65ms在开始初始化模块。
但是我现在mpu6050一直读不到,同一个I2C啊,谁有解决方法啊?

出0入0汤圆

发表于 2013-2-3 14:38:20 | 显示全部楼层
可能是楼上那个人说的原因吧,在没有把所有寄存器读出来的时候是锁定的。不过你BUF[0]读0x00寄存器是什么意思,我依次从0x03读到0x08就没问题啊。

这个是状态寄存器 LOCK 位的说明:
数据输出寄存器锁存。当六个数据输出寄存器上的一些但不是全部数据被读取时,该位置位。当此位置位时,六个数据输出寄存器被锁定且任何新的数据将不会被更新至这些寄存器中,除非符合以下三个条件之一: 一,所有6个寄存器已被读取或模式改变,二,模式发生变化,三,测量配置发生变化。

这是我的读取函数
/*
********************************************************************************
** 函数名称 : void Multiple_Read_HMC5883(void)
** 函数功能 : 连续读取HMC5883L寄存器
** 输    入        : 无
** 输    出        : 无
** 返    回        : 无
********************************************************************************
*/
void Multiple_Read_HMC5883(void)
{
    uchar i;  //连续读出HMC5883内部角度数据,地址范围0x3~0x5
        short Rec_Data[6]; //存放寄存器值数组

        for(i=0;i<6;i++)
          Rec_Data[i]=Single_Read(MAG_ADDRESS,i+3);

    M_X = Rec_Data[0]<<8 | Rec_Data[1];//Combine MSB and LSB of X Data output register
    M_Z = Rec_Data[2]<<8 | Rec_Data[3];//Combine MSB and LSB of Z Data output register
    M_Y = Rec_Data[4]<<8 | Rec_Data[5];//Combine MSB and LSB of Y Data output register

}

出0入0汤圆

发表于 2013-3-18 21:57:26 | 显示全部楼层
这个问题,解决办法:上电后,等待至少65ms,再进行初始化。

出0入0汤圆

发表于 2013-3-20 12:12:20 | 显示全部楼层
本帖最后由 觋-拂晓 于 2013-3-20 12:14 编辑
qiguibao 发表于 2013-3-18 21:57
这个问题,解决办法:上电后,等待至少65ms,再进行初始化。


       你好,我读取数据的时候发现几个问题。1、数据一直是负数。2、不论怎么转动y轴的数据变化都不大。3、z轴的数据不稳定,经常会跳到-4096。但是读 H 4 3确很正常。下面是我的代码:
hmc5883l.h
#ifndef HMC5883L_H_
#define HMC5883L_H_
#define HMC5883L_TWI_ADDR 0x3C //(0x1e<<1)
#define ID_A_DEFAULT            (0x48)  /* normal value of ID register A */
#define ID_B_DEFAULT            (0x34)  /* normal value of ID register B */
#define ID_C_DEFAULT            (0x33)  /* normal value of ID register C */
#define HMC5883L_CONFIG_REG_A   (0x00)  /* configuration register A */
#define HMC5883L_CONFIG_REG_B   (0x01)  /* configuration register B */
#define HMC5883L_MODE_REG       (0x02)  /* mode register */
#define HMC5883L_MAG_X_HI       (0x03)  /* X mag reading - MSB */
#define HMC5883L_MAG_X_LO       (0x04)  /* X mag reading - LSB */
#define HMC5883L_MAG_Z_HI       (0x05)  /* Z mag reading - MSB */
#define HMC5883L_MAG_Z_LO       (0x06)  /* Z mag reading - LSB */
#define HMC5883L_MAG_Y_HI       (0x07)  /* Y mag reading - MSB */
#define HMC5883L_MAG_Y_LO       (0x08)  /* Y mag reading - LSB */
#define HMC5883L_STATUS_REG     (0x09)  /* device status */
#define HMC5883L_ID_REG_A       (0x0a)  /* ID register A */
#define HMC5883L_ID_REG_B       (0x0b)  /* ID register B */
#define HMC5883L_ID_REG_C       (0x0c)  /* ID register C */
#endif /* HMC5883L_H_ */

#include <stdio.h>
#include "hmc5883l.h"
#include "twi.h"
#include "Usart.h"
uint8_t ReadHmc5883l(uint8_t regAddr)
{
        //To be able to access registers in read mode, first address has to be send in write mode.
        uint8_t temp=0;
        IIC_Start();
        IIC_Send_Byte(HMC5883L_TWI_ADDR);    //write
        IIC_Wait_Ack();
        IIC_Send_Byte(regAddr);//reg
        IIC_Wait_Ack();
        IIC_Start();
        IIC_Send_Byte(HMC5883L_TWI_ADDR+1);           // read
        IIC_Wait_Ack();
        temp=IIC_Recv_Byte();
        IIC_NAck();
        IIC_Stop();
        return temp;
}
void WriteHmc5883l(uint8_t regAddr,uint8_t DataToWrite)
{
        IIC_Start();
        IIC_Send_Byte(HMC5883L_TWI_ADDR);     //write
        IIC_Wait_Ack();
        IIC_Send_Byte(regAddr);//reg
        IIC_Wait_Ack();
        IIC_Send_Byte(DataToWrite);     // data
        IIC_Wait_Ack();
        IIC_Stop();
}
void hmc5883l_Init()
{
        PORTF_PIN0CTRL=PORTF_PIN1CTRL=PORT_OPC_WIREDANDPULL_gc;//using "wire-and pull up" because of electronic character
        _delay_ms(70);
        WriteHmc5883l(HMC5883L_CONFIG_REG_A,0x70);//CRA
        WriteHmc5883l(HMC5883L_CONFIG_REG_B,0x40);//CRB
        WriteHmc5883l(HMC5883L_MODE_REG,0x01);//MR  Single-Measurement Mode

}
int16_t hmc5883l_getAxis(uint8_t reg)
{
        char msb,lsb;
        msb = ReadHmc5883l(reg);
        lsb = ReadHmc5883l(reg+1);
        return ((msb<<8) | lsb);
}
int main(void)
{
        stdout = &mystdout;
        UsartInit();
        hmc5883l_Init();
        while (1)
        {
                while (!(ReadHmc5883l(HMC5883L_STATUS_REG)&0x01));//wait for data ready
                printf("x axis:%d\r\n",hmc5883l_getAxis(HMC5883L_MAG_X_HI));
                printf("y axis:%d\r\n",hmc5883l_getAxis(HMC5883L_MAG_Y_HI));
                printf("z axis:%d\r\n",hmc5883l_getAxis(HMC5883L_MAG_Z_HI));
                WriteHmc5883l(HMC5883L_MODE_REG,0x01);//Single-Measurement Mode
                _delay_ms(1000);
        }
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-3-20 12:18:27 | 显示全部楼层
zywei_09 发表于 2013-2-3 14:38
可能是楼上那个人说的原因吧,在没有把所有寄存器读出来的时候是锁定的。不过你BUF[0]读0x00寄存器是什么意 ...

为什么当我尝试读取数据寄存器的时候,RDY并没有清零。

出0入0汤圆

 楼主| 发表于 2013-3-20 14:50:24 | 显示全部楼层
其实,我觉得读书不正常,大部分原因是自己的读取数据时序问题,说白了,就是没有遵从IIC总线协议,这个只要读的过程中,时序错了一点,就会出问题,我也在这方面花了很长时间才弄完美,再接再厉!
其实最偷懒的方法,就是用常见的单片机,这样人家都弄好驱动程序了,你拿来用就行了,否则就得自己花时间移植

出0入0汤圆

 楼主| 发表于 2013-3-20 14:50:53 | 显示全部楼层
觋-拂晓 发表于 2013-3-20 12:18
为什么当我尝试读取数据寄存器的时候,RDY并没有清零。

见上。。。

出0入0汤圆

发表于 2013-3-20 14:57:27 | 显示全部楼层
xaper 发表于 2013-3-20 14:50
见上。。。

但是读识别寄存器的时候读出来的数据没有错啊。。

出0入0汤圆

 楼主| 发表于 2013-3-20 15:05:19 | 显示全部楼层
觋-拂晓 发表于 2013-3-20 14:57
但是读识别寄存器的时候读出来的数据没有错啊。。

那你试试写某个设置寄存器,然后读出来,看看读取的值和你写的值是不是一样的

出0入0汤圆

发表于 2013-3-20 15:10:05 | 显示全部楼层
xaper 发表于 2013-3-20 15:05
那你试试写某个设置寄存器,然后读出来,看看读取的值和你写的值是不是一样的 ...

这个的确有点问题,不过当我写多几遍的话就没问题了。

出0入0汤圆

发表于 2013-3-27 11:58:10 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2013-3-28 21:54:44 | 显示全部楼层
觋-拂晓 发表于 2013-3-20 15:10
这个的确有点问题,不过当我写多几遍的话就没问题了。

那还是不稳定,我开始也在这方面花了很长时间来改善I2C的数据读写效率,驱动这块一定得弄稳定了,就像房子的地基。

出0入0汤圆

发表于 2013-3-29 10:04:03 | 显示全部楼层
xaper 发表于 2013-3-28 21:54
那还是不稳定,我开始也在这方面花了很长时间来改善I2C的数据读写效率,驱动这块一定得弄稳定了,就像房 ...

avr xmega的硬件i2c该怎么使用啊,不知道有没有读写传感器的例子。模拟i2c的话看了比较多,差别都比较大,切换SDA和SCL电平时延时都不同,这会有影响吗。

出0入0汤圆

 楼主| 发表于 2013-3-29 14:56:57 | 显示全部楼层
觋-拂晓 发表于 2013-3-29 10:04
avr xmega的硬件i2c该怎么使用啊,不知道有没有读写传感器的例子。模拟i2c的话看了比较多,差别都比较大 ...

这个我没用过,你仔细看单片机芯片手册上的时序图,还是时间参数,慢慢来,别急

出0入0汤圆

发表于 2013-3-29 15:45:11 | 显示全部楼层
大家讨论的很激烈啊,受教了

出0入0汤圆

发表于 2013-5-17 14:16:05 | 显示全部楼层
很受用!我就是碰到上电之后读取数据变慢,且断断续续的困扰,然后手动复位就好了。一直很奇怪!

出0入0汤圆

发表于 2013-5-21 15:29:28 | 显示全部楼层
又学习了!

出0入0汤圆

发表于 2013-6-25 16:16:58 | 显示全部楼层
xaper 发表于 2012-9-12 19:52
每次读取之前延时会儿就好了。

楼主能把程勋贴出来吗?我的加延时读数也不变。。

出0入0汤圆

发表于 2014-4-14 09:41:10 | 显示全部楼层
Single_Write(HMC5883L_Addr,0x00,0x14);  这句是设置速率为30HZ,也就是34ms左右输出一次

出0入0汤圆

发表于 2014-4-14 09:44:34 | 显示全部楼层
js200300953 发表于 2012-8-1 07:57
我初始化为:A=0b01111000,B=0b00000000,M=0b00000000。
然后不断读就可以了。

你这是设置在连续测量模式下,输出速率是连续测量模式的最大输出速率:75HZ

出0入0汤圆

发表于 2014-4-14 09:53:57 | 显示全部楼层
xaper 发表于 2013-3-29 14:56
这个我没用过,你仔细看单片机芯片手册上的时序图,还是时间参数,慢慢来,别急 ...

楼主读出的数据怎么处理的?把处理部分的函数贴出来呀

出0入0汤圆

发表于 2014-7-25 22:36:37 | 显示全部楼层
mark一下

出0入0汤圆

发表于 2014-8-25 11:23:54 | 显示全部楼层
xlong0628 发表于 2012-8-30 18:40
我的识别寄存器读出是对的,但是读数据寄存器一直变动,自测试也不准,这是咋回事???? ...

我跟你一样的问题,悲剧。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 17:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表