ADXL362加速度传感器使用记录

ADXL362是ADI公司的加速度传感器,这个产品在小米手环里被用到了。它的核心技术是超级低功耗检测运动、加速度、静止这些信息。

它里面有几种模式:

1)默认模式

传感器刚起来时进入默认状态,此时运动和静止的状态是不使能的。如果用户使能了运动和静止功能,静止和运动两种检测皆可以被检测,并且可以触发中断。处理器必须处理中断。

实际将寄存器ACT_INACT_CTL寄存器设置为Default Mode(代码中是ADXL362_MODE_DEFAULT),允许运动和静止检测和中断,但实际上试了不行。

2)Link模式

LINK模式下,运动和静止检测链接在一起。可以配合中断检测。如果需要连续检测运动/静止(可以在中断里查看AWAKE位判断是检测到运动还是静止),这个方法可以。

特别要注意:在中断处理函数处理完后,退出来之前,一定要再读一次ADXL362的STATUS(读取这个STATUS可以把ADXL362内部的中断信息清空),否则有可能出现无法再进中断的危险。这个估计是ADXL362的一个重大bug。但是实际测试发现片子存在不一致性,即有些片子即使在退出中断前再读一次STATUS,仍然还存在无法再进中断的风险。

下面是读取STATUS清空ACT和INACT中断信息的文档中的依据。

3)LOOP模式

LOOP模式和LINK模式很像。文档资料里说不需要中断服务。但实际上是可以用中断一起配合使用的。

但是它的问题和LINK一样,存在永远无法进入中断的问题。这个BUG的现象和LINK一模一样。解决办法是退出来之前,一定要再读一次ADXL362的STATUS(读取这个STATUS可以把ADXL362内部的中断信息清空)。LOOP模式的好处是貌似不存在不一致性,也就是片子的一致性可以。

因此,强烈建议选LOOP模式。

现在解释下这个现象产生的过程(在INT1中断引脚的处理函数里):

void EXTI_IRQHandler()
{

   unsigned char adxl362_status = 0;
   ADXL362_GetRegisterValue(&adxl362_status, ADXL362_REG_STATUS, 1);
   
   if(adxl362_status & ADXL362_STATUS_AWAKE)
   {// 检测到运动
    
    // (A)
   }
   else
   {// 检测到静止

    // (B)
   }
   
   EXTI->PR = ((uint32_t)0x00000400);
   // 下面这句必须添加,以防ADXL362不工作 
   ADXL362_GetRegisterValue(&adxl362_status, ADXL362_REG_STATUS, 1);//(C)
}

上面的代码是用来不断检测运动和静止的代码。

如果ADXL362检测到静止,然后在处理静止的时候(B)位置(还未退出中断)发生了运动事件(ADXL362在这么短时间内检测到运动了),那么如果没有(C)代码,那么会导致无法在进中断。同样的,如果在检测到运动的时候(A)发生了静止事件(还未退出中断),那么同样的,如果没有(C)代码,会导致后续无法再进中断。

下面是比较好的连续检测静止和运动的初始代码。

void ADXL362(void)
{
    unsigned char adxl362_status;
    /* Init device. */
    if(ADXL362_Init())
    {
      /* Put the device in standby mode. */
       ADXL362_SetPowerMode(0);
      /* Set accelerometer's output data rate to: 12.5 Hz. */
      ADXL362_SetOutputRate(ADXL362_ODR_12_5_HZ);
      /* Setup the activity and inactivity detection. */
      ADXL362_SetRegisterValue(
                    ADXL362_ACT_INACT_CTL_LINKLOOP(ADXL362_MODE_LINK),
                    ADXL362_REG_ACT_INACT_CTL,
                    1);
      ADXL362_SetupActivityDetection(1, 50, 3);     // 检测参考阀值: 200mg,  检测时间: 第三个参数值 / 12.5 s
      ADXL362_SetupInactivityDetection(1, 200, 36); //  检测参考阀值: 200mg,  检测时间: 第三个参数值 / 12.5 s
      ADXL362_SetRegisterValue(0x30, ADXL362_REG_INTMAP1, 1);
      /* Start the measurement process. */
      //ADXL362_SetPowerMode(1);
      
      ADXL362_SetRegisterValue(ADXL362_POWER_CTL_MEASURE(ADXL362_MEASURE_ON), ADXL362_REG_POWER_CTL, 1);
      
      /* Clear ACT and INACT bits by reading the Status Register. */
      ADXL362_GetRegisterValue(&adxl362_status,
                               ADXL362_REG_STATUS,
                               1);
      ACCIoInit();
    }
}

片子的运动和静止需要设置检测时间,这个检测时间和片子的ODR配置相关。公式是:

Time = TIME_ACT/ODR.

比如上面的代码TIME_ACT是3,选的ODR是12.5Hz,那么检测运动的时间是3/12.5Hz。

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值