1ADXL重力加速度传感器实现计步器程序(利用MSP430F135实现)
1ADXL重力加速度传感器实现计步器程序(利用MSP430F135实现).zip
(116.54 KB)
//存储器没有文件系统,一次采集,一次上载
#include "delay.h"
#include "Key.h"
#include <msp430x13x.h>
#include <string.h>
#include <math.h>
#include <stdio.h>
#include"ADC12.h"
#include "hzlib.h"
#include "LCD.h"
#include "SD2608.h"
#define MEM_IN 0x02 //P3.1
#define MEM_OUT 0x04 //P3.2
#define SCLK 0x08 //P3.3
#define ATRDY 0x40 //AT45DB161 RDY/BUSY P2.6
#define ATCS 0x80 //AT45DB161 AT/CS P2.7
#define TIME_MS 10000 //采样频率为100
#define X_CHANNEL 0
#define Y_CHANNEL 1
#define Z_CHANNEL 2
//#define TIMEWINDOW_MIN 8 //时间窗,×0.02s=0.2s
//#define TIMEWINDOW_MAX 30 //时间窗,×0.02s=0.8s
#define REGULATION 8 //认为找到稳定规律所需要的步数
unsigned char itemp,jtemp,temp;
unsigned char TIMEWINDOW_MIN =11; //时间窗,×0.02s=0.2
unsigned char TIMEWINDOW_MAX =30 ; //时间窗,×0.02s=0.8s
unsigned int Adresult;
unsigned char _bad_flag[3];
unsigned char sampling_counter;
unsigned int _adresult[3];
unsigned int _max[3]={0,0,0};
unsigned int _min[3]={5000,5000,5000};
unsigned int _dc[3]={500,500,500};
unsigned int _vpp[3]={30,30,30};
unsigned int _precision[3]={5,5,5};
unsigned int _old_fixed[3];
unsigned int _new_fixed[3];
unsigned long int STEPS;
unsigned long int STEPS_Temp;
unsigned int _array0[3]={1,1,1};
unsigned int _array1[3]={1,1,1};
unsigned int _array2[3]={0,0,0};
unsigned int _array3[3]={0,0,0};
unsigned int _array4[3]={0,0,0};
unsigned int ADXYZ[3] ;
unsigned long int totalxyz[3];
unsigned int averagexyz[3];
unsigned char avxyz;
unsigned char counter;
unsigned char counterx=0;
unsigned char countery=0;
unsigned char counterz=0;
unsigned char Interval=0; //记录时间间隔数
unsigned char TempSteps=0; //记步缓存
unsigned char InvalidSteps=0; //无效步缓存
unsigned char ReReg=1;
// 1-已经开始,但是还没有找到规律
// 0-已经找到规律
unsigned char high_or_low=0,k=0;
unsigned char recieve;
unsigned char date[7];
unsigned char wdata[7]={0,0,128,0,1,1,0};
void fnClkInit(void)
{
unsigned int a;
WDTCTL = WDTPW +WDTHOLD; //关闭看门狗
BCSCTL1|=XTS; //XT1口为高频 XTS=1,ACLK = LFXT1
do
{
IFG1&=~OFIFG; //清除振荡器失效标志
for (a=0xFF;a>0;a--); //延时 等待XT1口起振
}
while ((IFG1&OFIFG)!=0); //判断XT1口是否起振
BCSCTL2 |= SELM_3; //选择LFXT1CLK为MCLK时钟源
BCSCTL1 |= XT2OFF+DIVA0+DIVA1; //禁止XT2口 ACLK 8分频
}
/*******************定时器初始化定时5MS*******************/
void TimerBInit(void)
{
TBCTL = TBSSEL_1 + TBCLR ; //ACLK为定时器时钟
TBCCTL0 = CCIE; //开定时器中断
TBCCR0 = TIME_MS; //5MS
//TBCTL |= MC0; //增计数模式
}
void main(void)
{
fnClkInit();
TimerBInit();
//usart_Init();
Init_ADC();
Init_keyPort();
vdLCD_Init();
vdDisp_Main();
clock();
_EINT();
while(1)
{
Iskey ();
vdDisp_bushu(STEPS);
}
}
#pragma vector=TIMERB0_VECTOR
__interrupt void Timer_B (void)
{
ADC12CTL0 &= ~ENC;
if(recieve==0x04)
{
//----------------------------------------------ADC采样----------------------//
ADXYZ[0] =ADC12MEM0;//AX
ADXYZ[1]=ADC12MEM1;//AY
ADXYZ[2]=ADC12MEM2;//AZ
//----------------------------------------------开机求平均值判断放置位置----------------------//
if(avxyz==0)
{
counter=counter+1;
totalxyz[0]=totalxyz[0]+ADXYZ[0];
totalxyz[1]=totalxyz[1]+ADXYZ[1];
totalxyz[2]=totalxyz[2]+ADXYZ[2];
if(counter>=40)
{
counter=0;
counterx=0;
countery=0;
counterz=0;
averagexyz[0]= (int)(totalxyz[0]/40);
averagexyz[1]= (int)(totalxyz[1]/40);
averagexyz[2]= (int)(totalxyz[2]/40);
totalxyz[0]=0;
totalxyz[1]=0;
totalxyz[2]=0;
avxyz=1;
//----------------------------------------------x方向为垂直位置----------------------//
if (( averagexyz[0]>= averagexyz[1])&&( averagexyz[0]>= averagexyz[2])&& (averagexyz[0]>3500))
{
counterx=1;
countery=0;
counterz=0;
}
else if (( averagexyz[0]<= averagexyz[1])&&( averagexyz[0]<= averagexyz[2])&& (averagexyz[0]<1800))
{
counterx=1;
countery=0;
counterz=0;
}
//----------------------------------------------y方向为垂直位置----------------------//
else if (( averagexyz[1]>= averagexyz[0])&&( averagexyz[1]>= averagexyz[2])&& (averagexyz[1]>3500))
{
counterx=0;
countery=1;
counterz=0;
}
else if(( averagexyz[1]<= averagexyz[0])&&( averagexyz[1]<= averagexyz[2])&& (averagexyz[1]<1800))
{
counterx=0;
countery=1;
counterz=0;
}
//----------------------------------------------z方向为垂直位置----------------------//
else if (( averagexyz[2]>= averagexyz[0])&&( averagexyz[2]>= averagexyz[1])&& (averagexyz[2]>3500))
{
counterx=0;
countery=0;
counterz=1;
}
else if (( averagexyz[2]<= averagexyz[0])&&( averagexyz[2]<= averagexyz[1])&& (averagexyz[2]<1800))
{
counterx=0;
countery=0;
counterz=1;
}
//----------------------------------------------未能确定方向重现找----------------------//
else
{
avxyz=0;
}
}
}
//----------------------------------------------加速度滤波----------------------//
if(avxyz==1)
{
for(jtemp=X_CHANNEL;jtemp<=Z_CHANNEL;jtemp++)
{
_array4[jtemp]=_array3[jtemp];
_array3[jtemp]=_array2[jtemp];
_array2[jtemp]=_array1[jtemp];
_array1[jtemp]=_array0[jtemp];
_array0[jtemp]= ADXYZ[jtemp];
_adresult[jtemp]=_array0[jtemp]+_array1[jtemp]+_array2[jtemp]+_array3[jtemp]+_array4[jtemp];
_adresult[jtemp]=_adresult[jtemp]/5;
if (_adresult[jtemp]>_max[jtemp]) {_max[jtemp]=_adresult[jtemp];}
if (_adresult[jtemp]<_min[jtemp]) {_min[jtemp]=_adresult[jtemp];}
}
sampling_counter=sampling_counter+1;
Interval=Interval+1;
//----------------------------------计算动态门限和动态精度-----------------------//
if (sampling_counter==50)
{
sampling_counter=0;
for(jtemp=X_CHANNEL;jtemp<=Z_CHANNEL;jtemp++)
{
_vpp[jtemp]=_max[jtemp]-_min[jtemp];
_dc[jtemp]=_min[jtemp]+_vpp[jtemp]/2;
_max[jtemp]=0;
_min[jtemp]=5000;
_bad_flag[jtemp]=0;
if (_vpp[jtemp]>=1000)
{
TIMEWINDOW_MIN =20;
TIMEWINDOW_MAX =60;
_precision[jtemp]=40;
}
else if ((_vpp[jtemp]>=400)&& (_vpp[jtemp]<1000))
{
TIMEWINDOW_MIN =25;
TIMEWINDOW_MAX =70;
_precision[jtemp]=20;
}
else if ((_vpp[jtemp]>=200) && (_vpp[jtemp]<400))
{
TIMEWINDOW_MIN =35;
TIMEWINDOW_MAX =80;
_precision[jtemp]=10;
}
else
{
_precision[jtemp]=2;
_bad_flag[jtemp]=1;
}
}
}
//--------------------------线性移位寄存器--------------------------------------//
for(jtemp=X_CHANNEL;jtemp<=Z_CHANNEL;jtemp++)
{
_old_fixed[jtemp]=_new_fixed[jtemp];
if (_adresult[jtemp]>=_new_fixed[jtemp])
{
if((_adresult[jtemp]-_new_fixed[jtemp])>=_precision[jtemp])
_new_fixed[jtemp]=_adresult[jtemp];
}
if (_adresult[jtemp]<_new_fixed[jtemp])
{
if((_new_fixed[jtemp]-_adresult[jtemp])>=_precision[jtemp])
_new_fixed[jtemp]=_adresult[jtemp];
}
}
//------------------------- 动态门限判决 ----------------------------------
if(counterx==1)
{
if ((_old_fixed[X_CHANNEL]>=_dc[X_CHANNEL])&&(_new_fixed[X_CHANNEL]<_dc[X_CHANNEL])&&(_bad_flag[X_CHANNEL]==0))
{
if((Interval>=TIMEWINDOW_MIN)&&(Interval<=TIMEWINDOW_MAX)) //如果时间间隔在有效的时间窗内
{
if(ReReg==1) //如果还没有找到规律
{
TempSteps++; //记步缓存加1
if(TempSteps>=REGULATION) //如果记步缓存达到所要求的规律数
{
ReReg=0; //已经找到规律
STEPS=STEPS+TempSteps; //更新显示
TempSteps=0;
}
Interval=0;
}
else if(ReReg==0) //如果已经找到规律,直接更新显示
{
STEPS++;
TempSteps=0;
Interval=0;
}
}
else if(Interval>TIMEWINDOW_MAX) //如果时间间隔大于时间窗上限,记步已经间断,重新寻找规律
{
InvalidSteps=0;
ReReg=1;
TempSteps=1;
Interval=0;
}
}
}
if(countery==1)
{
if ((_old_fixed[Y_CHANNEL]>=_dc[Y_CHANNEL])&&(_new_fixed[Y_CHANNEL]<_dc[Y_CHANNEL])&&(_bad_flag[Y_CHANNEL]==0))
{
if((Interval>=TIMEWINDOW_MIN)&&(Interval<=TIMEWINDOW_MAX)) //如果时间间隔在有效的时间窗内
{
if(ReReg==1) //如果还没有找到规律
{
TempSteps++; //记步缓存加1
if(TempSteps>=REGULATION) //如果记步缓存达到所要求的规律数
{
ReReg=0; //已经找到规律
STEPS=STEPS+TempSteps; //更新显示
TempSteps=0;
}
Interval=0;
}
else if(ReReg==0) //如果已经找到规律,直接更新显示
{
STEPS++;
TempSteps=0;
Interval=0;
}
}
else if(Interval>TIMEWINDOW_MAX) //如果时间间隔大于时间窗上限,记步已经间断,重新寻找规律
{
InvalidSteps=0;
ReReg=1;
TempSteps=1;
Interval=0;
}
}
}
if(counterz==1)
{
if ((_old_fixed[Z_CHANNEL]>=_dc[Z_CHANNEL])&&(_new_fixed[Z_CHANNEL]<_dc[Z_CHANNEL])&&(_bad_flag[Z_CHANNEL]==0))
{
if((Interval>=TIMEWINDOW_MIN)&&(Interval<=TIMEWINDOW_MAX)) //如果时间间隔在有效的时间窗内
{
if(ReReg==1) //如果还没有找到规律
{
TempSteps++; //记步缓存加1
if(TempSteps>=REGULATION) //如果记步缓存达到所要求的规律数
{
ReReg=0; //已经找到规律
STEPS=STEPS+TempSteps; //更新显示
TempSteps=0;
}
Interval=0;
}
else if(ReReg==0) //如果已经找到规律,直接更新显示
{
STEPS++;
TempSteps=0;
Interval=0;
}
}
else if(Interval>TIMEWINDOW_MAX) //如果时间间隔大于时间窗上限,记步已经间断,重新寻找规律
{
InvalidSteps=0;
ReReg=1;
TempSteps=1;
Interval=0;
}
}
}
if(Interval>=250)
{
avxyz=0;
Interval=0;
}
}
}
ADC12CTL0 |=ENC; //可能需要,也可能不需要
ADC12CTL0 |= ADC12SC;
}
|