资讯详情

HMC5883l磁力计数据读取

1.数据手册地址 2.芯片介绍

  1. 设备7位地址为0x1e,读地址为0x3d,写地址为0x3c。如图 图1 2.主要有三个寄存器需要配置。分别配置寄存器A(0x配置寄存器B(0x模型寄存器(001)x03)

    1. 配置寄存器A(0x00)用于配置设置的数据输出速率和测量配置. 需要注意的是: 要设为0。 设置采样平均数。 用于设置输出速率。 用于设置测量模式。 具体配置参数如图所示 2.配置寄存器B(0x01) 用于配置测量范围。 要设为0。

3.模式寄存器(0x03) 要设为0 设置测量模式。

测试代码如下: //i2c.c

//i2c.c  #include "stm32f4xx_hal.h" #include "iic.h"  void i2c_init(void) { 
          GPIO_InitTypeDef GPIO_InitStruct = { 
       0};   GPIO_InitStruct.Pin =  I2C_SCL_Pin;   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;   GPIO_InitStruct.Pull = GPIO_NOPULL;   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;   HAL_GPIO_Init(I2C_PORT, &GPIO_InitStruct);  }   void SDA_INPUT(void) { 
           GPIO_InitTypeDef GPIO_InitStruct = { 
       0};   GPIO_InitStruct.Pin =  I2C_SDA_Pin;   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;   GPIO_InitStruct.Pull = GPIO_NOPULL;   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(I2C_PORT, &GPIO_InitStruct);
}
 

void SDA_OUTPUT(void)
{ 
       

  GPIO_InitTypeDef GPIO_InitStruct = { 
       0};
  GPIO_InitStruct.Pin =  I2C_SDA_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(I2C_PORT, &GPIO_InitStruct);
	
}
 
 
void i2c_Delay(void)
{ 
       
	uint8_t i;
	for (i = 0; i < 50; i++);
}
 

void delay_us(uint16_t time)
{ 
       
	uint16_t i;
	
	
	for (i = 0 ; i < time ; i++)
	{ 
       
		__NOP();
		__NOP();
		__NOP();
		__NOP();
		__NOP();
		__NOP();
		__NOP();
		__NOP();
		__NOP();
		__NOP();
		__NOP();
		__NOP();
		__NOP();
		__NOP();
		__NOP();
		__NOP();
	}
	
}
 
void delay_ms(uint8_t time)
{ 
       
	uint8_t i;
	
	for (i = 0 ; i < 10 * time ; i++)
	{ 
       
		delay_us(255);
		delay_us(255);
		delay_us(200);		
	}
}
 
 
void i2c_Start(void)
{ 
       
		
	SDA_OUTPUT();
	I2C_SDA_1();	
	delay_us(20);	
	I2C_SCL_1();
	delay_us(50);	
	I2C_SDA_0();	
	delay_us(50);	
	I2C_SCL_0();	
	delay_us(10);
}
 
 
void i2c_Stop(void)
{ 
       
	
	SDA_OUTPUT();
	I2C_SDA_0();	//STOP:when CLK is high DATA change form low to high
	delay_us(20);	
	I2C_SCL_1();
	delay_us(50);
	I2C_SDA_1();
	delay_us(30);
}
 
 
void i2c_Ack(void)
{ 
       
	SDA_OUTPUT();
	I2C_SDA_0();	
	delay_us(20);
 
	I2C_SCL_1();	
	delay_us(50);
	I2C_SCL_0();	
	delay_us(10);
}
 
 
void i2c_NoAck(void)
{ 
       
	SDA_OUTPUT();
	I2C_SDA_1();	
	delay_us(20);
	
	I2C_SCL_1();	
	delay_us(50);
	I2C_SCL_0();	
	delay_us(10);
}
 
 
bool i2c_WaitAck(void)
{ 
       
	uint8_t ucErrTime = 0x00;
 
	
	SDA_INPUT();	
	I2C_SDA_1();
	delay_us(30);
	
	I2C_SCL_1();	
	delay_us(30);	
		
	while (I2C_SDA_READ())
	{ 
       
		ucErrTime++;
		if (ucErrTime > 250)
		{ 
       
			I2C_SCL_0();
			delay_us(30);
			i2c_Stop();
			return (FALSE);
		}
	}
	I2C_SCL_0();
	delay_us(30);		
	return (TRUE);
}
 

void i2c_SendByte(uint8_t _ucByte)
{ 
       
	uint8_t i;
 
	
	SDA_OUTPUT();

	for (i = 0; i < 8; i++)
	{ 
       		
		if (_ucByte & 0x80)
			I2C_SDA_1();
		else
			I2C_SDA_0();
 
		_ucByte <<= 1;	
		
		delay_us(10);		
		I2C_SCL_1();
		delay_us(30);
		I2C_SCL_0();
		delay_us(10);
	}
}
 
uint8_t i2c_ReadByte(void)
{ 
       
	uint8_t i;
	uint8_t value = 0x00;
 
	
	for (i = 0; i < 8; i++)
	{ 
       
		SDA_OUTPUT();
		I2C_SDA_1();		
		delay_us(20);
		
		I2C_SCL_1();	
		delay_us(50);

		SDA_INPUT();
		value <<= 1;

		if (I2C_SDA_READ())
			value++;

		I2C_SCL_0();	 
		delay_us(10);
	}
	return (value);
}

//i2c.h

#ifndef _iic_h
#define _iic_h
#include "struct.h"

//i2c.h


#include "gpio.h"
#include "stm32f4xx_hal.h"
#include "stdint.h"


//#define I2C_PORT GPIOA
//#define I2C_SCL_Pin GPIO_PIN_13
//#define I2C_SDA_Pin GPIO_PIN_14


#define I2C_PORT GPIOA //硬件接口定义
#define I2C_SCL_Pin GPIO_PIN_9
#define I2C_SDA_Pin GPIO_PIN_10

 
#define I2C_SCL_1() I2C_PORT->BSRR = I2C_SCL_Pin // SCL = 1 
#define I2C_SCL_0() I2C_PORT->BSRR = (uint32_t)I2C_SCL_Pin << 16U // SCL = 0 
#define I2C_SDA_1() I2C_PORT->BSRR = I2C_SDA_Pin // SDA = 1 
#define I2C_SDA_0() I2C_PORT->BSRR = (uint32_t)I2C_SDA_Pin << 16U // SDA = 0 
#define I2C_SDA_READ() (I2C_PORT->IDR & I2C_SDA_Pin) //读取SDA
							


void i2c_init(void);
void delay_us(uint16_t time);
void delay_ms(uint8_t time);
void i2c_Start(void);
void i2c_Stop(void);
void i2c_Ack(void);
void i2c_NoAck(void);
bool i2c_WaitAck(void);
void i2c_SendByte(uint8_t _ucByte);
uint8_t i2c_ReadByte(void);


#endif

// hmc5883l.c

#include "hmc5883l.h"

void HMC5883L_Init(void)
{ 
       

    i2c_Start();
    i2c_SendByte(0x3c); 
    i2c_WaitAck();
    i2c_SendByte(0x00);
    i2c_WaitAck();
    i2c_SendByte(0x58);  //输出速率75hz
    i2c_Stop();

    i2c_Start();
    i2c_SendByte(0x3c); //写指令
    i2c_WaitAck();
    i2c_SendByte(0x01);
    i2c_WaitAck();
    i2c_SendByte(0x60); //测量范围
    i2c_WaitAck();
    i2c_Stop();

    i2c_Start();
    i2c_SendByte(0x3c); //写指令
    i2c_WaitAck();
    i2c_SendByte(0x02);
    i2c_WaitAck();
    i2c_SendByte(0x00); //连续测量模式
    i2c_WaitAck();
    i2c_Stop();

}

void HMC5883L_READ(int16_t *x,int16_t *y)
{ 
        
    uint8_t XYZ_Data[6]={ 
       0};

    i2c_Start();
    i2c_SendByte(0x3c); 
    i2c_WaitAck(); 
    i2c_SendByte(0x03);  //X轴数据地址
    i2c_WaitAck(); 
    i2c_Stop();

    i2c_Start();          
    i2c_SendByte(0x3d); 
    i2c_WaitAck();
    
    for(uint8_t i=0;i<5;i++)     
    { 
       
    XYZ_Data[i]=i2c_ReadByte();
    i2c_Ack();
    }

    XYZ_Data[5] =i2c_ReadByte();  
    i2c_NoAck();
    i2c_Stop();

    *x = (int16_t)(XYZ_Data[0]<<8)|XYZ_Data[1];
    *y = (int16_t)(XYZ_Data[4]<<8)|XYZ_Data[5];
 
}


#ifndef _hmc5883l_h_
#define _hmc5883l_h_

#include "iic.h"
void HMC5883L_Init(void);
void HMC5883L_READ(int16_t *x,int16_t *y);
#endif

测试图

void main(){ 
       
  int16_t X_HM,Y_HM;
  i2c_init();
  HMC5883L_Init();   //磁力计
  while(1)
  { 
       
    osDelay(30);
	HMC5883L_READ(&X_HM,&Y_HM);
	printf("%d,%d\r\n",X_HM,Y_HM);
  }
}

可以利用公式计算角度:

Angle = (atan2(Y,X) * (180 / 3.14159265) + 180);

标签: 传感器hmc5883l

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

 锐单商城 - 一站式电子元器件采购平台  

 深圳锐单电子有限公司