LSM6DS3TH-C 6轴传感器驱动
说明
- 测试平台:STM32F4
- 使用说明:
- 在platform_ReadByte、与platform_WriteByte中实现对应平台的I2C读写操作接口
- 默认应用接口为弱定义,定义此USER_APP_INTERFACE宏定义可以开启示例的应用接口,用户可自定义自己的接口函数,打印信息可自行关闭,默认的接口函数不包含单位转换,只实现了原始数据存储
- 存储数据使用数据类型sLSM6DS3_Data
- 默认定义了对象sLSM6DS3_Dev g_lsm6ds3,可包含lsm6ds3.h头文件,即可使用此对象去访问用户接口函数
驱动源码
#ifndef __LSM6DS3_H__
#define __LSM6DS3_H__
#include "main.h"
#define LSM6DS3_WHO_AM_I 0X0F
#define LSM6DS3_CTRL1_XL 0X10
#define LSM6DS3_CTRL2_G 0X11
#define LSM6DS3_CTRL3_C 0X12
#define LSM6DS3_CTRL4_C 0X13
#define LSM6DS3_CTRL5_C 0X14
#define LSM6DS3_CTRL6_C 0X15
#define LSM6DS3_CTRL7_G 0X16
#define LSM6DS3_CTRL8_XL 0X17
#define LSM6DS3_CTRL9_XL 0X18
#define LSM6DS3_CTRL10_C 0X19
#define LSM6DS3_MASTER_CONFIG 0X1A
#define LSM6DS3_WAKE_UP_SRC 0X1B
#define LSM6DS3_TAP_SRC 0X1C
#define LSM6DS3_D6D_SRC 0X1D
#define LSM6DS3_STATUS_REG 0X1E
#define LSM6DS3_TAP_CFG 0x58
#define LSM6DS3_TAP_THS_6D 0x59
#define LSM6DS3_WAKE_UP_THS 0x5B
#define LSM6DS3_WAKE_UP_DUR 0x5C
#define LSM6DS3_MD1_CFG 0x5E
#define LSM6DS3_OUT_TEMP_L 0X20
#define LSM6DS3_OUT_TEMP_H 0X21
#define LSM6DS3_OUTX_L_G 0X22
#define LSM6DS3_OUTX_H_G 0X23
#define LSM6DS3_OUTY_L_G 0X24
#define LSM6DS3_OUTY_H_G 0X25
#define LSM6DS3_OUTZ_L_G 0X26
#define LSM6DS3_OUTZ_H_G 0X27
#define LSM6DS3_OUTX_L_XL 0X28
#define LSM6DS3_OUTX_H_XL 0X29
#define LSM6DS3_OUTY_L_XL 0X2A
#define LSM6DS3_OUTY_H_XL 0X2B
#define LSM6DS3_OUTZ_L_XL 0X2C
#define LSM6DS3_OUTZ_H_XL 0X2D
#define LSM6DS3_INT1_CTRL 0X0D
#define I2C_Handle hi2c1
#define LSM6DS3_SlaveAddress 0xd4
#define I2C_Status HAL_StatusTypeDef
#define LSM6DS3_DeviceID 0x6a
#undef USER_APP_INTERFACE
typedef enum
{
eRead = 0u,
eWrite = 1u,
} OPmode_t;
typedef enum{
STATUS_XLDA_ACC_E = 0x01,
STATUS_GDA_GYRO_E = 0x02,
STATUS_TDA_TEMP_E = 0x04,
}LSM6DS3_STATUS_t;
typedef struct
{
int16_t data_raw_acceleration[3];
int16_t data_raw_angular_rate[3];
int16_t data_raw_temperature;
float acceleration_mg[3];
float angular_rate_mdps[3];
float temperature_degC;
uint8_t whoamI;
uint8_t uReaddata;
uint8_t orientation;
} sLSM6DS3_Data;
typedef struct
{
void *handle;
sLSM6DS3_Data m_dataBuf;
uint8_t slaveAddress;
uint8_t deviceID;
void (*Init)(void);
uint8_t (*ReadByte)(uint8_t reg);
void (*WriteByte)(uint8_t reg, uint8_t data);
uint16_t (*ReadMultiple)(uint8_t reg_begin, uint8_t reg_end, uint8_t *data);
uint8_t (*ReadOrigin)(void);
uint8_t (*ReadWhoAmI)(void);
int16_t *(*ReadAngularRateRaw)(int16_t *pbuf);
int16_t *(*ReadAccelerationRaw)(int16_t *pbuf);
int16_t *(*ReadTemperatureRaw)(int16_t *pbuf);
} sLSM6DS3_Dev;
extern sLSM6DS3_Dev g_lsm6ds3;
#endif
#include "LSM6DS3.h"
#include "i2c.h"
#include "debug.h"
#include
static void Lsm6ds3_Init(void);
static void Lsm6ds3_WriteByte(uint8_t reg, uint8_t data);
static uint8_t Lsm6ds3_ReadByte(uint8_t reg);
static uint16_t Lsm6ds3_ReadMultiple(uint8_t reg_addr_begin, uint8_t reg_addr_end, uint8_t *data);
uint8_t Lsm6ds3_ReadOrigin(void);
uint8_t Lsm6ds3_ReadWhoAmI(void);
int16_t *Lsm6ds3_ReadAccelerationRaw(int16_t *pbuf);
int16_t *Lsm6ds3_ReadAngularRateRaw(int16_t *pbuf);
int16_t *Lsm6ds3_ReadTemperatureRaw(int16_t *pbuf);
sLSM6DS3_Dev g_lsm6ds3 =
{
&hi2c1,
{0},
LSM6DS3_SlaveAddress,
LSM6DS3_DeviceID,
Lsm6ds3_Init,
Lsm6ds3_ReadByte,
Lsm6ds3_WriteByte,
Lsm6ds3_ReadMultiple,
Lsm6ds3_ReadOrigin,
Lsm6ds3_ReadWhoAmI,
Lsm6ds3_ReadAngularRateRaw,
Lsm6ds3_ReadAccelerationRaw,
Lsm6ds3_ReadTemperatureRaw,
};
static I2C_Status platform_ReadByte(void *handle, uint8_t slaveAddress, uint8_t reg, uint8_t *bufp, uint16_t len)
{
return HAL_I2C_Mem_Read(handle, slaveAddress, reg, I2C_MEMADD_SIZE_8BIT, bufp, len, 1000);
}
static I2C_Status platform_WriteByte(void *handle, uint8_t slaveAddress, uint8_t reg, uint8_t *bufp, uint16_t len)
{
return HAL_I2C_Mem_Write(handle, slaveAddress, reg, I2C_MEMADD_SIZE_8BIT, (uint8_t *)bufp, len, 1000);
}
static void Lsm6ds3_WriteByte(uint8_t reg, uint8_t data)
{
I2C_Status ret = platform_WriteByte(g_lsm6ds3.handle, g_lsm6ds3.slaveAddress | eWrite,
reg, &data, sizeof(data));
if(ret != HAL_OK)
p_err("error_code:%d", ret);
}
static uint8_t Lsm6ds3_ReadByte(uint8_t reg)
{
I2C_Status ret = platform_ReadByte(g_lsm6ds3.handle, g_lsm6ds3.slaveAddress | eRead,
reg, &(g_lsm6ds3.m_dataBuf.uReaddata), sizeof(g_lsm6ds3.m_dataBuf.uReaddata));
if(ret != HAL_OK)
{
p_err("error_code:%d", ret);
g_lsm6ds3.m_dataBuf.uReaddata= 0xff;
}
p_info("Lsm6ds3_ReadByte ret=%d, reg=0x%x, data=0x%x", ret, reg, g_lsm6ds3.m_dataBuf.uReaddata);
return g_lsm6ds3.m_dataBuf.uReaddata;
}
static uint16_t Lsm6ds3_ReadMultiple(uint8_t reg_addr_begin, uint8_t reg_addr_end, uint8_t *data)
{
uint16_t nCount = 0;
if(reg_addr_begin > reg_addr_end)
{
p_err("register address invalid!");
return 0;
}
while(nCount < (reg_addr_end - reg_addr_begin + 1))
{
data[nCount] = Lsm6ds3_ReadByte(reg_addr_begin + nCount);
nCount++;
}
return nCount;
}
static void Lsm6ds3_Init(void)
{
uint8_t whoAmI = Lsm6ds3_ReadByte(LSM6DS3_WHO_AM_I);
p_info("Lsm6ds3_Init[G-SensorId] -> 0x%x", whoAmI);
if(whoAmI != LSM6DS3_DeviceID)
{
p_err("read who am i failed!");
return;
}
Lsm6ds3_WriteByte(LSM6DS3_CTRL1_XL, 0x20);
Lsm6ds3_WriteByte(LSM6DS3_CTRL9_XL, 0x38);
Lsm6ds3_WriteByte(LSM6DS3_INT1_CTRL, 0x01);
Lsm6ds3_WriteByte(LSM6DS3_CTRL2_G, 0x5C);
Lsm6ds3_WriteByte(LSM6DS3_CTRL10_C, 0x38);
Lsm6ds3_WriteByte(LSM6DS3_TAP_CFG, 0x90);
Lsm6ds3_WriteByte(LSM6DS3_WAKE_UP_DUR, 0x00);
Lsm6ds3_WriteByte(LSM6DS3_WAKE_UP_THS, 0x02);
Lsm6ds3_WriteByte(LSM6DS3_MD1_CFG, 0x20);
Lsm6ds3_WriteByte(LSM6DS3_TAP_THS_6D, 0x40);
Lsm6ds3_WriteByte(LSM6DS3_CTRL8_XL, 0x01);
p_info("Lsm6ds3 init successfule!");
}
#ifdef USER_APP_INTERFACE
uint8_t Lsm6ds3_ReadOrigin(void)
{
g_lsm6ds3.m_dataBuf.orientation = Lsm6ds3_ReadByte(LSM6DS3_D6D_SRC);
return g_lsm6ds3.m_dataBuf.orientation;
}
uint8_t Lsm6ds3_ReadWhoAmI(void)
{
g_lsm6ds3.m_dataBuf.whoamI = Lsm6ds3_ReadByte(LSM6DS3_WHO_AM_I);
return g_lsm6ds3.m_dataBuf.whoamI;
}
int16_t *Lsm6ds3_ReadAngularRateRaw(int16_t *pbuf)
{
uint8_t buf[6] = {0};
if((g_lsm6ds3.ReadByte(LSM6DS3_STATUS_REG) & STATUS_GDA_GYRO_E) != 0)
{
Lsm6ds3_ReadMultiple(LSM6DS3_OUTX_L_G, LSM6DS3_OUTZ_H_G, buf);
g_lsm6ds3.m_dataBuf.data_raw_angular_rate[0] = (buf[1] << 8) | buf[0];
g_lsm6ds3.m_dataBuf.data_raw_angular_rate[1] = (buf[3] << 8) | buf[2];
g_lsm6ds3.m_dataBuf.data_raw_angular_rate[2] = (buf[5] << 8) | buf[4];
}
if(NULL != pbuf)
memcpy(pbuf, buf, sizeof(buf));
return g_lsm6ds3.m_dataBuf.data_raw_angular_rate;
}
int16_t *Lsm6ds3_ReadAccelerationRaw(int16_t *pbuf)
{
uint8_t buf[6] = {0};
if((g_lsm6ds3.ReadByte(LSM6DS3_STATUS_REG) & STATUS_XLDA_ACC_E) != 0)
{
Lsm6ds3_ReadMultiple(LSM6DS3_OUTX_L_XL, LSM6DS3_OUTZ_H_XL, buf);
g_lsm6ds3.m_dataBuf.data_raw_acceleration[0] = (buf[1] << 8) | buf[0];
g_lsm6ds3.m_dataBuf.data_raw_acceleration[1] = (buf[3] << 8) | buf[2];
g_lsm6ds3.m_dataBuf.data_raw_acceleration[2] = (buf[5] << 8) | buf[4];
}
if(NULL != pbuf)
memcpy(pbuf, buf, sizeof(buf));
return g_lsm6ds3.m_dataBuf.data_raw_acceleration;
}
int16_t *Lsm6ds3_ReadTemperatureRaw(int16_t *pbuf)
{
uint8_t buf[2] = {0};
if((g_lsm6ds3.ReadByte(LSM6DS3_STATUS_REG) & STATUS_TDA_TEMP_E) != 0)
{
Lsm6ds3_ReadMultiple(LSM6DS3_OUT_TEMP_L, LSM6DS3_OUT_TEMP_H, buf);
g_lsm6ds3.m_dataBuf.data_raw_temperature = (buf[1] << 8) | buf[0];
}
if(NULL != pbuf)
memcpy(pbuf, buf, sizeof(buf));
return &(g_lsm6ds3.m_dataBuf.data_raw_temperature);
}
#else
__weak uint8_t Lsm6ds3_ReadOrigin(void)
{
return 0xff;
}
__weak uint8_t Lsm6ds3_ReadWhoAmI(void)
{
return 0xff;
}
__weak int16_t *Lsm6ds3_ReadAngularRateRaw(int16_t *pbuf)
{
return NULL;
}
__weak int16_t *Lsm6ds3_ReadAccelerationRaw(int16_t *pbuf)
{
return NULL;
}
__weak int16_t *Lsm6ds3_ReadTemperatureRaw(int16_t *pbuf)
{
return NULL;
}
#endif