最近需要使用磁传感器,之前使用的是HMC5883,不过这次买的是LSM303D,记录一下。使用的单片机是STM32F407,模拟iic,正点原子的库。 数据手册参考的是:https://item.szlcsc.com/2776949.html 代码参考的是:https://blog.csdn.net/cp1300/article/details/75644988 修改的代码如下
#include "lsm303.h"
#include "delay.h"
#include "usart.h"
#include "myiic.h"
#define SlaveAddr_A 0x32
#define SlaveAddr_M 0x3C
u8 LSM303DLH_Init()
{
u8 temp;
u8 retry = 0;
IIC_Init();
for(retry = 0;retry < 3;retry ++)
{
LSM303DLH_WriteOneReg(LSM303_CTRL_REG1_A_0x20, 0x27);
delay_ms(3);
temp = LSM303DLH_ReadOneReg(LSM303_CTRL_REG1_A_0x20);
if(temp != 0x27)
{
printf("初始化失败,LSM303_CTRL_REG1_A_0x20默认值错误:0x%02X\r\n", temp);
delay_ms(10);
}
else break;
}
if(temp != 0x27)
{
return FALSE;
}
delay_ms(1);
for(retry = 0;retry < 3;retry ++)
{
LSM303DLH_WriteOneReg(LSM303_CRA_REG_M_0x00, 0x30);
delay_ms(1);
LSM303DLH_WriteOneReg(LSM303_CRB_REG_M_0x01, 0xE0);
delay_ms(1);
LSM303DLH_WriteOneReg(LSM303_MR_REG_M_0x02, 0x00);
delay_ms(1);
temp = LSM303DLH_ReadOneReg(LSM303_MR_REG_M_0x02);
if(temp != 0)
{
printf("初始化失败,LSM303_MR_REG_M_0x02值错误:0x%02X\r\n", temp);
delay_ms(10);
}
else break;
}
return TRUE;
}
u8 LSM303DLH_ReadOneReg(LSM303DLH_REG_TYPE RegAddr)
{
u8 data;
u8 SlaveAddr = (RegAddr>0x19)?SlaveAddr_A:SlaveAddr_M;
IIC_Start();
IIC_Send_Byte(SlaveAddr);
IIC_Wait_Ack();
IIC_Send_Byte(RegAddr);
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(SlaveAddr+1);
IIC_Wait_Ack();
data = IIC_Read_Byte(0);
IIC_Stop();
return data;
}
void LSM303DLH_ReadMultReg(LSM303DLH_REG_TYPE RegAddr, u8 RegNum, u8 DataBuff[])
{
u8 i;
u8 SlaveAddr = (RegAddr>0x19)?SlaveAddr_A:SlaveAddr_M;
IIC_Start();
IIC_Send_Byte(SlaveAddr);
IIC_Wait_Ack();
IIC_Send_Byte(RegAddr);
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(SlaveAddr+1);
IIC_Wait_Ack();
for(i = 0;i < RegNum;i ++)
{
if(i == (RegNum-1))
{
DataBuff[i] = IIC_Read_Byte(FALSE);
}
else
{
DataBuff[i] = IIC_Read_Byte(TRUE);
}
}
IIC_Stop();
}
void LSM303DLH_WriteOneReg(LSM303DLH_REG_TYPE RegAddr,u8 data)
{
u8 SlaveAddr = (RegAddr>0x19)?SlaveAddr_A:SlaveAddr_M;
IIC_Start();
IIC_Send_Byte(SlaveAddr);
IIC_Wait_Ack();
IIC_Send_Byte(RegAddr);
IIC_Wait_Ack();
IIC_Send_Byte(data);
IIC_Wait_Ack();
IIC_Stop();
}
u8 LSM303DLH_ReadMagnetic(M_Data *p_lsm303d)
{
u8 buff[6];
s16 temp;
LSM303DLH_ReadMultReg(LSM303_OUT_X_H_M_0x03, 6, buff);
temp = buff[0];
temp<<=8;
temp|= buff[1];
p_lsm303d->x_m = temp;
temp = buff[2];
temp<<=8;
temp|= buff[3];
p_lsm303d->z_m = temp;
temp = buff[4];
temp<<=8;
temp|= buff[5];
p_lsm303d->y_m = temp;
printf("x = %f, y = %f, z = %f\r\n", p_lsm303d->x_m, p_lsm303d->y_m, p_lsm303d->z_m);
return TRUE;
}
#ifndef __LSM303_H
#define __LSM303_H
#include "sys.h"
typedef enum
{
LSM303_CRA_REG_M_0x00 = 0x00,
LSM303_CRB_REG_M_0x01 = 0x01,
LSM303_MR_REG_M_0x02 = 0x02,
LSM303_OUT_X_H_M_0x03 = 0x03,
LSM303_OUT_X_L_M_0x04 = 0x04,
LSM303_OUT_Y_H_M_0x05 = 0x05,
LSM303_OUT_Y_L_M_0x06 = 0x06,
LSM303_OUT_Z_H_M_0x07 = 0x07,
LSM303_OUT_Z_L_M_0x08 = 0x08,
LSM303_SR_REG_Mg_0x09 = 0x09,
LSM303_IRA_REG_M_0x0A = 0x0A,
LSM303_IRB_REG_M_0x0B = 0x0B,
LSM303_IRC_REG_M_0x0C = 0x0C,
LSM303_CTRL_REG1_A_0x20 = 0x20,
LSM303_CTRL_REG2_A_0x21 = 0x21,
LSM303_CTRL_REG3_A_0x22 = 0x22,
LSM303_CTRL_REG4_A_0x23 = 0x23,
LSM303_CTRL_REG5_A_0x24 = 0x24,
LSM303_HP_FILTER_RESET_A_0x25 = 0x25,
LSM303_REFERENCE_A_0x26 = 0x26,
LSM303_STATUS_REG_A_0x27 = 0x27,
LSM303_OUT_X_L_A_0x28 = 0x28,
LSM303_OUT_X_H_A_0x29 = 0x29,
LSM303_OUT_Y_L_A_0x2A = 0x2A,
LSM303_OUT_Y_H_A_0x2B = 0x2B,
LSM303_OUT_Z_L_A_0x2C = 0x2C,
LSM303_OUT_Z_H_A_0x2D = 0x2D,
LSM303_INT1_CFG_A_0x30 = 0x30,
LSM303_INT1_SOURCE_A_0x31 = 0x31,
LSM303_INT1_THS_A_0x32 = 0x32,
LSM303_INT1_DURATION_A_0x33 = 0x33,
LSM303_INT2_CFG_A_0x34 = 0x34,
LSM303_INT2_SOURCE_A_0x35 = 0x35,
LSM303_INT2_THS_A_0x36 = 0x36,
LSM303_INT2_DURATION_A_0x37 = 0x37,
}LSM303DLH_REG_TYPE;
typedef struct
{
s16 x_m, y_m, z_m;
float x_gs, y_gs, z_gs;
}M_Data;
u8 LSM303DLH_Init(void);
u8 LSM303DLH_ReadMagnetic(M_Data *p_lsm303d);
#endif
|