之前使用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
来源:CSDN
作者:薛定谔的Akashi
链接:https://blog.csdn.net/yekui6254/article/details/104020078