LIS2MDL磁力计驱动

不问归期 提交于 2020-01-24 23:46:20

  之前使用STM32的硬件IIC(基于HAL库)调试了ST的LIS2MDL磁力计,现将写的驱动文件记录下来,并分享给有需要的同学。

/*
***********************************************************************************************
*                                       LIS2MDL磁力计驱动
*
*                                      实现LIS2MDL底层驱动
*
* Filename : LIS2MDL.c
* Version : V1.00
* Programmer(s) : FengDuo
*
***********************************************************************************************
*/
#define LIS2MDL_MOUDLE
//文件声明
/*
***********************************************************************************************
*                                         INCLUDE FILES
***********************************************************************************************
*/
#include "includes.h"
/*
***********************************************************************************************
*                                         LOCAL DEFINES
***********************************************************************************************
*/
static LIS2MDL_SAMPLE_DEF       LIS2MDLSample;
/*
***********************************************************************************************
*                                   LOCAL FUNCTION PROTOTYPES
***********************************************************************************************
*/
static void         LIS2MDL_IOInit(void);
static CPU_INT08U   LIS2MDL_Register_Read(CPU_INT08U addr);
static void         LIS2MDL_Register_Write(CPU_INT08U addr,CPU_INT08U val);
static void         LIS2MDL_Read_XYZ(CPU_INT16S *x,CPU_INT16S *y,CPU_INT16S *z);
static void         LIS2MDL_Read_Offset(CPU_INT16S *x_offset,CPU_INT16S *y_offset,CPU_INT16S *z_offset);
static void         LIS2MDL_Write_Offset(CPU_INT16S x_offset,CPU_INT16S y_offset,CPU_INT16S z_offset);
static void         LIS2MDL_Clean_Offset(void);
static CPU_BOOLEAN  LIS2MDL_Wait_Data_Update(CPU_INT08U max_cnt);
static CPU_BOOLEAN  LIS2MDL_Read_Average(CPU_INT16S *x,CPU_INT16S *y,CPU_INT16S *z,CPU_INT08U times);
#ifdef LIS2MDL_READ_TEMP
static void         LIS2MDL_Read_TEMP(CPU_INT16S *temp);
#endif
/*
***********************************************************************************************
                                         LOCAL FUNCTIONS
***********************************************************************************************
*/
/*
***********************************************************************************************
*                                     LIS2MDL_IOInit
*
* Description: LIS2MDL磁力计 IO初始化
*
* Argument(s): 无
*
* Return(s) :  无
*
* Caller(s) :
*
***********************************************************************************************
*/
static void LIS2MDL_IOInit(void)
{
    GPIO_InitTypeDef  GPIO_InitStruct;
    
    GPIO_InitStruct.Mode      = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull      = GPIO_PULLUP;
    GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Pin       = LIS2MDL_PIN_SCL |LIS2MDL_PIN_SDA;
    GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
    HAL_GPIO_Init(LIS2MDL_PORT_SDA_SCL, &GPIO_InitStruct);
}

/*
***********************************************************************************************
*                                     LIS2MDL_Register_Write
*
* Description: 写LIS2MDL寄存器
*
* Argument(s):
* addr: IN, 寄存器地址
*  val: IN, 要写入的值
*
* Return(s) :  无
*
* Caller(s) :
*
***********************************************************************************************
*/
static void LIS2MDL_Register_Write(CPU_INT08U addr,CPU_INT08U val)
{
    CPU_INT08U len = 0x01;
    LIS2MDL_HardI2C_Register_Write(LIS2MDL_ADDR_WRITE, addr, &val, len);
}
/*
***********************************************************************************************
*                                     LIS2MDL_Register_Read
*
* Description: 读LIS2MDL寄存器
*
* Argument(s):
* addr: IN, 寄存器地址
*
* Return(s) : 寄存器读取值
*
* Caller(s) :
*
***********************************************************************************************
*/
static CPU_INT08U LIS2MDL_Register_Read(CPU_INT08U addr)
{
    CPU_INT08U temp = 0x00, len = 0x01;
    LIS2MDL_HardI2C_Register_Read(LIS2MDL_ADDR_READ, addr, &temp, len);
    return temp;
}
/*
***********************************************************************************************
*                                     LIS2MDL_Read_XYZ
*
* Description: LIS2MDL读取XYZ三轴磁场强度
*
* Argument(s):
* x: OUT, X轴数据地址
* y: OUT, Y轴数据地址
* z: OUT, Z轴数据地址
*
* Return(s) : 无
*
* Caller(s) :
*
***********************************************************************************************
*/
static void LIS2MDL_Read_XYZ(CPU_INT16S *x,CPU_INT16S *y,CPU_INT16S *z)
{
    CPU_INT08U buf[LIS2MDL_XYZBUF_LEN];

    LIS2MDL_HardI2C_Register_Read(LIS2MDL_ADDR_READ, LIS2MDL_ADDR_XOUTL, buf, LIS2MDL_XYZBUF_LEN);
    *x=(CPU_INT16S)((buf[1]<<8)+buf[0]);
    *y=(CPU_INT16S)((buf[3]<<8)+buf[2]);
    *z=(CPU_INT16S)((buf[5]<<8)+buf[4]);
}

#ifdef LIS2MDL_READ_TEMP
/*
***********************************************************************************************
*                                     LIS2MDL_Read_TEMP
*
* Description: LIS2MDL读取温度值
*
* Argument(s):
* temp: OUT, 温度数据地址
*
* Return(s) :  无
*
* Caller(s) :
*
***********************************************************************************************
*/
static void LIS2MDL_Read_TEMP(CPU_INT16S *temp)
{
    CPU_INT08U buf[LIS2MDL_TEMBUF_LEN];
    CPU_INT16S dataT;

    LIS2MDL_HardI2C_Register_Read(LIS2MDL_ADDR_READ, LIS2MDL_ADDR_TEMPL, buf, LIS2MDL_TEMBUF_LEN);

    dataT = (CPU_INT16S)((buf[1]<<8)+buf[0]);
    *temp=  dataT/8+25;
}
#endif

/*
***********************************************************************************************
*                                     LIS2MDL_Read_Offset
*
* Description: LIS2MDL读取XYZ三轴OFFSET
*
* Argument(s):
* x_offset: OUT, X轴OFFSET数据地址
* y_offset: OUT, Y轴OFFSET数据地址
* z_offset: OUT, Z轴OFFSET数据地址
*
* Return(s) : 无
*
* Caller(s) :
*
***********************************************************************************************
*/
static void LIS2MDL_Read_Offset(CPU_INT16S *x_offset,CPU_INT16S *y_offset,CPU_INT16S *z_offset)
{  
    CPU_INT08U buf[LIS2MDL_OFFSETBUF_LEN];

    LIS2MDL_HardI2C_Register_Read(LIS2MDL_ADDR_READ, LIS2MDL_ADDR_OFFSETX_L, buf, LIS2MDL_OFFSETBUF_LEN);

    *x_offset = (CPU_INT16S)((buf[1]<<8)+buf[0]);
    *y_offset = (CPU_INT16S)((buf[3]<<8)+buf[2]);
    *z_offset = (CPU_INT16S)((buf[5]<<8)+buf[4]);
}

/*
***********************************************************************************************
*                                     LIS2MDL_Clean_Offset
*
* Description: 将LIS2MDL XYZ三轴OFFSET清0
*
* Argument(s): 无
*
* Return(s) :  无
*
* Caller(s) :
*
***********************************************************************************************
*/
static void LIS2MDL_Clean_Offset(void)
{
    CPU_INT08U i;
    
    for(i = 0x00;i < LIS2MDL_OFFSETBUF_LEN;i++)
    {
        LIS2MDL_Register_Write(LIS2MDL_ADDR_OFFSETX_L+i,0x00); 
    }
    HAL_Delay(100);
}

/*
***********************************************************************************************
*                                     LIS2MDL_Write_Offset
*
* Description: 写入LIS2MDL XYZ三轴OFFSET
*
* Argument(s):
* x_offset: OUT, X轴OFFSET
* y_offset: OUT, Y轴OFFSET
* z_offset: OUT, Z轴OFFSET
*
* Return(s) : 无
*
* Caller(s) :
*
***********************************************************************************************
*/
static void LIS2MDL_Write_Offset(CPU_INT16S x_offset,CPU_INT16S y_offset,CPU_INT16S z_offset)
{
    CPU_INT08U buf[LIS2MDL_OFFSETBUF_LEN];

    buf[0] =  x_offset & 0xFF;
    buf[1] = (x_offset >> 8) & 0xFF;
    buf[2] =  y_offset & 0xFF;
    buf[3] = (y_offset >> 8) & 0xFF;
    buf[4] =  z_offset & 0xFF;
    buf[5] = (z_offset >> 8) & 0xFF;

    LIS2MDL_HardI2C_Register_Write(LIS2MDL_ADDR_WRITE, LIS2MDL_ADDR_OFFSETX_L, buf, LIS2MDL_OFFSETBUF_LEN);
}
/*
***********************************************************************************************
*                                     LIS2MDL_Wait_Data_Update
*
* Description: LIS2MDL查询寄存器数据就绪
*
* Argument(s):
* max_cnt: IN, 最大轮询次数
*
* Return(s) :  成功:TRUE,失败:FALSE
*
* Caller(s) :
*
***********************************************************************************************
*/
static CPU_BOOLEAN LIS2MDL_Wait_Data_Update(CPU_INT08U max_cnt)
{
    for(; max_cnt>0x00; max_cnt--)
    {
        if(LIS2MDL_Register_Read(LIS2MDL_ADDR_STATUS) & 0x08)
        {
            return TRUE;
        }
        HAL_Delay(1);
    }
    return FALSE;
}

/*
***********************************************************************************************
*                                     LIS2MDL_Read_Average
*
* Description: LIS2MDL读取XYZ三轴磁场强度平均值
*
* Argument(s):
* x: IN, X轴数据地址
* y: IN, Y轴数据地址
* z: IN, Z轴数据地址
* times: IN, 读取次数
*
* Return(s) :  无
*
* Caller(s) :
*
***********************************************************************************************
*/
static CPU_BOOLEAN LIS2MDL_Read_Average(CPU_INT16S *x,CPU_INT16S *y,CPU_INT16S *z,CPU_INT08U times)
{
    CPU_INT08U i,j;
    CPU_INT16S tx,ty,tz;
    CPU_INT08U  temp_serial[10],tmp_serial;
    CPU_INT16S  temp_x[10],temp_y[10],temp_z[10];
    CPU_INT32S  tmp = 0;
    
    *x=0;
    *y=0;
    *z=0;
    
    if(times)
    {
        for(i=0;i<times;i++)
        {
            if(!LIS2MDL_Wait_Data_Update(15))
            {
                return FALSE;
            }
            LIS2MDL_Read_XYZ(&tx,&ty,&tz);
            temp_x[i]=tx;
            temp_y[i]=ty;
            temp_z[i]=tz;
        }
    }
    
    /**********************************计算X轴*********************************/
    for(j=0; j<times; j++) 
    {      
      	temp_serial[j] = j;	
    }
    
    for(i=times; i>0; i--)
    {
        for(j=0; j<(i-1); j++)
        {
            if(temp_x[temp_serial[j]] > temp_x[temp_serial[j+1]])
            {
                tmp_serial = temp_serial[j];
                temp_serial[j] = temp_serial[j+1];
                temp_serial[j+1] = tmp_serial;            
            }
        }
    }	
    
    for(i=1;i<times-1;i++) 
    { 
        tmp += temp_x[temp_serial[i]];
    }
    
    *x = tmp/(times-2);
    
    /**********************************计算Y轴*********************************/
    tmp = 0;
    
    for(j=0; j<times; j++) 
    {      
      	temp_serial[j] = j;	
    }
    
    for(i=times; i>0; i--)
    {
        for(j=0; j<(i-1); j++)
        {
            if(temp_y[temp_serial[j]] > temp_y[temp_serial[j+1]])
            {
                tmp_serial = temp_serial[j];
                temp_serial[j] = temp_serial[j+1];
                temp_serial[j+1] = tmp_serial;            
            }
        }
    }	
    
    for(i=1;i<times-1;i++) 
    { 
        tmp += temp_y[temp_serial[i]];
    }
    
    *y = tmp/(times-2);
    
    /**********************************计算Z轴*********************************/
    tmp = 0;
    
    for(j=0; j<times; j++) 
    {      
      	temp_serial[j] = j;	
    }
    
    for(i=times; i>0; i--)
    {
        for(j=0; j<(i-1); j++)
        {
            if(temp_z[temp_serial[j]] > temp_z[temp_serial[j+1]])
            {
                tmp_serial = temp_serial[j];
                temp_serial[j] = temp_serial[j+1];
                temp_serial[j+1] = tmp_serial;            
            }
        }
    }	
    
    for(i=1;i<times-1;i++) 
    { 
        tmp += temp_z[temp_serial[i]];
    }
    
    *z = tmp/(times-2);

    return TRUE;
}
/*
***********************************************************************************************
*                                    GLOBAL FUNCTIONS
***********************************************************************************************
*/
/*
***********************************************************************************************
*                                     QMC5883L_Init
*
* Description: QMC5883L磁力计初始化
*
* Argument(s): 无
*
* Return(s) :  初始化结果, 成功TRUE,失败FALSE
*
* Caller(s) :
*
***********************************************************************************************
*/
CPU_BOOLEAN LIS2MDL_Init(void)
{
    CPU_INT08U i,uErrTime = 0x00;
    CPU_INT08U uRegCheck[3]= {LIS2MDL_CFGA_VALUE_IDLE,LIS2MDL_CFGB_VALUE,LIS2MDL_CFGC_VALUE};
    LIS2MDL_IOInit();
    LIS2MDL_POWER_ON();
    HAL_Delay(50);

    while (LIS2MDL_Register_Read(LIS2MDL_ADDR_CHIPID) != LIS2MDL_CHIPID_VALUE)  /* 读取器件ID */
    {
        uErrTime++;
        if(uErrTime>250)
        {
            return FALSE;
        }
    }

    LIS2MDL_Register_Write(LIS2MDL_ADDR_CFGA,LIS2MDL_CFGA_VALUE_IDLE);
    LIS2MDL_Register_Write(LIS2MDL_ADDR_CFGB,LIS2MDL_CFGB_VALUE);
    LIS2MDL_Register_Write(LIS2MDL_ADDR_CFGC,LIS2MDL_CFGC_VALUE);

    for(i = 0x00;i < 0x03;i++)                                                  /* 回读寄存器校验 */
    {
        if(LIS2MDL_Register_Read(LIS2MDL_ADDR_CFGA + i)!=uRegCheck[i])
        {
            return FALSE;
        }
    }
    /* 传感器初始化后需重写OFFSET */
    LIS2MDL_Write_Offset(LIS2MDLSave.X_Offset,LIS2MDLSave.Y_Offset,LIS2MDLSave.Z_Offset);
    return TRUE;
}

/*
***********************************************************************************************
*                                     LIS2MDL_Soft_Reset
*
* Description: LIS2MDL磁力计软复位
*
* Argument(s): 无
*
* Return(s) :  无
*
* Caller(s) :
*
***********************************************************************************************
*/
void LIS2MDL_Soft_Reset(void)
{
    LIS2MDL_Register_Write(LIS2MDL_ADDR_CFGA, LIS2MDL_CFGA_SOFT_RST);
    HAL_Delay(2);
    LIS2MDL_Register_Write(LIS2MDL_ADDR_CFGA, LIS2MDL_CFGA_REBOOT);
    HAL_Delay(20);
}

/*
***********************************************************************************************
*                                     LIS2MDL_Hard_Reset
*
* Description: LIS2MDL磁力计硬复位
*
* Argument(s): 无
*
* Return(s) :  无
*
* Caller(s) :
*
***********************************************************************************************
*/
void LIS2MDL_Hard_Reset(void)
{
    LIS2MDL_POWER_OFF();
    HAL_Delay(1000);
    LIS2MDL_POWER_ON();
}

/*
***********************************************************************************************
*                                     LIS2MDL_Adjust_Magnetic
*
* Description: LIS2MDL校准
*
* Argument(s): 无
*
* Return(s) :  无
*
* Caller(s) :
*
***********************************************************************************************
*/
CPU_BOOLEAN LIS2MDL_Adjust_Magnetic(void)
{
    CPU_INT08U  err;
    CPU_BOOLEAN res;
    CPU_INT16S  x,y,z;

    x = 0x00;
    y = 0x00;
    z = 0x00;

    OSSemPend(App_SensorSem, OS_TICKS_PER_SEC, &err);                           /* 请求信号量 */
    if(err == OS_ERR_NONE)
    {
        /* LIS2MDL开启连续模式 */
        LIS2MDL_Register_Write(LIS2MDL_ADDR_CFGA, LIS2MDL_CFGA_VALUE_CONTINUE);

        LIS2MDL_Clean_Offset();                                                 /* 清除磁力计原OFFSET */
        /* 读取10组X,Y,Z三个方向的磁场强度值,并对其取平均 */
        if(!LIS2MDL_Read_Average(&x,&y,&z,10))
        {
            OSSemPost(App_SensorSem);                                           /* 释放信号量 */
            res = FALSE;
        }
        else
        {
            LIS2MDL_Write_Offset(x,y,z);                                        /* 写入新的OFFSET */
        }

        LIS2MDL_Read_Offset(&x,&y,&z);                                          /* 读出OFFSET */
        LIS2MDLSave.X_Offset = x;
        LIS2MDLSave.Y_Offset = y;
        LIS2MDLSave.Z_Offset = z;

        /* LIS2MDL开启空闲模式 */
        LIS2MDL_Register_Write(LIS2MDL_ADDR_CFGA, LIS2MDL_CFGA_VALUE_IDLE);
        OSSemPost(App_SensorSem);                                               /* 释放信号量 */

        res = TRUE;
    }
    else
    {
        res = FALSE;
    }
    return res;
}

/*
***********************************************************************************************
*                                     LIS2MDL_Read_MagDensity
*
* Description: LIS2MDL读取磁场强度
*
* Argument(s): 无
*
* Return(s) :  传感器读取数据结果
*
* Caller(s) :
*
***********************************************************************************************
*/
LIS2MDL_RESULT_SAMPLE LIS2MDL_Read_MagDensity(void)
{
    CPU_INT08U i,param_vali;
    CPU_INT16U MagDensity = 0x00;
    CPU_INT16S fx = 0x00, fy = 0x00, fz = 0x00;
    CPU_INT16S  x = 0x00,  y = 0x00,  z = 0x00;
    CPU_INT16S Temp = 0x00;
    SENSOR_DATA_ELEMENT_T Q_Sample;
    /* 检查传感器 */
    if (LIS2MDL_Register_Read(LIS2MDL_ADDR_CHIPID) != LIS2MDL_CHIPID_VALUE)
    {
        LIS2MDLSample.HardFault = TRUE;
        return LIS2MDL_DATA_ERROR_ADDR;
    }
    else
    {
        LIS2MDLSample.HardFault = FALSE;
    }
    /* LIS2MDL开启连续模式 */
    LIS2MDL_Register_Write(LIS2MDL_ADDR_CFGA, LIS2MDL_CFGA_VALUE_CONTINUE);
    for(i=0;i<2;i++)
    {
        if (LIS2MDL_Wait_Data_Update(15))
        {
            LIS2MDL_Read_XYZ(&x,&y,&z);
        }
        else
        {
            LIS2MDL_Register_Write(LIS2MDL_ADDR_CFGA, LIS2MDL_CFGA_VALUE_IDLE);
            return LIS2MDL_DATA_ERROR_TIMEOUT;
        }
    }
    /* LIS2MDL开启空闲模式 */
    LIS2MDL_Register_Write(LIS2MDL_ADDR_CFGA ,LIS2MDL_CFGA_VALUE_IDLE);

#ifdef LIS2MDL_READ_TEMP
    LIS2MDL_Read_TEMP(&Temp);
#endif
    if ((x == 0) && (y == 0) && (z == 0))
    {
        param_vali = FALSE;
        LIS2MDLSample.DetectInvalid = TRUE;
    }
    else
    {
        param_vali = TRUE;
        LIS2MDLSample.DetectInvalid = FALSE;
    }
    
    LIS2MDLSample.X_Data = (CPU_INT16S)(x * LIS2MDL_SENSITIVITY);
    LIS2MDLSample.Y_Data = (CPU_INT16S)(y * LIS2MDL_SENSITIVITY);
    LIS2MDLSample.Z_Data = (CPU_INT16S)(z * LIS2MDL_SENSITIVITY);
    
    fx = LIS2MDLSample.X_Data;
    fy = LIS2MDLSample.Y_Data;
    fz = LIS2MDLSample.Z_Data;
    MagDensity = (CPU_INT16U)(sqrt(fx*fx+fy*fy+fz*fz));
    
    Q_Sample.Bx    = fx;
    Q_Sample.By    = fy;
    Q_Sample.Bz    = fz;
    Q_Sample.Temp  = Temp;
    Q_Sample.BNorm = MagDensity;
    Q_Enqueue(&Q_Sample,&Q_CtlM);
    
    if (!param_vali)
    {
        return LIS2MDL_DATA_ERROR_VALUE;
    }
    return LIS2MDL_DATA_SUCCESS;
}

/*
***********************************************************************************************
*                                     LIS2MDL_HardState
*
* Description: 读取传感器硬件是否损坏
*
* Argument(s): 无
*
* Return(s) :  传感器硬件损坏结果
*
* Caller(s) :
*
***********************************************************************************************
*/
CPU_BOOLEAN LIS2MDL_HardState(void)
{
    return LIS2MDLSample.HardFault;
}

/*
***********************************************************************************************
*                                     LIS2MDL_DetectState
*
* Description: 读取传感器采集是否失效
*
* Argument(s): 无
*
* Return(s) :  传感器采集失效结果
*
* Caller(s) :
*
***********************************************************************************************
*/
CPU_BOOLEAN LIS2MDL_DetectState(void)
{
    return LIS2MDLSample.DetectInvalid;
}

/*
***********************************************************************************************
*                                     LIS2MDL_ManualAdjustMag
*
* Description: LIS2MDL磁力计手动更新磁场校准值
*
* Argument(s): 无
* x_offset: OUT, X轴OFFSET
* y_offset: OUT, Y轴OFFSET
* z_offset: OUT, Z轴OFFSET
*
* Return(s) :  无
*
* Caller(s) :
*
***********************************************************************************************
*/
void LIS2MDL_ManualAdjustMag(CPU_INT16S x_offset,CPU_INT16S y_offset,CPU_INT16S z_offset)
{
    LIS2MDL_Write_Offset(x_offset,y_offset,z_offset);
}
/*
***********************************************************************************************
*                                       LIS2MDL磁力计驱动
*
*                                      实现LIS2MDL底层驱动
*
* Filename : LIS2MDL.h
* Version : V1.00
* Programmer(s) : FengDuo
*
***********************************************************************************************
*/

//文件声明
#ifndef _LIS2MDL_H_
#define _LIS2MDL_H_


#ifdef   LIS2MDL_MOUDLE
#define  LIS2MDL_EXT
#else
#define  LIS2MDL_EXT  extern
#endif
/*
***********************************************************************************************
*                                         INCLUDE FILES
***********************************************************************************************
*/
//......
/*
***********************************************************************************************
*                                            DEFINES
***********************************************************************************************
*/
/* 器件地址:设备从地址+读写选择 */
#define LIS2MDL_ADDR_WRITE                        0x3C
#define LIS2MDL_ADDR_READ                         0x3D

/* 设备寄存器地址 */
#define LIS2MDL_ADDR_CFGA                         0x60
#define LIS2MDL_ADDR_CFGB                         0x61
#define LIS2MDL_ADDR_CFGC                         0x62
#define LIS2MDL_ADDR_INTCRTL                      0x63
#define LIS2MDL_ADDR_INTSOURCE                    0x64
#define LIS2MDL_ADDR_INTTHSL                      0x65
#define LIS2MDL_ADDR_INTTHSH                      0x66
#define LIS2MDL_ADDR_STATUS                       0x67

#define LIS2MDL_ADDR_XOUTL                        0x68
#define LIS2MDL_ADDR_XOUTH                        0x69
#define LIS2MDL_ADDR_YOUTHL                       0x6A
#define LIS2MDL_ADDR_YOUTH                        0x6B
#define LIS2MDL_ADDR_ZOUTL                        0x6C
#define LIS2MDL_ADDR_ZOUTH                        0x6D

#define LIS2MDL_ADDR_TEMPL                        0x6E
#define LIS2MDL_ADDR_TEMPH                        0x6F

#define LIS2MDL_ADDR_OFFSETX_L                    0x45
#define LIS2MDL_ADDR_OFFSETX_H                    0x46
#define LIS2MDL_ADDR_OFFSETY_L                    0x47
#define LIS2MDL_ADDR_OFFSETY_H                    0x48
#define LIS2MDL_ADDR_OFFSETZ_L                    0x49
#define LIS2MDL_ADDR_OFFSETZ_H                    0x4A

#define LIS2MDL_ADDR_CHIPID                       0x4F

/* 设备寄存器参数值 */
#define LIS2MDL_CFGA_TEMP_EN                    (1 << 7)
#define LIS2MDL_CFGA_REBOOT                     (1 << 6)
#define LIS2MDL_CFGA_SOFT_RST                   (1 << 5)
#define LIS2MDL_CFGA_LP                         (1 << 4)
#define LIS2MDL_CFGA_ODR_10HZ                   (0 << 3) | (0 << 2)
#define LIS2MDL_CFGA_ODR_20HZ                   (0 << 3) | (1 << 2)
#define LIS2MDL_CFGA_ODR_50HZ                   (1 << 3) | (0 << 2)
#define LIS2MDL_CFGA_ODR_100HZ                  (1 << 3) | (1 << 2)
#define LIS2MDL_CFGA_MODE_CONTINUE              (0 << 1) | (0 << 0)
#define LIS2MDL_CFGA_MODE_SINGLE                (0 << 1) | (1 << 0)
#define LIS2MDL_CFGA_MoDE_IDLE                  (1 << 1) | (1 << 0)

#define LIS2MDL_CFGB_OFF_CANC_ONE_SHOT_EN       (1 << 4)
#define LIS2MDL_CFGB_INT_EN                     (1 << 3)
#define LIS2MDL_CFGB_SET_FREQ                   (1 << 2)
#define LIS2MDL_CFGB_OFF_CANC_EN                (1 << 1)
#define LIS2MDL_CFGB_LPF_EN                     (1 << 0)

#define LIS2MDL_CFGC_INT_ON_PIN                 (1 << 6)
#define LIS2MDL_CFGC_I2C_DIS                    (1 << 5)
#define LIS2MDL_CFGC_BDU                        (1 << 4)
#define LIS2MDL_CFGC_BLE                        (1 << 3)
#define LIS2MDL_CFGC_SPI                        (1 << 2)
#define LIS2MDL_CFGC_SELF_TEST                  (1 << 1)
#define LIS2MDL_CFGC_DRDY_ON_PIN                (1 << 0)


#define LIS2MDL_CHIPID_VALUE                      0x40                          /* 器件标识 */

#define LIS2MDL_CFGA_VALUE_CONTINUE             ( LIS2MDL_CFGA_TEMP_EN         \
                                                | LIS2MDL_CFGA_ODR_100HZ       \
                                                | LIS2MDL_CFGA_MODE_CONTINUE )  /* 温度补偿,100HZ,连续模式 */

#define LIS2MDL_CFGA_VALUE_IDLE                 ( LIS2MDL_CFGA_TEMP_EN         \
                                                | LIS2MDL_CFGA_ODR_100HZ       \
                                                | LIS2MDL_CFGA_MoDE_IDLE )      /* 温度补偿,100HZ,空闲模式 */

#define LIS2MDL_CFGB_VALUE                      ( LIS2MDL_CFGB_OFF_CANC_EN     \
                                                | LIS2MDL_CFGB_LPF_EN )         /* 偏移抵消,启用低通滤波 */

#define LIS2MDL_CFGC_VALUE                      ( LIS2MDL_CFGC_BDU )            /* 开启数据完整性保护 */

#define LIS2MDL_XYZBUF_LEN                        0x06
#define LIS2MDL_TEMBUF_LEN                        0x02
#define LIS2MDL_OFFSETBUF_LEN                     0x06

#define LIS2MDL_SENSITIVITY                     ( 1.5 )                         /* 磁力计灵敏度 */

#define LIS2MDL_CUM_REBOOT_MAXCNT               ( 100 )                         /* 磁力计累计重启最大次数 */
#define LIS2MDL_CON_REBOOT_MAXCNT               LIS2MDL_CUM_REBOOT_MAXCNT       /* 磁力计连续重启最大次数 */

/* LIS2MDL 供电控制 */ 
#define LIS2MDL_POWER_ON()                      BSP_SNR_PWR_H()
#define LIS2MDL_POWER_OFF()                     BSP_SNR_PWR_L()

/* LIS2MDL 管脚 */ 
#define LIS2MDL_PIN_SCL                         BSP_IIC1_PIN_SCL
#define LIS2MDL_PIN_SDA                         BSP_IIC1_PIN_SDA
#define LIS2MDL_PORT_SDA_SCL                    BSP_IIC1_PORT_SDA_SCL

//#define LIS2MDL_READ_TEMP                                                       /* 使用LIS2MDL内部温度 */

typedef struct 
{
    CPU_INT16S  X_Data;                                                         /* 磁力计X轴数据 */
    CPU_INT16S  Y_Data;                                                         /* 磁力计Y轴数据 */
    CPU_INT16S  Z_Data;                                                         /* 磁力计Z轴数据 */
    CPU_INT16S  T_Data;                                                         /* 磁力计内部温度 */
    CPU_INT16U  MagDensity;                                                     /* 磁力计总磁扰强度 */
    CPU_FP32    XY_Angle;                                                       /* 磁力计X轴Y轴夹角 */
    CPU_FP32    XZ_Angle;                                                       /* 磁力计X轴Z轴夹角 */
    CPU_FP32    YZ_Angle;                                                       /* 磁力计Y轴Z轴夹角 */

    CPU_INT16S  X_Offset;                                                       /* 磁力计X轴OFFSET */
    CPU_INT16S  Y_Offset;                                                       /* 磁力计Y轴OFFSET */
    CPU_INT16S  Z_Offset;                                                       /* 磁力计Z轴OFFSET */

    CPU_BOOLEAN HardFault;                                                      /* 传感器硬件损坏 */
    CPU_BOOLEAN DetectInvalid;                                                  /* 传感器检测失效 */
}LIS2MDL_SAMPLE_DEF;

typedef struct 
{
    CPU_INT16S X_Offset;                                                        /* 磁力计X轴OFFSET */
    CPU_INT16S Y_Offset;                                                        /* 磁力计Y轴OFFSET */
    CPU_INT16S Z_Offset;                                                        /* 磁力计Z轴OFFSET */
}LIS2MDL_Save_DEF;

typedef enum{
    LIS2MDL_DATA_SUCCESS,                                                       /* 获取数据成功 */
    LIS2MDL_DATA_ERROR_ADDR,                                                    /* 传感器通信地址错误 */
    LIS2MDL_DATA_ERROR_TIMEOUT,                                                 /* 传感器读取超时 */
    LIS2MDL_DATA_ERROR_VALUE,                                                   /* 传感器数值错误 */
}LIS2MDL_RESULT_SAMPLE;
/*
***********************************************************************************************
*                                            EXTERNS
***********************************************************************************************
*/
LIS2MDL_EXT LIS2MDL_Save_DEF LIS2MDLSave;
/*
***********************************************************************************************
*                                  GLOBAL FUNCTION PROTOTYPES
***********************************************************************************************
*/
LIS2MDL_EXT void LIS2MDL_Soft_Reset(void);
LIS2MDL_EXT void LIS2MDL_Hard_Reset(void);
LIS2MDL_EXT CPU_BOOLEAN LIS2MDL_Init(void);
LIS2MDL_EXT CPU_BOOLEAN LIS2MDL_HardState(void);
LIS2MDL_EXT CPU_BOOLEAN LIS2MDL_DetectState(void);
LIS2MDL_EXT CPU_BOOLEAN LIS2MDL_Adjust_Magnetic(void);
LIS2MDL_EXT LIS2MDL_RESULT_SAMPLE LIS2MDL_Read_MagDensity(void);
LIS2MDL_EXT void LIS2MDL_ManualAdjustMag(CPU_INT16S x_offset,CPU_INT16S y_offset,CPU_INT16S z_offset);
#endif

有需要下载源文件的同学可以去该地址下载:https://download.csdn.net/download/yekui6254/12109416

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!