xaper 发表于 2012-7-31 21:29:46

HMC5883L读取数据问题

本帖最后由 xaper 于 2012-7-31 21:33 编辑

初始化:voidInit_HMC5883L(void)
{
        Single_Write(HMC5883L_Addr,0x00,0x14);   
        Single_Write(HMC5883L_Addr,0x02,0x00);   
}读取程序:
void read_hmc5883l(void)
{
        Single_Write(HMC5883L_Addr,0x00,0x14);
        Single_Write(HMC5883L_Addr,0x02,0x00);   
        delay5ms();
        BUF=Single_Read(HMC5883L_Addr,0x00);//OUT_X_L_A
        delay5ms();
        BUF=Single_Read(HMC5883L_Addr,0x03);//OUT_X_L_A
        delay5ms();
        BUF=Single_Read(HMC5883L_Addr,0x04);//OUT_X_H_A
        delay5ms();

        BUF=Single_Read(HMC5883L_Addr,0x07);//OUT_Y_L_A
        delay5ms();
        BUF=Single_Read(HMC5883L_Addr,0x08);//OUT_Y_H_A
        delay5ms();

        for(uint8 i=0;i<5;i++)
        {
                uart_send1(UART5,BUF);//串口输出寄存器的值
        }
        x=(BUF << 8) | BUF; //Combine MSB and LSB of X Data output register
        y=(BUF << 8) | BUF; //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器件连续测)。这是正常的吗?

js200300953 发表于 2012-7-31 21:56:26

本帖最后由 js200300953 于 2012-7-31 21:58 编辑

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

Name_006 发表于 2012-7-31 22:12:22

汗 你看下手册呗   那两个是初始化设置呀   没有设置初始化 肯定不行啊                                                            

xaper 发表于 2012-7-31 23:35:16

Name_006 发表于 2012-7-31 22:12 static/image/common/back.gif
汗 你看下手册呗   那两个是初始化设置呀   没有设置初始化 肯定不行啊                                 ...

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

xaper 发表于 2012-7-31 23:36:28

js200300953 发表于 2012-7-31 21:56 static/image/common/back.gif
Single_Write、Single_Read的细节也贴出来吧。

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

js200300953 发表于 2012-8-1 07:57:19

我初始化为:A=0b01111000,B=0b00000000,M=0b00000000。
然后不断读就可以了。

xaper 发表于 2012-8-1 10:47:02

js200300953 发表于 2012-8-1 07:57 static/image/common/back.gif
我初始化为:A=0b01111000,B=0b00000000,M=0b00000000。
然后不断读就可以了。

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

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

Name_006 发表于 2012-8-1 19:27:47

额你的意思是不是掉电重启啊掉电之后肯定不保存了   再重新配置才行啊                                 

xaper 发表于 2012-8-4 10:49:45

不知道为为什么,我在初始化前延时一会儿吗,后来就好了

xlong0628 发表于 2012-8-30 18:40:03

我的识别寄存器读出是对的,但是读数据寄存器一直变动,自测试也不准,这是咋回事????

绝对零度 发表于 2012-9-6 22:01:37

楼主是如何解决的?我也遇到同样问题!!

xaper 发表于 2012-9-12 19:52:04

绝对零度 发表于 2012-9-6 22:01 static/image/common/back.gif
楼主是如何解决的?我也遇到同样问题!!

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

天涯_1110 发表于 2012-9-18 17:47:32

xaper 发表于 2012-8-1 10:47 static/image/common/back.gif
奇怪,我按照你这样配置,数据还是不变。

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

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

Randy1022 发表于 2012-9-18 18:48:29

都需要先初始化再读的吧?

zzycgd 发表于 2012-11-7 11:08:36

{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}

COMPASSNAVHK 发表于 2012-11-8 11:08:52

xaper 发表于 2012-8-1 10:47 static/image/common/back.gif
奇怪,我按照你这样配置,数据还是不变。

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

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

COMPASSNAVHK 发表于 2012-11-8 11:09:38

xlong0628 发表于 2012-8-30 18:40 static/image/common/back.gif
我的识别寄存器读出是对的,但是读数据寄存器一直变动,自测试也不准,这是咋回事???? ...

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

dragondslj 发表于 2012-11-21 17:07:46

我用HMC5883L的X Y轴数据正常,Z轴数据总是0保持不变,求解释,xy都可以,为什么z不行呢???

number007cool 发表于 2012-11-22 14:29:58

这个片子怎么会有这么多的疑难杂症呢

COMPASSNAVHK 发表于 2012-12-14 17:16:36

dragondslj 发表于 2012-11-21 17:07 static/image/common/back.gif
我用HMC5883L的X Y轴数据正常,Z轴数据总是0保持不变,求解释,xy都可以,为什么z不行呢??? ...

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

rovershie 发表于 2013-1-1 17:24:33

这么多人看数据手册不认真阿!!!{:lol:}{:lol:}{:lol:} ,你回去看下数据手册LOCK位。我这里就不给搂住点透了。。。。。。

lijunyuan 发表于 2013-1-2 11:55:04

新手学习中!请问自己做一个,最低成本是多少呢?

NO_龙 发表于 2013-1-2 20:44:05

这个我也遇到了,今天认认真真看了手册。上电后要等65ms才可以正常工作。启动后I2C接口初始化,延时65ms在开始初始化模块。
但是我现在mpu6050一直读不到,同一个I2C啊,谁有解决方法啊?

zywei_09 发表于 2013-2-3 14:38:20

可能是楼上那个人说的原因吧,在没有把所有寄存器读出来的时候是锁定的。不过你BUF读0x00寄存器是什么意思,我依次从0x03读到0x08就没问题啊。

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

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

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

    M_X = Rec_Data<<8 | Rec_Data;//Combine MSB and LSB of X Data output register
    M_Z = Rec_Data<<8 | Rec_Data;//Combine MSB and LSB of Z Data output register
    M_Y = Rec_Data<<8 | Rec_Data;//Combine MSB and LSB of Y Data output register

}

qiguibao 发表于 2013-3-18 21:57:26

这个问题,解决办法:上电后,等待至少65ms,再进行初始化。

觋-拂晓 发表于 2013-3-20 12:12:20

本帖最后由 觋-拂晓 于 2013-3-20 12:14 编辑

qiguibao 发表于 2013-3-18 21:57 static/image/common/back.gif
这个问题,解决办法:上电后,等待至少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);//MRSingle-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);
        }
}

觋-拂晓 发表于 2013-3-20 12:18:27

zywei_09 发表于 2013-2-3 14:38 static/image/common/back.gif
可能是楼上那个人说的原因吧,在没有把所有寄存器读出来的时候是锁定的。不过你BUF读0x00寄存器是什么意 ...

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

xaper 发表于 2013-3-20 14:50:24

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

xaper 发表于 2013-3-20 14:50:53

觋-拂晓 发表于 2013-3-20 12:18 static/image/common/back.gif
为什么当我尝试读取数据寄存器的时候,RDY并没有清零。

见上。。。

觋-拂晓 发表于 2013-3-20 14:57:27

xaper 发表于 2013-3-20 14:50 static/image/common/back.gif
见上。。。

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

xaper 发表于 2013-3-20 15:05:19

觋-拂晓 发表于 2013-3-20 14:57 static/image/common/back.gif
但是读识别寄存器的时候读出来的数据没有错啊。。

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

觋-拂晓 发表于 2013-3-20 15:10:05

xaper 发表于 2013-3-20 15:05 static/image/common/back.gif
那你试试写某个设置寄存器,然后读出来,看看读取的值和你写的值是不是一样的 ...

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

jayzah 发表于 2013-3-27 11:58:10

mark
{:lol:}

xaper 发表于 2013-3-28 21:54:44

觋-拂晓 发表于 2013-3-20 15:10 static/image/common/back.gif
这个的确有点问题,不过当我写多几遍的话就没问题了。

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

觋-拂晓 发表于 2013-3-29 10:04:03

xaper 发表于 2013-3-28 21:54 static/image/common/back.gif
那还是不稳定,我开始也在这方面花了很长时间来改善I2C的数据读写效率,驱动这块一定得弄稳定了,就像房 ...

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

xaper 发表于 2013-3-29 14:56:57

觋-拂晓 发表于 2013-3-29 10:04 static/image/common/back.gif
avr xmega的硬件i2c该怎么使用啊,不知道有没有读写传感器的例子。模拟i2c的话看了比较多,差别都比较大 ...

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

东方云滨 发表于 2013-3-29 15:45:11

大家讨论的很激烈啊,受教了

戏子们月 发表于 2013-5-17 14:16:05

很受用!我就是碰到上电之后读取数据变慢,且断断续续的困扰,然后手动复位就好了。一直很奇怪!

junwugui 发表于 2013-5-21 15:29:28

又学习了!

mbwhy 发表于 2013-6-25 16:16:58

xaper 发表于 2012-9-12 19:52 static/image/common/back.gif
每次读取之前延时会儿就好了。

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

hfjydq 发表于 2014-4-14 09:41:10

Single_Write(HMC5883L_Addr,0x00,0x14);这句是设置速率为30HZ,也就是34ms左右输出一次

hfjydq 发表于 2014-4-14 09:44:34

js200300953 发表于 2012-8-1 07:57
我初始化为:A=0b01111000,B=0b00000000,M=0b00000000。
然后不断读就可以了。

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

hfjydq 发表于 2014-4-14 09:53:57

xaper 发表于 2013-3-29 14:56
这个我没用过,你仔细看单片机芯片手册上的时序图,还是时间参数,慢慢来,别急 ...

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

幽灵盾 发表于 2014-7-25 22:36:37

mark一下

SMC 发表于 2014-8-25 11:23:54

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

我跟你一样的问题,悲剧。
页: [1]
查看完整版本: HMC5883L读取数据问题