配色: 字号:
fall_detector
2013-11-13 | 阅:  转:  |  分享 
  




























































































三轴加速度传感器在跌倒

检测中的应用

作者:NingJia

前言

人们在跌倒后会面临双重危险。显而易见的是跌倒本身可能对

人体产生伤害;另外,如果跌倒后不能得到及时的救助,可能

会使结果更加恶化。例如,许多老年人由于其身体比较虚弱,

自理能力和自我保护能力下降,常常会发生意外跌倒,如果得

不到及时的救助,这种跌倒可能会导致非常严重的后果。有资

料显示,很多严重的后果并不是由于跌倒直接造成的,而是由

于跌倒后,未得到及时的处理和救护。当出现跌倒情况时,如

果能够及时地通知到救助人员,将会大大地减轻由于跌倒而造

成的危害。

不仅是对老人,在很多其他情况下,跌倒的报警也是非常有帮

助的,尤其是从比较高的地方跌倒下来的时候。比如人们在登

山,建筑,擦窗户,刷油漆和修理屋顶的时候。

这促使人们越来越热衷于对跌倒检测以及跌倒预报仪器的研

制。近年来,随着MEMS加速度传感器技术的发展,使得设

计基于三轴加速度传感器的跌倒检测器成为可能。这种跌倒检

测器的基本原理是通过测量佩戴该仪器的个体在运动过程中

的三个正交方向的加速度变化来感知其身体姿态的变化,并通

过算法分析判断该个体是否发生跌倒情况。当个体发生跌倒

时,仪器能够配合GPS模块以及无线发送模块对这一情况进

行定位及报警,以便获得相应的救助。而跌倒检测器的核心部

分就是判断跌倒情况是否发生的检测原理及算法。

ADXL345

1

是ADI公司的一款3轴、数字输出的加速度传感器。

本文将在研究跌倒检测原理的基础上,提出一种基于ADXL345

的新型跌倒检测解决方案。

iMEMS加速度传感器ADXL345

iMEMS半导体技术把微型机械结构与电子电路集成在同一颗

芯片上。iMEMS加速度传感器就是利用这种技术,实现对单轴、

双轴甚至三轴加速度进行测量并产生模拟或数字输出的传感

器。根据不同的应用,加速度传感器的测量范围从几g到几十g

不等。数字输出的加速度传感器还会集成多种中断模式。这些

特性可以为用户提供更加方便灵活的解决方案。

ADXL345是ADI公司最近推出的基于iMEMS技术的3轴、

数字输出加速度传感器。ADXL345具有+/-2,+/-4,+/-8,+/-16g

可变的测量范围;最高13bit分辨率;固定的4mg/LSB灵敏度;

3mm5mm1mm超小封装;40-145uA超低功耗;标准的I2C

或SPI数字接口;32级FIFO存储;以及内部多种运动状态检

测和灵活的中断方式等特性。所有这些特性,使得ADXL345

有助于大大简化跌倒检测算法,使其成为一款非常适合用于跌

倒检测器应用的加速度传感器。本文给出的跌倒检测解决方

案,完全基于ADXL345内部的运动状态检测功能和中断功能,

甚至不需要对加速度的具体数值进行实时读取和复杂的计算

操作,可以使算法的复杂度降至最低。

中断系统

图1给出了ADXL345的系统框图及管脚定义。























图1.ADXL345系统框图及管脚定义

ADXL345具有两个可编程的中断管脚:Int1和Int2。以及

Data_Ready、Single_Tap、Double_Tap、Activity、Inactivity、

Free_Fall、Watermark、Overrun,共计8个中断源。每个中断

源可以独立地使能或禁用,还可以灵活地选择是否映射到Int1

或Int2中断管脚。所有的功能都可以同时使用,只是某些功能

可能需要共用中断管脚。中断功能通过INT_ENABLE寄存器的

相应位来选择使能或禁用,通过INT_MAP寄存器的相应位来选

择映射到Int1管脚或Int2管脚。

中断功能的具体定义如下:

1、Data_Ready-当有新的数据产生时,Data_Ready中断

置位;当没有新的数据时,Data_Ready中断清除。

2、Single_Tap-当加速度值超过一定门限(THRESH_TAP)

并且持续时间小于一定时间范围(DUR)的时候,

Single_Tap中断置位。

3、Double_Tap-当第一次Single_Tap事件发生后,在一定

时间(LATENT)之后,并在一定时间(WINDOW)之

内,又发生第二次Single_Tap事件时,Double_Tap中断

置位。

图2给出了有效的Single_Tap中断和Double_Tap中断的示意

图。



AnalogDialogue43-07www.analog.com/analogdialogue1

3-AXIS

SENSOR

SENSE

ELECTRONICS

DIGITAL

FILTER

ADXL345

SERIAL

INPUT/OUTPUT

INT1

INT2

SDA/SDI/SDIO

SDO/ALT

ADDRESS

SCL/SCLK

GND

ADC

32LEVEL

FIFO

POWER

MANAGEMENT

CONTROL

AND

INTERRUPT

LOGIC

V

S

V

DDI/O

CS

14

SCL/SCLK

7

1

2

3

4

5

6

V

DDI/O

GND

RESERVED

GND

GND

V

S

SDA/SDI/SDIO

SDO/ALTADDRESS

RESERVED

NC

INT2

INT1

13

12

11

10

9

8

CS

+Z

+X

+Y



















































































































图2.Single_Tap和Double_Tap中断示意

4、Activity-当加速度值超过一定门限(THRESH_ACT)

时,Activity中断置位。

5、Inactivity-当加速度值低于一定门限(THRESH_INACT)

并且持续超过一定时间(TIME_INACT)时,Inactivity中

断置位。TIME_INACT可以设定的最长时间为255s。

需要指出的是,对于Activity和Inactivity中断,用户可以针

对X、Y、Z轴来分别进行使能或禁用。比如,可以只使能

X轴的Activity中断,而禁用Y轴和Z轴的Activity中断。

另外,对于Activity和Inactivity中断,用户还可以自由选择

DCcoupled工作方式或者ACcoupled工作方式。其区别

在于,DCcoupled工作方式下,每个采样点的加速度值将

直接与门限(THRESH_ACT或THRESH_INACT)进行

比较,来判断是否发生中断;而ACcoupled工作方式下,

新的采样点将以之前的某个采样点为参考,用两个采样点

的差值与门限(THRESH_ACT或THRESH_INACT)进

行比较,来判断是否发生中断。ACcoupled工作方式下的

Activity检测,是选择检测开始时的那一个采样点作为参

考,以后每个采样点的加速度值都与参考点进行比较。如

果它们的差值超过门限(THRESH_ACT),则Activity中

断置位。ACcoupled工作方式下的Inctivity检测,同样要

选择一个参考点。如果新采样点与参考点的加速度差值超

过门限(THRESH_INACT),参考点会被该采样点更新。

如果新采样点与参考点的加速度差值小于门限

(THRESH_INACT),并且持续超过一定时间

(TIME_INACT),则Inctivity置位。

6、Free_Fall-当加速度值低于一定门限(THRESH_FF)

并且持续超过一定时间(TIME_FF)时,Free_Fall中断

置位。与Inactivity中断的区别在于,Free_Fall中断主要

用于对自由落体运动的检测。因此,X、Y、Z轴总是同

时被使能或禁用;其时间设定也比Inactivity中断中要小很

多,TIME_FF可以设定的最大值为1.28s;而且Free_Fall

中断只能是DCcoupled工作方式。

7、Watermark-当FIFO里所存的采样点超过一定点数

(SAMPLES)时,Watermark中断置位。当FIFO里的采

样点被读取,使得其中保存的采样点数小于该数值

(SAMPLES)时,Watermark中断自动清除。

需要指出的是,ADXL345的FIFO最多可以存储32个采样

点(X、Y、Z三轴数值),且具有Bypass模式、普通FIFO

模式、Stream模式和Trigger模式,一共4种工作模式。

FIFO功能也是ADXL345的一个重要且十分有用的功能。

但是本文后面给出的解决方案中,并没有使用到FIFO功

能,所以,在此不做详细介绍。

8、Overrun-当有新采样点更新了未被读取得前次采样点

时,Overrun中断置位。Overrun功能与FIFO的工作模式

有关,当FIFO工作在Bypass模式下,如果有新采样点更

新了DATAX、DATAY和DATAZ寄存器里的数值,则

Overrun中断置位。当FIFO工作在其他三种模式下,只有

FIFO被存满32点时,Overrun中断才会置位。FIFO里的

采样点被读取后,Overrun中断自动清除。

跌倒过程中的加速度变化特征

对跌倒检测原理的研究主要是找到人体在跌倒过程中的加速

度变化特征。

图3给出的是加速度在不同运动过程中的变化曲线,包括(a)步

行上楼、(b)步行下楼、(c)坐下、(d)起立。假设跌倒检测器被

固定在被测的人体上。其中红色的曲线是Y轴(垂直方向)的

加速度曲线,其正常静止状态下应该为-1g;黑色和黄色的曲

线分别是X轴(前后方向)和Z轴(左右方向)的加速度曲线,

其正常静止状态下应该为0g;绿色的曲线是三轴加速度的矢量

和,其正常静止状态下应该为+1g。



















a.步行上楼



















b.步行下楼



2AnalogDialogue43-07

FIRSTTAP

TIMELIMITFOR

TAPS(DUR)

LATENCY

TIME

(LATENT)

TIMEWINDOWFOR

SECONDTAP(INTVL)

SECONDTAP

SINGLETAP

INTERRUPT

DOUBLETAP

INTERRUPT

THRESHOLD

(THRESH)

X

HIBW

INTERRUPTS

–1024

–768

–512

–256

0

256

512

768

1024

151101151201251301351401

VALUE(256/

g

)

SAMPLES(50/s)

VECTORSUM

Z-AXIS

X-AXIS

Y-AXIS

–1024

–768

–512

–256

0

256

512

768

1024

151101151201251301351401

VALUE(256/

g

)

SAMPLES(50/s)

VECTORSUM

Z-AXIS

X-AXIS

Y-AXIS













































































































c.坐下















d.起立

图3.不同运动过程中的加速度变化曲线

由于老年人的运动相对比较慢,所以在普通的步行过程中,加

速度变化不会很大。最明显的加速度变化就是在坐下动作中Y

轴加速度(和加速度矢量和)上有一个超过3g的尖峰,这个

尖峰是由于身体与椅子接触而产生的。

而跌倒过程中的加速度变化则完全不同。图4给出的是意外跌

倒过程中的加速度变化曲线。通过图4和图3的比较,可以发

现跌倒过程中的加速度变化有4个主要特征,这可以作为跌倒

检测的准则。这4个特这在图4中以红色的方框标注,下面将

对其逐一进行详细介绍。





















图6.自动功率控制回路的功能框图

1.失重:在跌倒的开始都会发生一定的失重现象。在自由

落体的下降过程,这个现象会更加明显,加速度的矢量

和会降低到接近0g,持续时间与自由落体的高度有关。

对于一般的跌倒,失重现象虽然不会有像自由落体那么

明显,但也会发生合加速度小于1g的情况(通常情况下

合加速度应大于1g)。因此,这可以作为跌倒状态的第一

个判断依据。可以由ADXL345的Free_Fall中断来检测。

2.撞击:失重之后,人体发生跌倒的时候会与地面或其他

物体发生撞击,在加速度曲线中会产生一个很大的冲击。

这个冲击可以通过ADXL345的Activity中断来检测。因此,

Free_Fall中断之后,紧接着产生Activity中断是跌倒状态

的第二个判断依据。

3.静止:通常,人体在跌倒后,也就是撞击发生之后,不

可能马上起来,会有短暂的静止状态(如果人因为跌倒

而导致昏迷,甚至可能是较长时间的静止)。表现在加速

度曲线上就是会有一段时间的平稳。这可以通过

ADXL345的Inactivity中断来检测。因此,Activity中断之

后的Inactivity中断是跌倒状态的第三个判断依据。

4.与初始状态比较:跌倒之后,人体会发生翻转,因此人体

的方向会与原先静止站立的姿态(初始状态)不同。这

使得跌倒之后的静止状态下的三轴加速度数值与初始状

态下的三轴加速度不同(见图4)。假设跌倒检测器固定

在被测人体上的某个部位,这样初始状态下的三轴加速

度数值可以认为是已知的(本例中,初始状态为:X轴0g,

Y轴-1g,Z轴0g)。读取Inactivity中断之后的三轴加速度

数据,并与初始状态进行比较。如图4所示,重力加速度

方向由Y轴上的-1g变为了Z轴上的1g,这说明人体发生了

侧向跌倒。因此,跌倒检测的第四个依据就是跌倒后的

静止状态下加速度值与初始状态发生变化,且矢量变化

超过一定的门限值(比如0.7g)。

这四个判断依据综合在一起,构成了整个的跌倒检测算法,可

以对跌倒状态给出报警。当然,还要注意各个中断之间的时间

间隔要在合理的范围之内。比如,除非是从很高的楼顶掉下来,

否则Free_Fall中断(失重)和Activity中断(撞击)之间的时

间间隔不会很长。同样,通常情况下,Activity中断(撞击)

和Inactivity中断(静止)之间的时间间隔也不会很长。本文接

下来会通过一个具体实例给出一组合理的取值。当然,相关中

断的检测门限以及时间参数也可以根据需要而灵活设置。

另外,如果跌倒造成了严重的后果,比如,导致了人的昏迷。

那么人体会在更常的一段时间内都保持静止。这个状态仍然可

以通过Inactivity中断来检测。也就是说,如果发现在跌倒之后

的很长时间内都保持Inactivity状态,可以再次给出一个严重报

警。

典型电路连接

ADXL345和微控制器之间的电路连接非常简单。本文中的测

试平台由ADXL345和微控制器ADuC7026

2

组成。图5给出了

ADXL345和ADuC7026之间的典型电路连接。ADXL345

AnalogDialogue43-073

–1024

–768

–512

–256

0

256

512

768

1024

151101151201251

VALUE(256/

g

)

SAMPLES(50/s)

VECTORSUM

Z-AXIS

X-AXIS

Y-AXIS

–1024

–768

–512

–256

0

256

512

768

1024

151101151201251

VALUE(256/

g

)

SAMPLES(50/s)

VECTORSUM

Z-AXIS

X-AXIS

Y-AXIS

413

21:WEIGHTLESSNESS

2:IMPACT

3:MOTIONLESS

4:INITIALSTATUS

–512

–256

0

256

512

768

1024

151101151201

VALUE(256/

g

)

SAMPLES(50/s)

VECTORSUM

Z-AXIS

X-AXIS

Y-AXIS

































的\CS管脚接高电平,表示ADXL345工作在I2C模式。SDA

和SCL是I2C总线的数据线和时钟线,分别连接到ADuC7026

相应的I2C总线管脚。ADuC7026的一个GPIO管脚连接到

ADXL345的ALT管脚,用来选择ADXL345的I2C地址。

ADXL345的INT1管脚连接到ADuC7026的IRQ输入用来产

生中断信号。

其他的单片机或者处理器都可以采用与图5类似的电路与

ADXL345进行连接。ADXL345还可以工作在SPI模式以获得

更高的数据传输速率。关于SPI工作模式的具体描述,请参考

ADXL345数据手册。

利用ADXL345简化跌倒检测算法

本节将给出以上解决方案的具体算法实现。表1中简要说明了

每个寄存器的作用以及在本算法中的设置值。对于各个寄存中

每一位的具体含义,请参考ADXL345的数据手册。

需要指出的是,表1给出的设置值中,某些寄存器会给出两个

数值,这说明在算法中会切换使用这两个数值,来达到不同的

检测目的。算法的流程图如图6所示。





图5.ADXL345与微控制器之间的典型电路连接



表1.ADXL345寄存器功能说明

地址寄存器名称类型默认值说明设置值设置的功能

0DEVID只读0xE5器件ID只读

1-1CReserved保留,不要操作保留

1DTHRESH_TAP读/写0x00Tap的门限不使用

1EOFSX读/写0x00X轴失调0x06补偿X轴失调,通过初始化校正获得

1FOFSY读/写0x00Y轴失调0xF9补偿Y轴失调,通过初始化校正获得

20OFSZ读/写0x00Z轴失调0xFC补偿Z轴失调,通过初始化校正获得

21DUR读/写0x00Tap的持续时间不使用

22LATENT读/写0x00Tap的延迟时间不使用

23WINDOW读/写0x00Tap的时间窗不使用

24THRESH_ACT读/写0x00Activity的门限0x20/0x08设置Activity的门限为2g或0.5g

25THRESH_INACT读/写0x00Inactivity的门限0x03设置Inactivity的门限为0.1875g

26TIME_INACT读/写0x00Inactivity的时间0x02/0x0A设置Inactivity的时间为2s或10s

27ACT_INACT_CTL读/写0x00Activity/Inactivity使能控制0x7F/0xFF使能X、Y、Z三轴的Activity和Inactivity功能,其中

Inactivity为ACcoupled模式,Activity为DCcoupled

或ACcoupled模式

28THRESH_FF读/写0x00Free-Fall的门限0x0C设置Free-Fall的门限为0.75g

29TIME_FF读/写0x00Free-Fall的时间0x06设置Free-Fall的时间为30ms

2ATAP_AXES读/写0x00Tap/DoubleTap使能控制不使用

2BACT_TAP_STATUS只读0x00Activity/Tap中断轴指示只读

2CBW_RATE读/写0x0A采样率和功耗模式控制0x0A设置采样率为100Hz

2DPOWER_CTL读/写0x00工作模式控制0x00设置为正常工作模式

2EINT_ENABLE读/写0x00中断使能控制0x1C使能Activity、Inactivity、Free-Fall中断

2FINT_MAP读/写0x00中断影射控制0x00所有中断影射到Int1管脚

30INT_SOURCE只读0x00中断源指示只读

31DATA_FORMAT读/写0x00数据格式控制0x0B设置为+/-16g测量范围,13bit右对齐模式,

中断为高电平触发,使用I2C数据接口

32DATAX0只读0x00只读

33DATAX1只读0x00

X轴数据

只读

34DATAY0只读0x00只读

35DATAY1只读0x00

Y轴数据

只读

36DATAZ0只读0x00只读

37DATAZ1只读0x00

Z轴数据

只读

38FIFO_CTL读/写0x00FIFO控制不使用

39FIFO_STATUS只读0x00FIFO状态只读



4AnalogDialogue43-07

ADXL345

V

SCS

SDA/SDI/SDIOSDA

SCL/SCLKSCL

SDO/ALTADDRESSGPIO

INT1IRQ

GNDGND

V

DDI/O

VDD

3.3V

ADuC7026



























































































































图6.算法流程图









算法中,关于各种中断的门限以及时间参数的设置如下所述。

1.初始化后,系统等待Free_Fall中断(失重),这里把

THRESH_FF设为0.75g,把TIME_FF设为30ms。

2.Free_Fall中断产生之后,系统开始等待Activity中断(撞

击),这里把THRESH_ACT设为2g,Activity中断为DC

coupled工作模式。

3.Free_Fall中断(失重)与Activity中断(撞击)之间的时

间间隔设置为200ms。如果超过200ms,则认为无效。

200ms计时需要通过MCU中的定时器来实现。

4.Activity中断产生之后,系统开始等待Inactivity中断(撞

击后的静止),这里把THRESH_INACT设为0.1875g,把

TIME_INACT设为2s,Inactivity中断为ACcoupled工作

模式。

5.在Activity中断产(撞击)生之后的3.5s时间之内,应该

有Inactivity中断(撞击后的静止)产生。如果超时,则认

为无效。3.5s计时需要通过MCU中的定时器来实现。

6.如果Inactivity中断之后的加速度值与初始状态(假设已

知)下数值的矢量差超过0.7g,则说明检测到一次有效的

跌倒,系统会给出一个报警。

7.当检测到跌倒状态之后,为了判断是否在跌倒之后人体有

长时间的静止不动。需要继续检测Activity中断和

Inactivity中断。这里把THRESH_ACT设为0.5g,Activity

中断为ACcoupled工作模式。把THRESH_INACT设为

0.1875g,把TIME_INACT设为10s,Inactivity中断为AC

coupled工作模式。也就是说,如果在10s之内,人体一

直没有任何动作,则会产生Inactivity中断,使系统给出一

个严重报警。而在此期间一旦人体有所动作,则会产生

Activity中断,从而结束整个判断过程。

8.本算法还可以检测出人体从较高的地方跌落。如果

Free_Fall中断连续产生且之间的间隔小于100ms,可以

认为,人体处于连续的跌落状态。如果Free_Fall中断(失

重)连续发生300ms,则说明人体是从超过0.45m的高度

跌落,系统会给出一个跌落的报警。

m45.03.010

2

1

2

1

22

===gtS

本算法已在ADuC7026微控制器中以C语言实现(见附录)。

本文设计了一个实验方案对算法进行验证。实验对向前跌倒,

向后跌倒,向左、右两侧跌倒等不同跌倒姿势以及跌倒后是否

有长时间静止状态的情况分别进行了10次测试,表2中给出

的是相关测试结果。

表2测试结果

跌倒姿势跌倒后长时间静止12345678910

否√√√√√√√√√√向前跌倒

是√









































否√√√√√√√√√√向后跌倒

是√









































否√√√√√√√√√√向左侧跌倒

是√









































否√√√√√√√√√√向右侧跌倒

是√









































注:符号√表示检测到跌倒,符号表示检测到跌倒后的长时间静止。

AnalogDialogue43-075

START

INITIALIZATION

NO

NO

YES

YES

YES

YES

YES

YES

YES

YES

YES

NO

NO

NO

NO

NO

NO

NO

FREE_FALLINTERRUPT

ASSERTED?

ACTIVITYINTERRUPT

ASSERTED?

ACTIVITYINTERRUPT

ASSERTED?

INACTIVITYINTERRUPT

ASSERTED?

INACTIVITYINTERRUPT

ASSERTED?

STABLESTATUSISDIFFERENT

FROMINITIALSTATUS?

TIMEOUT?

GENERATEFALLALERT

GENERATE

CRITICALALERT

GENERATECRITICAL

FREE-FALLALERT

CONTINUOUSFREE_FALL

DETECTED?

TIMEOUT?







从这个实验中可以看出基于ADXL345的解决方案能够有效地

对跌倒状态进行检测。当然,这里只是一个简单的实验方案,

仍需要进行更加全面、有效和长期的实验来验证该解决方案的

可靠性。

结论

ADXL345是ADI公司的一款功能强大的加速度传感器产品。

本文利用ADXL345内部的多种运动状态检测功能和灵活的中

断功能,提出一种新的跌倒检测解决方案。经验证,该解决方

案具有算法复杂度低,检测准确度高的优点。

附录

本算法的基于ADXL345和ADuC7026的测试平台实现。通过



KeilUV3编译,工程中共有4个头文件和一个c文件。下面详

细给出了c文件中源代码。

作者简介

NingJia[ning.jia@analog.com]是中国技术支持

中心现场应用工程师,在ADI有两年的工作经历,

负责向中国用户就ADI的模拟产品提供技术支

持。Ning于2007年获北京邮电大学信号和信息

处理专业硕士学位。

参考资料

1

ADXL345数据手册(www.analog.com,搜索ADXL345)



2

ADuC7026数据手册(www.analog.com,搜索ADuC7026)

6AnalogDialogue43-07

//Includeheaderfiles

#include"FallDetection.h"



voidIRQ_Handler()__irq//IRQinterrupt

{

unsignedchari;

if((IRQSTA&GP_TIMER_BIT)==GP_TIMER_BIT)//TIMER1Interrupt,interval20ms

{

T1CLRI=0;//ClearTimer1interrupt

if(DetectionStatus==0xF2)//Strikeafterweightlessnessisdetected,waitingforstable

{

TimerWaitForStable++;

if(TimerWaitForStable>=STABLE_WINDOW)//Timeout,restart

{

IRQCLR=GP_TIMER_BIT;//DisableADuC7026''sTimer1interrupt

DetectionStatus=0xF0;

putchar(DetectionStatus);

ADXL345Registers[XL345_THRESH_ACT]=STRIKE_THRESHOLD;

ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;

ADXL345Registers[XL345_TIME_INACT]=STABLE_TIME;

ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE|XL345_INACT_Y_ENABLE

|XL345_INACT_X_ENABLE|XL345_INACT_AC

|XL345_ACT_Z_ENABLE|XL345_ACT_Y_ENABLE

|XL345_ACT_X_ENABLE|XL345_ACT_DC;

xl345Write(4,XL345_THRESH_ACT,&ADXL345Registers[XL345_THRESH_ACT]);

}

}

elseif(DetectionStatus==0xF1)//Weightlessnessisdetected,waitingforstrike

{

TimerWaitForStrike++;

if(TimerWaitForStrike>=STRIKE_WINDOW)//Timeout,restart

{

IRQCLR=GP_TIMER_BIT;//DisableADuC7026''sTimer1interrupt

DetectionStatus=0xF0;

putchar(DetectionStatus);

ADXL345Registers[XL345_THRESH_ACT]=STRIKE_THRESHOLD;

ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;

ADXL345Registers[XL345_TIME_INACT]=STABLE_TIME;

ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE|XL345_INACT_Y_ENABLE

|XL345_INACT_X_ENABLE|XL345_INACT_AC

|XL345_ACT_Z_ENABLE|XL345_ACT_Y_ENABLE

|XL345_ACT_X_ENABLE|XL345_ACT_DC;

xl345Write(4,XL345_THRESH_ACT,&ADXL345Registers[XL345_THRESH_ACT]);

}

}

}

if((IRQSTA&SPM4_IO_BIT)==SPM4_IO_BIT)//ExternalinterruptformADXL345INT0

{

IRQCLR=SPM4_IO_BIT;//DisableADuC7026''sexternalinterrupt

xl345Read(1,XL345_INT_SOURCE,&ADXL345Registers[XL345_INT_SOURCE]);

if((ADXL345Registers[XL345_INT_SOURCE]&XL345_ACTIVITY)==XL345_ACTIVITY)//Activityinterruptasserted

{

if(DetectionStatus==0xF1)//Waitingforstrike,andnowstrikeisdetected

{

DetectionStatus=0xF2;//GotoStatus"F2"

putchar(DetectionStatus);

ADXL345Registers[XL345_THRESH_ACT]=STABLE_THRESHOLD;

ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;

ADXL345Registers[XL345_TIME_INACT]=STABLE_TIME;

ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE|XL345_INACT_Y_ENABLE

|XL345_INACT_X_ENABLE|XL345_INACT_AC

|XL345_ACT_Z_ENABLE|XL345_ACT_Y_ENABLE

|XL345_ACT_X_ENABLE|XL345_ACT_AC;

xl345Write(4,XL345_THRESH_ACT,&ADXL345Registers[XL345_THRESH_ACT]);

IRQEN|=GP_TIMER_BIT;//EnableADuC7026''sTimer1interrupt

TimerWaitForStable=0;

}

elseif(DetectionStatus==0xF4)//Waitingforlongtimemotionless,butamovementisdetected

{

DetectionStatus=0xF0;//GotoStatus"F0",restart

putchar(DetectionStatus);

ADXL345Registers[XL345_THRESH_ACT]=STRIKE_THRESHOLD;

ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;

ADXL345Registers[XL345_TIME_INACT]=STABLE_TIME;

ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE|XL345_INACT_Y_ENABLE

|XL345_INACT_X_ENABLE|XL345_INACT_AC

|XL345_ACT_Z_ENABLE|XL345_ACT_Y_ENABLE

|XL345_ACT_X_ENABLE|XL345_ACT_DC;

xl345Write(4,XL345_THRESH_ACT,&ADXL345Registers[XL345_THRESH_ACT]);

}

}

elseif((ADXL345Registers[XL345_INT_SOURCE]&XL345_INACTIVITY)==XL345_INACTIVITY)//Inactivityinterruptasserted

{

if(DetectionStatus==0xF2)//Waitingforstable,andnowstableisdetected

{

DetectionStatus=0xF3;//GotoStatus"F3"

IRQCLR=GP_TIMER_BIT;

putchar(DetectionStatus);

xl345Read(6,XL345_DATAX0,&ADXL345Registers[XL345_DATAX0]);

DeltaVectorSum=0;

for(i=0;i<3;i++)

{

Acceleration[i]=ADXL345Registers[XL345_DATAX1+i2]&0x1F;

Acceleration[i]=(Acceleration[i]<<8)|ADXL345Registers[XL345_DATAX0+i2];



AnalogDialogue43-077



if(Acceleration[i]<0x1000)

{

Acceleration[i]=Acceleration[i]+0x1000;

}

else//if(Acceleration[i]>=4096)

{

Acceleration[i]=Acceleration[i]-0x1000;

}

if(Acceleration[i]>InitialStatus[i])

{

DeltaAcceleration[i]=Acceleration[i]-InitialStatus[i];

}

else

{

DeltaAcceleration[i]=InitialStatus[i]-Acceleration[i];

}

DeltaVectorSum=DeltaVectorSum+DeltaAcceleration[i]DeltaAcceleration[i];

}



if(DeltaVectorSum>DELTA_VECTOR_SUM_THRESHOLD)//Thestablestatusisdifferentfromtheinitialstatus

{

DetectionStatus=0xF4;//Validfalldetection

putchar(DetectionStatus);



ADXL345Registers[XL345_THRESH_ACT]=STABLE_THRESHOLD;

ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;

ADXL345Registers[XL345_TIME_INACT]=NOMOVEMENT_TIME;

ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE|XL345_INACT_Y_ENABLE

|XL345_INACT_X_ENABLE|XL345_INACT_AC

|XL345_ACT_Z_ENABLE|XL345_ACT_Y_ENABLE

|XL345_ACT_X_ENABLE|XL345_ACT_AC;

xl345Write(4,XL345_THRESH_ACT,&ADXL345Registers[XL345_THRESH_ACT]);

}

else//Deltavectorsumisnotexceedthethreshold

{

DetectionStatus=0xF0;//GotoStatus"F0",restart

putchar(DetectionStatus);

ADXL345Registers[XL345_THRESH_ACT]=STRIKE_THRESHOLD;

ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;

ADXL345Registers[XL345_TIME_INACT]=STABLE_TIME;

ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE|XL345_INACT_Y_ENABLE

|XL345_INACT_X_ENABLE|XL345_INACT_AC

|XL345_ACT_Z_ENABLE|XL345_ACT_Y_ENABLE

|XL345_ACT_X_ENABLE|XL345_ACT_DC;

xl345Write(4,XL345_THRESH_ACT,&ADXL345Registers[XL345_THRESH_ACT]);

}

}

elseif(DetectionStatus==0xF4)//Waitforlongtimemotionlessandnowitisdetected

{

DetectionStatus=0xF5;//Validcriticalfalldetection

putchar(DetectionStatus);

ADXL345Registers[XL345_THRESH_ACT]=STRIKE_THRESHOLD;

ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;

ADXL345Registers[XL345_TIME_INACT]=STABLE_TIME;

ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE|XL345_INACT_Y_ENABLE

|XL345_INACT_X_ENABLE|XL345_INACT_AC

|XL345_ACT_Z_ENABLE|XL345_ACT_Y_ENABLE

|XL345_ACT_X_ENABLE|XL345_ACT_DC;

xl345Write(4,XL345_THRESH_ACT,&ADXL345Registers[XL345_THRESH_ACT]);

DetectionStatus=0xF0;//GotoStatus"F0",restart

putchar(DetectionStatus);

}

}

elseif((ADXL345Registers[XL345_INT_SOURCE]&XL345_FREEFALL)==XL345_FREEFALL)//FreeFallinterruptasserted

{

if(DetectionStatus==0xF0)//Waitingforweightless,andnowitisdetected

{

DetectionStatus=0xF1;//GotoStatus"F1"

putchar(DetectionStatus);

ADXL345Registers[XL345_THRESH_ACT]=STRIKE_THRESHOLD;

ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;

ADXL345Registers[XL345_TIME_INACT]=STABLE_TIME;

ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE|XL345_INACT_Y_ENABLE

|XL345_INACT_X_ENABLE|XL345_INACT_AC

|XL345_ACT_Z_ENABLE|XL345_ACT_Y_ENABLE

|XL345_ACT_X_ENABLE|XL345_ACT_DC;

xl345Write(4,XL345_THRESH_ACT,&ADXL345Registers[XL345_THRESH_ACT]);

IRQEN|=GP_TIMER_BIT;//EnableADuC7026''sTimer1interrupt

TimerWaitForStrike=0;

TimerFreeFall=0;

}

elseif(DetectionStatus==0xF1)//Waitingforstrikeafterweightless,andnowanewfreefallisdetected

{

if(TimerWaitForStrike
"FREE_FALL_INTERVAL",

{//thenitisconsiderasacontinuousfreefall

TimerFreeFall=TimerFreeFall+TimerWaitForStrike;

}

else/Notacontinuousfreefall

{

TimerFreeFall=0;

}

TimerWaitForStrike=0;

if(TimerFreeFall>=FREE_FALL_OVERTIME)//ifthecontinuoustimeoffreefallislongerthan

"FREE_FALL_OVERTIME"

{//considerthatafreefallfromhighplaceisdetected

DetectionStatus=0xFF;

putchar(DetectionStatus);

ADXL345Registers[XL345_THRESH_ACT]=STRIKE_THRESHOLD;

ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;

ADXL345Registers[XL345_TIME_INACT]=STABLE_TIME;

ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE|XL345_INACT_Y_ENABLE

|XL345_INACT_X_ENABLE|XL345_INACT_AC

|XL345_ACT_Z_ENABLE|XL345_ACT_Y_ENABLE

|XL345_ACT_X_ENABLE|XL345_ACT_DC;

xl345Write(4,XL345_THRESH_ACT,&ADXL345Registers[XL345_THRESH_ACT]);

DetectionStatus=0xF0;

putchar(DetectionStatus);

}

}

else

{

TimerFreeFall=0;

}

}

IRQEN|=SPM4_IO_BIT;//EnableADuC7026''sexternalinterrupt

}

}

voidmain(void)

{

ADuC7026_Initiate();//ADuC7026initialization

ADXL345_Initiate();//ADXL345initialization

DetectionStatus=0xF0;//Cleardetectionstatus,Start

InitialStatus[0]=0x1000;//Xaxis=0g,unsignedshortint,13bitresolution,0x1000=4096=0g,+/-0xFF=+/-256=+/-1g

InitialStatus[1]=0x0F00;//Yaxis=-1g

InitialStatus[2]=0x1000;//Zaxis=0g

IRQEN=SPM4_IO_BIT;//EnableADuC7026''sexternalinterrupt,toreceivetheinterruptfromADXL345INT0

while(1)//Endlessloop,waitforinterrupts

{

;

}

}

献花(0)
+1
(本文系东郭现世首藏)