/*************************************************************************************************** Motion.c ****************************************************************************************************/ #define THIS_FILE_ID 19 #include "includes.h" #define LSM303D_WHO_AM_I_VAL 0x49 #define LSM6DS3_WHO_AM_I_VAL 0x69 MOTION_SENSOR_TYPE MotionSensorType; SUT_MOTION sutMotion; /********************************************************************** DelayNs ***********************************************************************/ void DelayNs(unsigned short ns) { while(ns--); } /********************************************************************** DelayUs SystemCoreClock=72 Mhz t=70 SystemCoreClock=60 Mhz t=60 ***********************************************************************/ //void DelayUs(unsigned short us) //{ // int t; // while(us--){ // t=60; // while(t--); // } //} //void DelayMs(unsigned short ms) //{ // while(ms--){ // DelayUs(1000); // IWDG_ReloadCounter(); // } //} static int32_t platform_write(void *handle, uint8_t Reg, uint8_t *Bufp, uint16_t len) { unsigned char data; unsigned short i,j; data=Reg; if(handle==(void *)LSM303AGR_I2C_ADD_XL){ MOTION_CS_XL_LOW; }else MOTION_CS_MAG_LOW; DELAY_NOP; for(i=0;i<8;i++) { MOTION_CLK_LOW; DELAY_NOP; DELAY_NOP; if((data<1)data|=0x40;//地址自增 }else MOTION_CS_MAG_LOW; DELAY_NOP; //发地址 for(i=0;i<8;i++) { DELAY_NOP; MOTION_CLK_LOW; DELAY_NOP; if((data<lastTick)lastTick=curTick+50; else return; flag=0; if(MotionReadAccel(&Ax,&Ay,&Az)){ flag=1; } if(MotionReadMagne(&Mx,&My,&Mz)){ flag=1; } if(flag){ if(++sucCt>9)sucCt=0; //先存起来 Axx[sucCt]=Ax; Ayy[sucCt]=Ay; Azz[sucCt]=Az; Mxx[sucCt]=Mx; Myy[sucCt]=My; Mzz[sucCt]=Mz; //再处理 if(sucCt==9){//计算处理 //求平均 Axp=0;Ayp=0; for(i=0;i<10;i++){ Axp+=Axx[i]; Ayp+=Ayy[i]; } Axp/=10; Ayp/=10; Axm=0;Aym=0; //找到最大偏差点 for(i=0;i<10;i++){ Ax=Axx[i]-Axp; Ay=Ayy[i]-Ayp; if(Ax<0)Ax*=-1; if(Ay<0)Ay*=-1; if(Ax>Axm){ Axm=Ax; i1=i; } if(Ay>Aym){ Aym=Ay; i2=i; } } tsk_lock(); sutMotion.Flag=0; //判断Ax还是Ay偏差最大 if(Axm>Aym){ //Ax偏差最大,取Ax sutMotion.Ax=Axx[i1]; sutMotion.Ay=Ayy[i1]; sutMotion.Az=Azz[i1]; sutMotion.Mx=Mxx[i1]; sutMotion.My=Myy[i1]; sutMotion.Mz=Mzz[i1]; if(Axm>(Axp+ACC_THRESHOLD))sutMotion.Flag=1; }else{ //Ay偏差最大,取Ay sutMotion.Ax=Axx[i2]; sutMotion.Ay=Ayy[i2]; sutMotion.Az=Azz[i2]; sutMotion.Mx=Mxx[i2]; sutMotion.My=Myy[i2]; sutMotion.Mz=Mzz[i2]; if(Aym>(Ayp+ACC_THRESHOLD))sutMotion.Flag=2; } tsk_unlock(); //打印 #if 0 float fAx,fAy,fAz,fMx,fMy,fMz; fAx=sutMotion.Ax*SENSITIVITY_ACC; fAy=sutMotion.Ay*SENSITIVITY_ACC; fAz=sutMotion.Az*SENSITIVITY_ACC; fMx=sutMotion.Mx*SENSITIVITY_MAG; fMy=sutMotion.My*SENSITIVITY_MAG; fMz=sutMotion.Mz*SENSITIVITY_MAG; printf("\r\n"); printf("Ax=%10.3f\r\n",fAx); printf("Ay=%10.3f\r\n",fAy); printf("Az=%10.3f\r\n",fAz); printf("Mx=%10.3f\r\n",fMx); printf("My=%10.3f\r\n",fMy); printf("Mz=%10.3f\r\n",fMz); printf("----Flag=%d---\r\n",sutMotion.Flag); #endif } }else{ SlwTrace(DEBUG,"Motion Test Error!\r\n"); sucCt=0; tsk_lock(); sutMotion.Ax=0; sutMotion.Ay=0; sutMotion.Az=0; sutMotion.Mx=0; sutMotion.My=0; sutMotion.Mz=0; sutMotion.Flag=0; tsk_unlock(); } } /*************************************************** *每20ms调用一次 ****************************************************/ void MotionTest(void) { static unsigned char ct=0; int Ax,Ay,Az,Mx,My,Mz; float mgData_X, mgData_Y,mgData_Z; //data in mg float gaussData_X, gaussData_Y, gaussData_Z; //data in Gauss u8_t flag_LSM303C_ACC_STATUS_FLAGS; LSM303C_MAG_ZYXDA_t flag_LSM303C_MAG_XYZDA; Type3Axis16bit_U data; // accelerometer row data status_t response; // mems error variable if(++ct>100)ct=0; else return; //get Acceleration Raw data response = LSM303C_MAG_R_NewXYZData(0, (LSM303C_MAG_ZYXDA_t*) &flag_LSM303C_MAG_XYZDA); if(response==MEMS_ERROR) SlwTrace(DEBUG,"ERROR111"); //manage here comunication error //read only if new data are available from accelerometer else if (flag_LSM303C_ACC_STATUS_FLAGS&LSM303C_ACC_ZYX_NEW_DATA_AVAILABLE) { response = LSM303C_ACC_GetAccRaw(0, data.u8bit); //convert from LSB to mg mgData_X=data.i16bit[0]*SENSITIVITY_ACC; mgData_Y=data.i16bit[1]*SENSITIVITY_ACC; mgData_Z=data.i16bit[2]*SENSITIVITY_ACC; Ax=data.i16bit[0]; Ax=data.i16bit[1]; Ax=data.i16bit[2]; } //get Magnetic Raw data response = LSM303C_MAG_R_NewXYZData(0, (LSM303C_MAG_ZYXDA_t*) &flag_LSM303C_MAG_XYZDA); if(response==MEMS_ERROR) SlwTrace(DEBUG,"ERROR222"); //manage here comunication error //read only if new data are available else if ((LSM303C_MAG_ZYXDA_t) flag_LSM303C_MAG_XYZDA & LSM303C_MAG_ZYXDA_AVAILABLE) { response = LSM303C_MAG_Get_Magnetic(0, data.u8bit); //convert from LSB to Gauss gaussData_X=data.i16bit[0]*SENSITIVITY_MAG; gaussData_Y=data.i16bit[1]*SENSITIVITY_MAG; gaussData_Z=data.i16bit[2]*SENSITIVITY_MAG; Mx=data.i16bit[0]; My=data.i16bit[1]; Mz=data.i16bit[2]; } printf("\r\n"); printf("Ax=%10.3f\r\n",mgData_X); printf("Ay=%10.3f\r\n",mgData_Y); printf("Az=%10.3f\r\n",mgData_Z); printf("Mx=%10.3f\r\n",gaussData_X); printf("My=%10.3f\r\n",gaussData_Y); printf("Mz=%10.3f\r\n",gaussData_Z); printf("----\r\n"); }