ADXL重力加速度傳感器實現計步器程序,利用MSP430F135實現,代碼功能完整。
可用按鍵控制。
0.png (54.35 KB, 下載次數: 74)
下載附件
2018-3-11 19:51 上傳
單片機源程序如下:
- //存儲器沒有文件系統,一次采集,一次上載
- #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
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
ADXL重力加速度傳感器實現計步器程序(利用MSP430F135實現).zip
(120.55 KB, 下載次數: 35)
2018-3-11 19:13 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|