ADXL362加速度传感器使用记录

xiaoxiao2021-03-01  23

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。

转载请注明原文地址: https://www.6miu.com/read-4050069.html

最新回复(0)