打印

【TI 技术资料分享】重力加速度传感器实现计步器程序

[复制链接]
869|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
必胜客A|  楼主 | 2015-3-9 21:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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;
   }


相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

55

主题

176

帖子

2

粉丝