资讯详情

STC8H开发(六): SPI驱动ADXL345三轴加速度检测模块

目录

  • STC8H开发(1): 在Keil5中配置和使用FwLib_STC8包装库(图文详解)
  • STC8H开发(二): 在Linux VSCode配置和使用FwLib_STC8包装库(图文详解)
  • STC8H开发(三): 基于FwLib_STC8的模数转换ADC介绍和演示用例说明
  • STC8H开发(4): FwLib_STC8 封装库的介绍和使用注意事项
  • STC8H开发(五): SPI驱动nRF24L01无线模块
  • STC8H开发(6): SPI驱动ADXL345三轴加速试验模块
  • STC8H开发(7): I2C驱动MPU6050三轴加速度 三轴角速度检测模块

ADXL345

ADXL345是一种常见的3轴加速度计, Analog Device生产. 13位分辨率, ±16 g测量范围, 分辨率3.9 mg/LSB. 可通过SPI(I2C接口访问. 主要用于倾斜检测, 静态重力加速度测量, 以及由运动或冲击引起的动态加速度测量. 能量不到1.0°倾斜角度变化. 可单击, 双击, 中断自由落体等情况.

模块与STC8H的接线

市场上的模块, 一般是8个pin脚, 在使用SPI在接线方式下, 与STC8H接线方式如下. 除了SPI用到的CS, MISO, MOSI, SCLK以外, STC8H还需要提供两个中断输入, 因为INT0, INT1已经被SPI接口占用, 所以只能用INT2和INT3, 这两个外部中断只支持低电平触发, 所以在ADXL需要在345中设置中断输出active low.

 * GND       -> GND               G  * VDD(Vcc)  -> VCC               V  * CS        -> GPIO OUT P35      34  * INT1      -> GPIO IN  P36 INT2 35  * INT2      -> GPIO IN  P37 INT3 36  * SDO       -> MISO     P33      30  * SDI/SDA   -> MOSI     P34      31  * SCL       -> SCLK     P32      29 

模块与STC8H的SPI通信

SPI初始化和大多数SPI设备不同, 使用的初始参数是

  • 空闲时钟高电平
  • 数据顺序 MSB 先发送
  • 使用时钟相位数据
void SPI_Init(void) { 
             // ADXL345, SPI CLK max frequency is 5MHz     SPI_SetClockPrescaler(SPI_ClockPreScaler_16);     // Clock is high when idle     SPI_SetClockPolarity(HAL_State_ON);     // Data transfer is driven by lower SS pin     SPI_SetClockPhase(SPI_ClockPhase_TrailingEdge);     // MSB first     SPI_SetDataOrder(SPI_DataOrder_MSB);     // Define the output pins     SPI_SetPort(SPI_AlterPort_P35_P34_P33_P32);     // Ignore SS pin, use MSTR to swith between master/slave mode     SPI_IgnoreSlaveSelect(HAL_State_ON);     // Master mode     SPI_SetMasterMode(HAL_State_ON);     // Start SPI     SPI_SetEnabled(HAL_State_ON); } 

可使用以前多字节发送的接口, 这里需要注意的是

  1. ADXL345写读同一寄存器地址, 通过地址的D7. 需要阅读操作D7置1
  2. ADXL345支持一次读取多字节, 即burst read, 通过地址的D6(次高位)区分, 读多字节需要D6置1
uint8_t ADXL345_ReadByte(uint8_t addr) { 
             ADXL345_CS = 0;     xbuf
       
        [
        0
        ] 
        = addr 
        | 
        0x80
        ; xbuf
        [
        1
        ] 
        = 
        0xFF
        ; 
        SPI_TxRxBytes
        (xbuf
        , 
        2
        )
        ; ADXL345_CS 
        = 
        1
        ; 
        return xbuf
        [
        1
        ]
        ; 
        } 
        uint16_t 
        ADXL345_ReadInt
        (
        uint8_t addr
        ) 
        { 
          ADXL345_CS 
        = 
        0
        ; xbuf
        [
        0
        ] 
        = addr 
        | 
        0xC0
        ; xbuf
        [
        1
        ] 
        = 
        0xFF
        ; xbuf
        [
        2
        ] 
        = 
        0xFF
        ; 
        SPI_TxRxBytes
        (xbuf
        , 
        3
        )
        ; ADXL345_CS 
        = 
        1
        ; 
        return 
        *
        (
        (
        uint16_t 
        *
        )
        &xbuf
        [
        1
        ]
        )
        ; 
        } 
        void 
        ADXL345_WriteByte
        (
        uint8_t addr
        , 
        uint8_t dat
        ) 
        { 
          ADXL345_CS 
        = 
        0
        ; xbuf
        [
        0
        ] 
        = addr
        ; xbuf
        [
        1
        ] 
        = dat
        ; 
        SPI_TxRxBytes
        (xbuf
        , 
        2
        )
        ; ADXL345_CS 
        = 
        1
        ; 
        } 
       

模块的中断及设置

中断类型

模块提供多种中断, 包含

DATA READY 数据待读取

当三轴数据采集完成时, 会产生这个中断, 采集的速度是由决定的, 默认为100Hz, 即每秒100次采集. 当中断产生后, 必须通过读取X, Y, Z轴的采样数据才能清除中断, 如果没有读取动作, 就不会再产生中断

SINGLE TAP 单次敲击

当采样数据满足预设的敲击加速度和持续时长时, 会产生这个中断, 产生中断后, 必须通过读取中断源寄存器将中断清除, 否则不会再产生中断.

DOUBLE TAP 双击

同上, 当单次敲击满足预设的时间间隔和时间窗口时, 会产生这个中断, 需要通过读取中断源寄存器将中断清除

ACTIVITY 活动和 INACTIVITY 非活动

加速度值大于THRESH_ACT寄存器(地址0x24)存储值时, Activity(活动)中断置位. 加速度值小于THRESH_INACT寄存器(地址0x25)的存储值时, Inactivity(静止)位置位, TIME_INACT最大值为255秒.

需要通过读取中断源寄存器清除中断

FREE FALL 自由落体

加速度值小于THRESH_FF寄存器(地址0x28)的存储值时, FREE_FALL置位. 大于TIME_FF寄存器(地址0x29)所有轴(逻辑与)所规定的时间. FREE_FALL中断不同于静止中断, 因为所有轴始终参与, 并为逻辑“和”的形式,定时器周期小得多(最大值 1.28秒), 始终为直流耦合操作模式.

WATERMARK 水位

在FIFO模式和流模式下, FIFO中的采样数与FIFO_CTL寄存器(地址0x38)采样数位规定的数量相等时, 水位中断置位. 此后FIFO继续收集样本直到填满, 然后停止收集数据. FIFO停止收集数据后, 该器件继续工作, 因此, FIFO填满 时, 敲击检测等功能可以使用

OVERRUN 溢出

当有新采样点更新了未被读取的前次采样点时, Overrun中断置位. Overrun功能与FIFO的工作模式有关:

  1. 当FIFO工作在Bypass模式下, 如果有新采样点更新了DATAX、 DATAY和DATAZ寄存器(地址0x32至0x37)里的数值,则Overrun中断置位
  2. 在其他模式下, 只有FIFO被存满时, Overrun中断才会置位.
  3. 读取FIFO内容时,Overrun位自动清零

中断设置

对应的寄存器有

  • 寄存器0x2E—INT_ENABLE 这里设置各个中断的开启和关闭
  • 寄存器0x2F—INT_MAP (R/W) 这里设置中断输出到INT1还是INT2, 对应的位为0输出到INT1, 为1输出到INT2
  • 寄存器0x30—INT_SOURCE(只读) 产生中断时, 中断对应的位会被置1, 读取这里的值可以判断中断来源并清除中断

敲击检测参数说明

ADXL345的敲击检测和双击检测有5个参数可以设置, 如果设置得不正确, 可能会完全不产生中断

寄存器0x2A—TAP_AXES

用于设置参与检测的轴, 测试阶段可以将三个轴都打开

寄存器0x1D THRESH_TAP

用于设置敲击判断的加速度阈值, 运动时检测到的加速度会与THRESH_TAP的值进行比较, 超过即满足. 需要设置合适的值以便实现正常敲击检测.

从0到255, 间隔为 62.5 mg/LSB(即0xFF = 16 g), 开启敲击检测后这个值不能为0, 否则芯片会不能正常工作.

实际测试中, 值不能太小, 否则一直在触发, 值也不能太大, 否则无论怎么敲击也检测不到中断, 经验值为0x1F到0x35之间, Arduino库使用的是0x28, 对应2.5g加速度.

寄存器0x21 DUR

时间长度值, 运动中, 满足THRESH_TAP加速度强度的采集, 其持续时间与 DUR 的值进行比较, 超过即满足. 需要设置合适的值才能正确检测敲击.

从0到255, 间隔为 625 μs/LSB, 值为0时,禁用单击/双击检测功能.

实际测试中, 值不能太大否则完全检测不到, Arduino库使用的是0x20, 0.02秒, 可以在这个附近调整.

寄存器0x22—Latent

时间长度, 表示在检测到敲击后, 与第二次敲击之间需要满足的间隔长度, 在此间隔时间后开启检测窗口, 能检测出可能的第二次敲击事件.

英文手册的原文 The latent register is eight bits and contains an unsigned time value representing the wait time from the detection of a tap event to the start of the time window (defined by the window register) during which a possible second tap event can be detected.

从0到255, 间隔为 1.25 ms/LSB, 值为0时,禁用双击检测功能

可以根据自己的场景调整, Arduino库使用的是0x50, 对应0.1秒.

寄存器0x23—Window

时间长度, 表示在延迟时间(由Latent寄存器确定)期满后的时间窗口长度,在窗口中开始进行第二次有效敲击。

从0到255, 间隔为 1.25 ms/LSB, 值为0时,禁用双击检测功能

英文手册原文 The window register is eight bits and contains an unsigned time value representing the amount of time after the expiration of the latency time (determined by the latent register) during which a second valid tap can begin.

可以根据自己的场景调整, Arduino库使用的是0xF0, 对应0.3秒.

中断使用的注意事项

  1. 在中断处理中, 要清除中断位
  2. 在初始化后, 一定要清中断, 否则不会产生第一次中断处理, 就一直卡在哪里

下面这段代码就是在进入main循环前的中断清理

// read to clear interrupts, or the counter will never receive interrupts
x = ADXL345_ReadInt(ADXL345_REG_DATAX0);
y = ADXL345_ReadInt(ADXL345_REG_DATAY0);
z = ADXL345_ReadInt(ADXL345_REG_DATAZ0);
x = ADXL345_ReadByte(ADXL345_REG_INT_SOURCE);

检测数据

ADXL345在检测过程中, 根据采样速率不断输出三轴上采样的加速度值, 因为重力加速度的存在, 在调整模块倾斜度时能观察到读数的变化, 对应PCB上标识的三轴方向, 当轴朝向地面时, 读数会达到最大负值, 在背向地面时, 能读到最大正值. 根据三轴采样到的数据, 可以判断(如果当前是静止状态)器件姿态(倾斜度).

这个采样只能得到俯仰角和横滚角数据, 不能得到航向角数据, 如果需要航向角, 还需要有电子罗盘传感器配合.

完整代码

  • GitHub FwLib_STC8/tree/master/demo/spi/adxl345
  • Gitee FwLib_STC8/tree/master/demo/spi/adxl345

标签: 加速度传感器adxl345加速度倾斜度角度传感器芯片

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台