超低功耗
待机电流: 10nA
运动唤醒模式电流: 270nA
高分辨率: 1 mg/LSB
数字接口: SPI数字接口
供电电压: 1.6 V至3.5 V
ADXL362是一款超低功耗、 3轴MEMS加速度计,输出数据速率为100 Hz时功耗低于2 μA,在运动触发唤醒模式下功耗为270 nA。与使用周期采样来实现低功耗的加速度计不同,ADXL362没有通过欠采样混叠输入信号;它采用全数据速率对传感器的整个带宽进行采样。ADXL362通常提供12位输出分辨率;在较低分辨率足够时,还提供8位数据输出以实现更高效的单字节传送。测量范围为±2 g、 ±4 g及±8 g, ±2 g范围内的分辨率为1 mg/LSB。噪声电平要求低于ADXL362正常值550 μg/√Hz的应用可以选择两个低噪声模式(典型值低至175 μg/√Hz)之一,电源电流增加极小。除了超低功耗以外, ADXL362还具有许多特性来实现真正的系统级节能。该器件包含了一个深度多模式输出FIFO、一个内置微功耗温度传感器和几个运动检测模式,其中包括阙值可调的睡眠和唤醒工作模式,在该模式下当测量速率为6 HZ左右时功耗低至270 nA。如有需要,可在检测到运动时提供一个引脚输出来直接控制外部开关。此外,ADXL362还支持对采样时间和/或系统时钟进行外部控制。ADXL362可以在1.6V至3.5V的宽电源电压范围内工作,并且必要时可以与采用独立低电源电压工作的主机接口。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9RmMTJ8R-1584185336838)(https://raw.githubusercontent.com/WuliYongShun/PictureHouse/master/img/20200313173608.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t1V7HjV7-1584185336840)(https://raw.githubusercontent.com/WuliYongShun/PictureHouse/master/img/20200313173627.png)]
驱动程序调试成功,正常通讯,使用STM32单片机(Hal库)形式对传感器进行控制操作及读取数据,源码如下(程序原理ADI官方代码,修改其中读写程序即可),经过测试驱动程序正常使用。
/**
******************************************************************************
* Copyright(C) 2016-2026 GDKY All Rights Reserved
*
* @file ADXL362Driver.c
* @author YSHUN
* @version V1.00
* @date 2020.02.05
* @brief 硬件层驱动处理程序.
******************************************************************************
*/
#ifndef __ADXL362_H__
#define __ADXL362_H__
/* INCLUDES ------------------------------------------------------------------- */
#include "stm32l0xx_hal.h"
#include "gpio.h"
#include "spi.h"
#ifdef __cplusplus
extern "C" {
#endif
/* TYPEDEFS ------------------------------------------------------------------- */
#define ADXL362_CS_Pin GPIO_PIN_1
#define ADXL362_CS_GPIO_Port GPIOB
#define Clr_Cs() HAL_GPIO_WritePin(ADXL362_CS_GPIO_Port, ADXL362_CS_Pin, GPIO_PIN_RESET)
#define Set_Cs() HAL_GPIO_WritePin(ADXL362_CS_GPIO_Port, ADXL362_CS_Pin, GPIO_PIN_SET)
#define ADXL362_SLAVE_ID 1
/* ADXL362 communication commands */
#define ADXL362_WRITE_REG 0x0A
#define ADXL362_READ_REG 0x0B
#define ADXL362_WRITE_FIFO 0x0D
/* Registers */
#define ADXL362_REG_DEVID_AD 0x00
#define ADXL362_REG_DEVID_MST 0x01
#define ADXL362_REG_PARTID 0x02
#define ADXL362_REG_REVID 0x03
#define ADXL362_REG_XDATA 0x08 //X轴数据(8 MSB)寄存器
#define ADXL362_REG_YDATA 0x09 //Y轴数据(8 MSB)寄存器
#define ADXL362_REG_ZDATA 0x0A //Z轴数据(8 MSB)寄存器
#define ADXL362_REG_STATUS 0x0B //状态寄存器,用于指示ADXL362的各种状态
#define ADXL362_REG_FIFO_L 0x0C //FIFO条目寄存器,低8位
#define ADXL362_REG_FIFO_H 0x0D //FIFO条目寄存器,高8位
#define ADXL362_REG_XDATA_L 0x0E
#define ADXL362_REG_XDATA_H 0x0F
#define ADXL362_REG_YDATA_L 0x10
#define ADXL362_REG_YDATA_H 0x11
#define ADXL362_REG_ZDATA_L 0x12
#define ADXL362_REG_ZDATA_H 0x13
#define ADXL362_REG_TEMP_L 0x14 //温度数据寄存器
#define ADXL362_REG_TEMP_H 0x15
#define ADXL362_REG_SOFT_RESET 0x1F //软复位寄存器
#define ADXL362_REG_THRESH_ACT_L 0x20 //运动阈值寄存器,保存8个LSB
#define ADXL362_REG_THRESH_ACT_H 0x21 //运动阈值寄存器,保存3个MSB
#define ADXL362_REG_TIME_ACT 0x22 //运动时间寄存器
#define ADXL362_REG_THRESH_INACT_L 0x23 //静止阈值寄存器,保存8个LSB
#define ADXL362_REG_THRESH_INACT_H 0x24 //静止阈值寄存器,保存3个MSB
#define ADXL362_REG_TIME_INACT_L 0x25 //静止时间寄存器,保存8个LSB
#define ADXL362_REG_TIME_INACT_H 0x26 //静止时间寄存器,保存8个MSB
#define ADXL362_REG_ACT_INACT_CTL 0x27
#define ADXL362_REG_FIFO_CTL 0x28
#define ADXL362_REG_FIFO_SAMPLES 0x29
#define ADXL362_REG_INTMAP1 0x2A //INT1/INT2功能映射寄存器,INT1映射
#define ADXL362_REG_INTMAP2 0x2B //INT1/INT2功能映射寄存器,INT2映射
#define ADXL362_REG_FILTER_CTL 0x2C //滤波器控制寄存器
#define ADXL362_REG_POWER_CTL 0x2D //电源控制寄存器
#define ADXL362_REG_SELF_TEST 0x2E //自检寄存器
/* ADXL362_REG_STATUS definitions */
#define ADXL362_STATUS_ERR_USER_REGS (1 << 7)
#define ADXL362_STATUS_AWAKE (1 << 6)
#define ADXL362_STATUS_INACT (1 << 5)
#define ADXL362_STATUS_ACT (1 << 4)
#define ADXL362_STATUS_FIFO_OVERRUN (1 << 3)
#define ADXL362_STATUS_FIFO_WATERMARK (1 << 2)
#define ADXL362_STATUS_FIFO_RDY (1 << 1)
#define ADXL362_STATUS_DATA_RDY (1 << 0)
/* ADXL362_REG_ACT_INACT_CTL definitions */
#define ADXL362_ACT_INACT_CTL_LINKLOOP(x) (((x) & 0x3) << 4)
#define ADXL362_ACT_INACT_CTL_INACT_REF (1 << 3)
#define ADXL362_ACT_INACT_CTL_INACT_EN (1 << 2)
#define ADXL362_ACT_INACT_CTL_ACT_REF (1 << 1)
#define ADXL362_ACT_INACT_CTL_ACT_EN (1 << 0)
/* ADXL362_ACT_INACT_CTL_LINKLOOP(x) options */
#define ADXL362_MODE_DEFAULT 0
#define ADXL362_MODE_LINK 1
#define ADXL362_MODE_LOOP 3
/* ADXL362_REG_FIFO_CTL */
#define ADXL362_FIFO_CTL_AH (1 << 3)
#define ADXL362_FIFO_CTL_FIFO_TEMP (1 << 2)
#define ADXL362_FIFO_CTL_FIFO_MODE(x) (((x) & 0x3) << 0)
/* ADXL362_FIFO_CTL_FIFO_MODE(x) options */
#define ADXL362_FIFO_DISABLE 0
#define ADXL362_FIFO_OLDEST_SAVED 1
#define ADXL362_FIFO_STREAM 2
#define ADXL362_FIFO_TRIGGERED 3
/* ADXL362_REG_INTMAP1 */
#define ADXL362_INTMAP1_INT_LOW (1 << 7)
#define ADXL362_INTMAP1_AWAKE (1 << 6)
#define ADXL362_INTMAP1_INACT (1 << 5)
#define ADXL362_INTMAP1_ACT (1 << 4)
#define ADXL362_INTMAP1_FIFO_OVERRUN (1 << 3)
#define ADXL362_INTMAP1_FIFO_WATERMARK (1 << 2)
#define ADXL362_INTMAP1_FIFO_READY (1 << 1)
#define ADXL362_INTMAP1_DATA_READY (1 << 0)
/* ADXL362_REG_INTMAP2 definitions */
#define ADXL362_INTMAP2_INT_LOW (1 << 7)
#define ADXL362_INTMAP2_AWAKE (1 << 6)
#define ADXL362_INTMAP2_INACT (1 << 5)
#define ADXL362_INTMAP2_ACT (1 << 4)
#define ADXL362_INTMAP2_FIFO_OVERRUN (1 << 3)
#define ADXL362_INTMAP2_FIFO_WATERMARK (1 << 2)
#define ADXL362_INTMAP2_FIFO_READY (1 << 1)
#define ADXL362_INTMAP2_DATA_READY (1 << 0)
/* ADXL362_REG_FILTER_CTL definitions */
#define ADXL362_FILTER_CTL_RANGE(x) (((x) & 0x3) << 6)
#define ADXL362_FILTER_CTL_RES (1 << 5)
#define ADXL362_FILTER_CTL_HALF_BW (1 << 4)
#define ADXL362_FILTER_CTL_EXT_SAMPLE (1 << 3)
#define ADXL362_FILTER_CTL_ODR(x) (((x) & 0x7) << 0)
/* ADXL362_FILTER_CTL_RANGE(x) options */
#define ADXL362_RANGE_2G 0 /* +-2 g */
#define ADXL362_RANGE_4G 1 /* +-4 g */
#define ADXL362_RANGE_8G 2 /* +-8 g */
/* ADXL362_FILTER_CTL_ODR(x) options */
#define ADXL362_ODR_12_5_HZ 0 /* 12.5 Hz */
#define ADXL362_ODR_25_HZ 1 /* 25 Hz */
#define ADXL362_ODR_50_HZ 2 /* 50 Hz */
#define ADXL362_ODR_100_HZ 3 /* 100 Hz */
#define ADXL362_ODR_200_HZ 4 /* 200 Hz */
#define ADXL362_ODR_400_HZ 5 /* 400 Hz */
/* ADXL362_REG_POWER_CTL definitions */
#define ADXL362_POWER_CTL_RES (1 << 7)
#define ADXL362_POWER_CTL_EXT_CLK (1 << 6)
#define ADXL362_POWER_CTL_LOW_NOISE(x) (((x) & 0x3) << 4)
#define ADXL362_POWER_CTL_WAKEUP (1 << 3)
#define ADXL362_POWER_CTL_AUTOSLEEP (1 << 2)
#define ADXL362_POWER_CTL_MEASURE(x) (((x) & 0x3) << 0)
/* ADXL362_POWER_CTL_LOW_NOISE(x) options */
#define ADXL362_NOISE_MODE_NORMAL 0
#define ADXL362_NOISE_MODE_LOW 1
#define ADXL362_NOISE_MODE_ULTRALOW 2
/* ADXL362_POWER_CTL_MEASURE(x) options */
#define ADXL362_MEASURE_STANDBY 0
#define ADXL362_MEASURE_ON 2
/* ADXL362_REG_SELF_TEST */
#define ADXL362_SELF_TEST_ST (1 << 0)
/* ADXL362 device information */
#define ADXL362_DEVICE_AD 0xAD
#define ADXL362_DEVICE_MST 0x1D
#define ADXL362_PART_ID 0xF2
/* ADXL362 Reset settings */
#define ADXL362_RESET_KEY 0x52
/* MACROS -------------------------------------------------------------------- */
/* CONSTANTS ----------------------------------------------------------------- */
/* GLOBAL VARIABLES ----------------------------------------------------------- */
/* GLOBAL FUNCTIONS ----------------------------------------------------------- */
/*! Initializes the device. */
unsigned char ADXL362_Init(void);
/*! Writes data into a register. */
void ADXL362_SetRegisterValue(unsigned char registerValue,
unsigned char registerAddress,
unsigned char bytesNumber);
/*! Performs a burst read of a specified number of registers. */
void ADXL362_GetRegisterValue(unsigned char *pReadData,
unsigned char registerAddress,
unsigned char bytesNumber);
/*! Reads multiple bytes from the device's FIFO buffer. */
void ADXL362_GetFifoValue(unsigned char *pBuffer, unsigned short bytesNumber);
/*! Resets the device via SPI communication bus. */
void ADXL362_SoftwareReset(void);
/*! Places the device into standby/measure mode. */
void ADXL362_SetPowerMode(unsigned char pwrMode);
/*! Selects the measurement range. */
void ADXL362_SetRange(unsigned char gRange);
/*! Selects the Output Data Rate of the device. */
void ADXL362_SetOutputRate(unsigned char outRate);
/*! Reads the 3-axis raw data from the accelerometer. */
void ADXL362_GetXyz(short *x, short *y, short *z);
/*! Reads the temperature of the device. */
float ADXL362_ReadTemperature(void);
/*! Configures the FIFO feature. */
void ADXL362_FifoSetup(unsigned char mode,
unsigned short waterMarkLvl,
unsigned char enTempRead);
/*! Configures activity detection. */
void ADXL362_SetupActivityDetection(unsigned char refOrAbs,
unsigned short threshold,
unsigned char time);
/*! Configures inactivity detection. */
void ADXL362_SetupInactivityDetection(unsigned char refOrAbs,
unsigned short threshold,
unsigned short time);
void ADXL362_Set(void);
/* 芯片ID读取 */
uint16_t ADXL362_ReadID(void);
void ADXL362_GetData(int16_t *Xdata,int16_t *Ydata,int16_t *Zdata,int16_t *Tdata);
/* 唤醒模式初始化 */
void ADXL362_WakeUpMode( void );
#ifdef __cplusplus
}
#endif
#endif /* __ADXL362_H__ */
/**
******************************************************************************
* Copyright(C) 2016-2026 GDKY All Rights Reserved
*
* @file ADXL362Driver.c
* @author YSHUN
* @version V1.00
* @date 2020.02.05
* @brief 硬件层驱动处理程序.
******************************************************************************
*/
/* INCLUDES ------------------------------------------------------------------- */
#include "ADXL362.h"
/**
* @brief 唤醒模式初始化
* @retval None
*/
void ADXL362_WakeUpMode( void )
{
/* 1、写入十进制250 (0xFA)到寄存器0x20,写入0到寄存器0x21:将运动阈值设为250 mg */
// ADXL362_SetRegisterValue( 0xFA, 0x20, 1 );
ADXL362_SetRegisterValue( 0x32, 0x20, 1 );
/* 2、写入十进制150 (0x96)到寄存器0x23,写入0到寄存器0x24:将静止阈值设为150 mg */
// ADXL362_SetRegisterValue( 0x96, 0x23, 1 );
ADXL362_SetRegisterValue( 0x32, 0x20, 1 );
/* 3、写入十进制30 (0x1E)到寄存器0x25:将静止定时器设为30个样本或约5秒 */
ADXL362_SetRegisterValue( 0x1E, 0x25, 1 );
// ADXL362_SetRegisterValue( 0x10, 0x25, 1 );
/* 4、写入0x3F到寄存器0x27:配置环路模式的运动检测并使能相对运动和静止检测 */
ADXL362_SetRegisterValue( 0x3F, 0x27, 1 );
/* 5、写入0x40到寄存器0x2B:将AWAKE位映射到INT2。INT2引脚与开关的栅极相连 */
ADXL362_SetRegisterValue( 0x40, 0x2B, 1 );
/* 6、写入0x0A到寄存器0x2D:开始在唤醒模式下进行测量*/
ADXL362_SetRegisterValue( 0x0A, 0x2D, 1 );
}
/**
* @brief 唤醒模式初始化
* @retval None
*/
void ADXL632_WakeMode(void)
{
/* 设置设备为待机模式,先进入待机模式配置将不会影响到传感器数据 */
ADXL362_SetPowerMode(0);
/* 加速计的输出数据速率设置为: 12.5 Hz. */
ADXL362_SetOutputRate(ADXL362_ODR_12_5_HZ);
/* 测量范围设置为4g */
ADXL362_SetRange(ADXL362_RANGE_4G);
/* 失能中断输出 */
ADXL362_SetRegisterValue(ADXL362_REG_INTMAP1, 0, 1);
ADXL362_SetRegisterValue(ADXL362_REG_INTMAP2, 0, 1);
/* 运动/静止控制寄存器配置,配置为环路模式内部中断信号 */
ADXL362_SetRegisterValue(ADXL362_ACT_INACT_CTL_LINKLOOP(ADXL362_MODE_LOOP) \
| ADXL362_ACT_INACT_CTL_INACT_EN \
| ADXL362_ACT_INACT_CTL_ACT_EN ,
ADXL362_REG_ACT_INACT_CTL, 1);
/* 设置运动状态阈值 */
ADXL362_SetupActivityDetection(1, 30, 1);
/* 设置静止状态阈值 */
ADXL362_SetupInactivityDetection(1, 700, 25);
/* FIFO缓冲区设置 */
/* 输出中断使能,设置INT1为运动中断 INT2为唤醒中断*/
ADXL362_SetRegisterValue(ADXL362_INTMAP1_ACT, ADXL362_REG_INTMAP1, 1);
ADXL362_SetRegisterValue(ADXL362_INTMAP2_INACT, ADXL362_REG_INTMAP2, 1);
/* 进入测量模式,开始测量过程 */
ADXL362_SetPowerMode(1);
// ADXL362_SetRegisterValue(0xC0, ADXL362_REG_POWER_CTL, 1);
}
/**
* @brief 初始化与设备的通信,并通过读取设备id检查部件是否存在
* @param
* @retval 1 成功
* 0 失败
*/
unsigned char ADXL362_Init(void)
{
unsigned char regValue = 0;
unsigned char status = 0;
/* SPI Init */
// MX_SPI1_Init();
// ADXL362_SoftwareReset();
ADXL362_GetRegisterValue(®Value, ADXL362_REG_PARTID, 1);
if((regValue != ADXL362_PART_ID))
{
status = 0;
}
else
{
status = 1;
}
ADXL362_WakeUpMode( );
return status;
}
/**
* @brief 写数据到寄存器
* @param registerValue - 写数据值
* @param registerAddress - 寄存器地址
* @param bytesNumber - 字节数. Accepted values: 0 - 1
* @retval None
*/
void ADXL362_SetRegisterValue(unsigned char registerValue,
unsigned char registerAddress,
unsigned char bytesNumber)
{
uint8_t m_reg_cmd = 0;
m_reg_cmd = ADXL362_WRITE_REG;
if(registerAddress > ADXL362_REG_SELF_TEST)
{
return;
}
Clr_Cs();
HAL_SPI_Transmit(&hspi1, &m_reg_cmd, 1, 1000);
HAL_SPI_Transmit(&hspi1, ®isterAddress, 1, 1000);
HAL_SPI_Transmit(&hspi1, ®isterValue, bytesNumber, 1000);
Set_Cs();
}
/**
* @brief 读数据从寄存器
* @param pReadData - 读缓冲区
* @param registerAddress - 寄存器地址
* @param bytesNumber - 字节数
* @retval None
*/
void ADXL362_GetRegisterValue(unsigned char* pReadData,
unsigned char registerAddress,
unsigned char bytesNumber)
{
uint8_t m_reg_addr = 0;
uint8_t m_reg_cmd = 0;
m_reg_addr = registerAddress;
m_reg_cmd = ADXL362_READ_REG;
if(pReadData == NULL)
{
return;
}
if(m_reg_cmd > ADXL362_REG_SELF_TEST)
{
return;
}
Clr_Cs();
HAL_SPI_Transmit(&hspi1, &m_reg_cmd, 1, 1000);
HAL_SPI_Transmit(&hspi1, &m_reg_addr, 1, 1000);
HAL_SPI_Receive(&hspi1, pReadData, bytesNumber, 1000);
Set_Cs();
}
/**
* @brief 从设备的FIFO缓冲区读取多个字节
* @param pBuffer - 存储读取字节缓冲区
* @param bytesNumber - 字节数
* @retval None
*/
void ADXL362_GetFifoValue(unsigned char* pBuffer, unsigned short bytesNumber)
{
uint8_t m_reg_cmd = 0;
m_reg_cmd = ADXL362_WRITE_FIFO;
if(pBuffer == NULL)
{
return;
}
Clr_Cs();
HAL_SPI_Transmit(&hspi1, &m_reg_cmd, 1, 1000);
HAL_SPI_Receive(&hspi1, pBuffer, bytesNumber, 1000);
Set_Cs();
}
/**
* @brief 软复位
*
* @retval None
*/
void ADXL362_SoftwareReset(void)
{
ADXL362_SetRegisterValue(ADXL362_RESET_KEY, ADXL362_REG_SOFT_RESET, 1);
}
/**
* @brief 芯片ID读取
*
* @retval 设备ID(默认为0xAD)
*/
uint16_t ADXL362_ReadID(void)
{
uint8_t defID = 0;
/* 读取器件ID,默认0xAD */
ADXL362_GetRegisterValue(&defID, ADXL362_REG_DEVID_AD, 1);
return defID;
}
/**
* @brief 将设备置于待机/测量模式
* @param pwrMode - Power mode.
* Example: 0 - standby mode.
* 1 - measure mode.
* @retval None
*/
void ADXL362_SetPowerMode(unsigned char pwrMode)
{
unsigned char oldPowerCtl = 0;
unsigned char newPowerCtl = 0;
ADXL362_GetRegisterValue(&oldPowerCtl, ADXL362_REG_POWER_CTL, 1);
newPowerCtl = oldPowerCtl & ~ADXL362_POWER_CTL_MEASURE(0x3);
newPowerCtl = newPowerCtl |
(pwrMode * ADXL362_POWER_CTL_MEASURE(ADXL362_MEASURE_ON));
ADXL362_SetRegisterValue(newPowerCtl, ADXL362_REG_POWER_CTL, 1);
}
/**
* @brief 测量范围选择
* @param gRange - Range option.
* Example: ADXL362_RANGE_2G - +-2 g
* ADXL362_RANGE_4G - +-4 g
* ADXL362_RANGE_8G - +-8 g
* @retval None
*/
void ADXL362_SetRange(unsigned char gRange)
{
unsigned char oldFilterCtl = 0;
unsigned char newFilterCtl = 0;
ADXL362_GetRegisterValue(&oldFilterCtl, ADXL362_REG_FILTER_CTL, 1);
newFilterCtl = oldFilterCtl & ~ADXL362_FILTER_CTL_RANGE(0x3);
newFilterCtl = newFilterCtl | ADXL362_FILTER_CTL_RANGE(gRange);
ADXL362_SetRegisterValue(newFilterCtl, ADXL362_REG_FILTER_CTL, 1);
}
/**
* @brief 选择设备的输出数据速率
* @param outRate - Output Data Rate option.
* Example: ADXL362_ODR_12_5_HZ - 12.5Hz
* ADXL362_ODR_25_HZ - 25Hz
* ADXL362_ODR_50_HZ - 50Hz
* ADXL362_ODR_100_HZ - 100Hz
* ADXL362_ODR_200_HZ - 200Hz
* ADXL362_ODR_400_HZ - 400Hz
* @retval None
*/
void ADXL362_SetOutputRate(unsigned char outRate)
{
unsigned char oldFilterCtl = 0;
unsigned char newFilterCtl = 0;
ADXL362_GetRegisterValue(&oldFilterCtl, ADXL362_REG_FILTER_CTL, 1);
newFilterCtl = oldFilterCtl & ~ADXL362_FILTER_CTL_ODR(0x7);
newFilterCtl = newFilterCtl | ADXL362_FILTER_CTL_ODR(outRate);
ADXL362_SetRegisterValue(newFilterCtl, ADXL362_REG_FILTER_CTL, 1);
}
/**
* @brief 从加速度计读取3轴原始数据
*
* @param x - Stores the X-axis data(as two's complement).
* @param y - Stores the X-axis data(as two's complement).
* @param z - Stores the X-axis data(as two's complement).
*
* @retval None
*/
void ADXL362_GetXyz(short* x, short* y, short* z)
{
unsigned char xyzValues[6] = {0, 0, 0, 0, 0, 0};
ADXL362_GetRegisterValue(xyzValues, ADXL362_REG_XDATA_L, 6);
*x = ((short)xyzValues[1] << 8) + xyzValues[0];
*y = ((short)xyzValues[3] << 8) + xyzValues[2];
*z = ((short)xyzValues[5] << 8) + xyzValues[4];
}
/**
* @brief 读设备温度
*
* @retval tempCelsius - 温度(摄氏度)
*/
float ADXL362_ReadTemperature(void)
{
unsigned char rawTempData[2] = {0, 0};
short signedTemp = 0;
float tempCelsius = 0;
ADXL362_GetRegisterValue(rawTempData, ADXL362_REG_TEMP_L, 2);
signedTemp = (short)(rawTempData[1] << 8) + rawTempData[0];
tempCelsius = (float)signedTemp * 0.065;
return tempCelsius;
}
/**
* @brief 配置FIFO特征
* @param mode - 可选择模式
* Example: ADXL362_FIFO_DISABLE - FIFO 失能.
* ADXL362_FIFO_OLDEST_SAVED - Oldest saved mode.
* ADXL362_FIFO_STREAM - Stream mode.
* ADXL362_FIFO_TRIGGERED - Triggered mode.
* @param waterMarkLvl - 指定要存储在FIFO中的样本数.
* @param enTempRead - 将温度数据存储到FIFO
* Example: 1 - temperature data is stored in the FIFO
* together with x-, y- and x-axis data.
* 0 - temperature data is skipped.
* @retval None
*/
void ADXL362_FifoSetup(unsigned char mode,
unsigned short waterMarkLvl,
unsigned char enTempRead)
{
unsigned char writeVal = 0;
writeVal = ADXL362_FIFO_CTL_FIFO_MODE(mode) |
(enTempRead * ADXL362_FIFO_CTL_FIFO_TEMP) |
ADXL362_FIFO_CTL_AH;
ADXL362_SetRegisterValue(writeVal, ADXL362_REG_FIFO_CTL, 1);
ADXL362_SetRegisterValue(waterMarkLvl, ADXL362_REG_FIFO_SAMPLES, 2);
}
/**
* @brief 配置活动检测
* @param refOrAbs - 参考/绝对 活动选择
* Example: 0 - absolute mode.
* 1 - referenced mode.
* @param threshold - 11-bit unsigned value that the adxl362 samples are
* compared to.
* @param time - 8-bit value written to the activity timer register. The amount
* of time (in seconds) is: time / ODR, where ODR - is the output
* data rate.
* @retval None.
*/
void ADXL362_SetupActivityDetection(unsigned char refOrAbs,
unsigned short threshold,
unsigned char time)
{
unsigned char oldActInactReg = 0;
unsigned char newActInactReg = 0;
/* Configure motion threshold and activity timer. */
ADXL362_SetRegisterValue((threshold & 0x7FF), ADXL362_REG_THRESH_ACT_L, 2);
ADXL362_SetRegisterValue(time, ADXL362_REG_TIME_ACT, 1);
/* Enable activity interrupt and select a referenced or absolute
configuration. */
ADXL362_GetRegisterValue(&oldActInactReg, ADXL362_REG_ACT_INACT_CTL, 1);
newActInactReg = oldActInactReg & ~ADXL362_ACT_INACT_CTL_ACT_REF;
newActInactReg |= ADXL362_ACT_INACT_CTL_ACT_EN |
(refOrAbs * ADXL362_ACT_INACT_CTL_ACT_REF);
ADXL362_SetRegisterValue(newActInactReg, ADXL362_REG_ACT_INACT_CTL, 1);
}
/**
* @brief 配置不活动检测
* @param refOrAbs - 参考/绝对不活动选择
* Example: 0 - absolute mode.
* 1 - referenced mode.
* @param threshold - 11-bit unsigned value that the adxl362 samples are
* compared to.
* @param time - 16-bit value written to the inactivity timer register. The
* amount of time (in seconds) is: time / ODR, where ODR - is the
* output data rate.
*
* @retval None
*/
void ADXL362_SetupInactivityDetection(unsigned char refOrAbs,
unsigned short threshold,
unsigned short time)
{
unsigned char oldActInactReg = 0;
unsigned char newActInactReg = 0;
/* Configure motion threshold and inactivity timer. */
ADXL362_SetRegisterValue((threshold & 0x7FF),
ADXL362_REG_THRESH_INACT_L,
2);
ADXL362_SetRegisterValue(time, ADXL362_REG_TIME_INACT_L, 2);
/* Enable inactivity interrupt and select a referenced or absolute
configuration. */
ADXL362_GetRegisterValue(&oldActInactReg, ADXL362_REG_ACT_INACT_CTL, 1);
newActInactReg = oldActInactReg & ~ADXL362_ACT_INACT_CTL_INACT_REF;
newActInactReg |= ADXL362_ACT_INACT_CTL_INACT_EN |
(refOrAbs * ADXL362_ACT_INACT_CTL_INACT_REF);
ADXL362_SetRegisterValue(newActInactReg, ADXL362_REG_ACT_INACT_CTL, 1);
}
使用芯片的运动唤醒模式功能,通过映射唤醒信号到中断INT2引脚,控制单片机发送数据。
唤醒模式非常适合进行简单的有无运动检测,其功耗极低(2.0 V电源电压时仅270 nA)。唤醒模式对于实现运动激活的开关操作特别有用,系统其余部分只有在检测到运动之后才激活。
唤醒模式仅以大约每秒6次的频率测量加速度以确定是否发生运动,从而将功耗降至非常低的水平。如果检测到运动,加速度计可以通过如下方式自治响应:
在唤醒模式下,除运动定时器以外的所有其它加速计功能都可以使用。所有寄存器都可以访问,实时数据可以读出和/或存入FIFO。
AWAKE位用于指示ADXL362处于唤醒还是休眠状态。当器件运动时,器件唤醒;当器件静止时,器件休眠。
唤醒信号可以映射到INT1或INT2引脚,该引脚可以用作状态输出,用以根据加速度计的唤醒状态,连接或断开下游电路的电源。配合环路模式时,此配置可实现自治运动激活的开关,如图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-miSyGGRd-1584185336842)(https://raw.githubusercontent.com/WuliYongShun/PictureHouse/master/img/20200313172247.png)]
如果下游电路的开启时间是可接受的,此运动开关配置可以消除应用其余部分的待机功耗,从而大幅降低系统级功耗。此待机功耗常常超过ADXL362的正常工作功耗。
ADXL362的特性使它非常适合用作自治运动开关。下面的示例实现了一个开关,配置好后,它不需要主机处理器的干预,就能灵巧地管理系统电源。本例中,唤醒信号映射到INT2引脚,用以驱动高边功率开关(如ADP195等)来控制下游电路的电源,我们这里用中断信号唤醒单片机并,通过485向另一块电路板发送数据。
程序启动流程
假设使用±2 g测量范围和唤醒工作模式
对应相关程序代码如下:
void ADXL362_WakeUpMode(void)
{
/* 1、写入十进制250 (0xFA)到寄存器0x20,写入0到寄存器0x21:将运动阈值设为250 mg。 */
ADXL362_SetRegisterValue( 0xFA, 0x20, 1 );
/* 2、写入十进制150 (0x96)到寄存器0x23,写入0到寄存器0x24:将静止阈值设为150 mg。 */
ADXL362_SetRegisterValue( 0x96, 0x23, 1 );
/* 3、写入十进制30 (0x1E)到寄存器0x25:将静止定时器设为30个样本或约5秒。 */
ADXL362_SetRegisterValue( 0x1E, 0x25, 1 );
/* 4、写入0x3F到寄存器0x27:配置环路模式的运动检测并使能相对运动和静止检测。 */
ADXL362_SetRegisterValue( 0x3F, 0x27, 1 );
/* 5、写入0x40到寄存器0x2B:将AWAKE位映射到INT2。INT2引脚与开关的栅极相连。 */
ADXL362_SetRegisterValue( 0x40, 0x2B, 1 );
/* 6、写入0x0A到寄存器0x2D:开始在唤醒模式下进行测量。*/
ADXL362_SetRegisterValue( 0x0A, 0x2D, 1 );
}
进过验证传感器正常,唤醒功能正常同时该传感器作为动作开关可以根据’ 0x20,和0x23 '设置动作阈值,来改变传感器的灵敏度。
需要注意的是,需要按照参考手册的时序进行操作
后续更新