Gsensor驱动调试

目录

Gsensor driver. 1

一、Gsensor文件建立与编译... 1

二、Gsensor的原理图... 2

三、Gsensor的相关配置... 2

四、Gsensor I2C 读写... 3

五、X、Y、Z轴数据的获取... 4

六、Gsensor加速度算法... 8

七、驻车监控功能:... 9

八、Xxx 调试总结:... 11                           

Gsensor driver

G-sensor中文是重力传感器的意思(英文全称是Gravity-sensor),它能够感知到加速力的变化,加速力就是当物体在加速过程中作用在物体上的力,比如晃动、跌落、上升、下降等各种移动变化都能被G-sensor转化为电信号,然后通过微处理器的计算分析后,就能够完成程序设计好的功能,比如汽车在行驶过程中突然加速前进或静止或剧烈震动,从而触发紧急录影,以及驻车监控功能。

一、Gsensor文件建立与编译

驱动文件路径:peripheral\g_sensor

建立A_GSensor_MEMS_XXX.c、A_GSensor_MEMS_XXX.h

添加kconfig 选项

config G_SENSOR_MEMS_XXX

        bool"G_SENSOR_MEMS_XXX"

        default n

Gsensor编译:

ifdef CONFIG_G_SENSOR_MEMS_XXX

libperipheral-objs += $(GSENSORPATH)/A_GSensor_MEMS_XXX.o

endif

 

二、Gsensor的原理图

         GsensorXXX的原理图与LIS3DE pin to pin,(XXX 无INT2.) XXX的引脚4和6分别是SCL和SDA并与A__I2C_CHANNEL2相连接,9脚为INT2脚,连接DSP PWC_wkup1,用于驻车监控唤醒。INT1 为硬件gpio 中断,并未使用。

三、Gsensor的相关配置

寄存器地址的配置      

/* Reg address defination */

#define GSENSOR_MEMS_XXX_I2C_ADDR   0x30

 

//Digital Gyro Register Define

#define REG_WHO_AM_I                       0x04  /*xx change*/

#define REG_POWER_DOWN_CTRL       0X01   /*xx add*/

#define REG_ACTION                            0X02    /*xx add*/

#define REG_MOTION_THRESHOLD       0X03  /*xx add*/

#define REG_START_DATA_READ          0X04  /*xx add*/

#define REG_STATUS                              0X05   /*xx add*/

 

//06h~0Dh: Data registers

#define REG_X_L             0x06

#define REG_X_H             0x07

#define REG_Y_L             0x08

#define REG_Y_H             0x09

#define REG_Z_L             0x0A

#define REG_Z_H             0x0B                          

 

#define REG_INT_CFG                           0X15   /*xx add*/

#define REG_CTRL1           0x16

#define REG_CTRL2           0x17

#define REG_CTRL3           0x18

#define REG_OVERSAMPLING          0x38

#define MAX_REG                      (REG_OVERSAMPLING)

 

Gsensor初始化的设置

int GSENSOR_MEMS_XXX_Init(void)

{

   UINT16 Data;

   UINT8 temp[10] = {0};

 

   if((GSENSOR_MEMS_XXX_Read( REG_WHO_AM_I, &Data) != OK) || (Data !=WHO_AM_I_ID)){

       GSENSOR_DBG("[%s]: Addr: 0x%02x, Data: 0x%02x", __func__,REG_WHO_AM_I, (UINT8)Data);

       return NG;

   }else{

                   MY_MSG("REG_WHO_AM_I:0x%X",Data);

         }

       GSENSOR_MEMS_XXX_Write( REG_POWER_DOWN_CTRL, 0x02);  // Powerdown reset

       A_KAL_TaskSleep(3);

       GSENSOR_MEMS_XXX_Write(0x03,0x1F);//

       GSENSOR_MEMS_XXX_Write(0x38,0x9F);//

       GSENSOR_MEMS_XXX_Write(0x15,0x00);//0x00 low active 0x08 high active(INT PIN)

       GSENSOR_MEMS_XXX_Write(0x16,0x00);//

       GSENSOR_MEMS_XXX_Write(0x02,0x02);//

       GSENSOR_MEMS_XXX_Write(0x02,0x00);//

       GSENSOR_MEMS_XXX_Write(0x02,0x04);//

       GSENSOR_MEMS_XXX_Write(0x02,0x00);//                  

   return OK;

}

四、Gsensor I2C 读写

一次读取多个字节:

VoidGSENSOR_MEMS_XXX_ReadData(UINT16addr,intRxDataSize,UINT8*RxDataBuf)

{

         UINT16WorkUINT16[3];

        

         WorkUINT16[0]= A__I2C_RESTART_FLAG | XXX_Info.I2CAddr; /* Slave Address + r/w (0) */

         WorkUINT16[1]= addr;   /* Sub Address */

         WorkUINT16[2]= A__I2C_RESTART_FLAG | XXX_Info.I2CAddr | 0x01;

         if(A_I2C_ReadAfterWrite(XXX_Info.I2CCHN, A__I2C_SPEED_FAST, 3, WorkUINT16, RxDataSize, RxDataBuf, 5000)!= OK) {

                   GSENSOR_DBG("[%s]fail", __func__);

                   return;

         }

}

GSENSOR_MEMS_XXX_ReadData(0x00, 1, temp1);

GSENSOR_MEMS_XXX_ReadData(0x04, 3, temp);

GSENSOR_MEMS_XXX_ReadData(0x06, 6, temp);

 

五、X、Y、Z轴数据的获取

int AppGSensor_XXX_DetectHandle(void)

         {

       UINT16 data;

         INT16 xdata,ydata,zdata;

         INT32 xTemp = 0, yTemp = 0, zTemp = 0;

         float gx, gy, gz,g_value_sqrt;

         UINT8 temp[10] = {0};

         UINT8 temp1[2] = {0};

        

         GSENSOR_MEMS_XXX_ReadData(0x00, 1,temp1);

         GSENSOR_MEMS_XXX_ReadData(0x04, 3,temp);

         GSENSOR_MEMS_XXX_ReadData(0x06, 6,temp);

         A_Prinxxolor(GREEN,"[8bit]%x,%x,%x,%x,%x,%x",temp[0],temp[1],temp[2],temp[3],temp[4],temp[5]);

         data = temp[0];

         data |= (temp[1] << 8);

         xdata = data;

         //xdata = xdata/256;//256/g

 

         data = temp[2];

         data |= (temp[3] << 8);

         ydata = data;

         //ydata = ydata/256;//256/g

 

         data = temp[4];

         data |= (temp[5] << 8);

         zdata = data;

       //zdata=zdata/256;//256/g

 

       A_Prinxxolor(GREEN, "[16bit/havechange to complement ]xdata:%d, ydata:%d, zdata:%d",xdata,ydata,zdata);

       

  #if 0

         /*if ((xdata & 0x8000) == 0x8000)

         {

                   //最高位是符号位,补码转换

                   xTemp = -((0xffff)- xdata));

         }

         if ((ydata & 0x8000) == 0x8000)

         {

                   //最高位是符号位,补码转换

                   yTemp = -((0xffff)- ydata));

         }

         if ((zdata & 0x8000) == 0x8000)

         {

                   //最高位是符号位,补码转换

                   zTemp = -((0xffff)- zdata));

         }*/

         if ((xdata >> (13)) == 0x0007)

         {

                   //最高位是符号位,补码转换

                   xTemp = -((0xffff - xdata)+1);

                   //xTemp = -((7 << 13) -1 - xdata);

         }

         else

         {

                   xTemp = xdata;

         }

         if ((ydata >> (13)) == 0x0007)

         {

                   //最高位是符号位,补码转换

                   yTemp = -((0xffff -ydata)+1);

                   //yTemp = -((7 << 13) -1 - ydata);

         }

         else

         {

                   yTemp = ydata;

         }

         if ((zdata >> (13)) == 0x0007)

         {

                   //最高位是符号位,补码转换

                   zTemp = -((0xffff -zdata)+1);

                   //zTemp = -((7 << 13) -1 - zdata);

         }

         else

         {

                   zTemp = zdata;

         }

    #endif

         #if 0

         xTemp = xTemp/2;

         yTemp = yTemp/2;

         zTemp = zTemp/2;

         //A_Prinxxolor(RED,"x:%d,y:%d,z:%d", xTemp, yTemp, zTemp);

         //------------------Add moving avg forZ---------------------

         #endif

         if((temp1[0]==0xA2) || (temp1[0]==0xA3)|| (temp1[0]==0xA5))

         {

               #if 1

                   #define moving_step 5 //Setup the times of moving average.

                   static int pointer = -1;

                   static shortbufferave[1][moving_step]; //buffer of Z, data

                   short         sum[3];   //      sum of moving_step

                   int  k,j;

 

                   if ( pointer == -1 )

                   {

                             for(k = 0; k < moving_step; ++k)

                             {

                                 bufferave[0][k]= zdata;

                             }

                   }

                  

                   pointer++;

                   pointer %= moving_step;

                  

                   bufferave[0][pointer] =zdata;

                  

                  

                   sum[0] = 0;

                   for(j = 0; j <moving_step; ++j)

                   {

                            sum[0] +=bufferave[0][j];

                   }

                   sum[0] = sum[0] /moving_step;

                  

                   zTemp = sum[0];

                  

                   xTemp = xdata/2;

                   yTemp = ydata/2;

                   zTemp = zTemp;

               #if 0

                   if((moving_step==1)&&(zTemp<(256*0.2)))

                   {

                            zTemp=0;

                   }

                   elseif((moving_step>1)&&(zTemp<(256*0.2)))

                   {

                            zTemp=zTemp;

                   }

                 //-----------------------------------------------

               #endif

          #endif 

                   //xdata = xdata/2;//256/g

                   //ydata = ydata/2;//256/g

                   //zdata = zdata  ;//256/g

         }

         else

         {

                   xTemp = xdata/2;//256/g

                   yTemp = ydata/2;//256/g

                   zTemp = zdata/2;//256/g

         }

         calc_gvalue_xxx(xTemp, &gx);

         calc_gvalue_xxx(yTemp, &gy);

         calc_gvalue_xxx(zTemp, &gz);

         gx_cur = gx;

         gy_cur = gy;

         gz_cur = gz;

       g_value_sqrt=sqrt(pow(gx,2)+pow(gy,2)+pow(gz,2));

       A_Prinxxolor(RED,"g_value_sqrt:%3.3f",g_value_sqrt);

         Check_even_xxx(gx, gy, gz);

         return OK;

}

 

六、Gsensor加速度算法

检测算法:将13位数据(3位为符号位)转换g 值后,判断实时g值与平均g值的大小来检测是否触发紧急录影。

void Check_even_xxx(float x, float y, floatz)

{

   static float g_data[5][3] = {0.0};

   static int gc =0;

   int i = 0, j = 0;

   static float avg[3] = {0.0};

   static float dtmax, dtx, dty, dtz;

 

   if (gc<5){

       g_data[gc][0] = x;

       g_data[gc][1] = y;

       g_data[gc][2] = z;

       gc++;

       avg[0] = (g_data[0][0] + g_data[1][0] + g_data[2][0] + g_data[3][0] +g_data[4][0])/gc;

       avg[1] = (g_data[0][1] + g_data[1][1] + g_data[2][1] + g_data[3][1] +g_data[4][1])/gc;

       avg[2] = (g_data[0][2] + g_data[1][2] + g_data[2][2] + g_data[3][2] +g_data[4][2])/gc;

       return;

    }else{

       Gfabs_xxx(&dtx, (x-avg[0]));

       Gfabs_xxx(&dty, (y-avg[1]));

       Gfabs_xxx(&dtz, (z-avg[2]));

       Max3_xxx(&dtmax, dtx, dty, dtz);

       A_Print("dtmax = %.2f,g_target: %.2f", dtmax,g_target);

        if (dtmax > g_target){

           A_Prinxxolor(BLUE,"urgent event:sendmsg:AMSG_CMD_GSENSOR_EVEN");

           SendMsg(EVENT_RECORD, 1, 0);

           gc = 0;

           return;

       }

 

       for(i=0; i<4; i++){

           for(j=0; j<3; j++){

           g_data[i][j] = g_data[i+1][j];

           }

       }

       g_data[4][0] = x;

       g_data[4][1] = y;

       g_data[4][2] = z;

       avg[0] = (g_data[0][0] + g_data[1][0] + g_data[2][0] + g_data[3][0] +g_data[4][0])/5.0;

       avg[1] = (g_data[0][1] + g_data[1][1] + g_data[2][1] + g_data[3][1] +g_data[4][1])/5.0;

       avg[2] = (g_data[0][2] + g_data[1][2] + g_data[2][2] + g_data[3][2] +g_data[4][2])/5.0;

    }

}

碰撞触发紧急录影灵敏度设置:

int AppGSensor_XXX_set_event_sensitivity(UINT16sens)

{

         if(sens== 1)/*height*/

                   g_target= 1.0;

         elseif(sens == 2)/*middle*/

                   g_target= 1.5;

         elseif(sens == 3)/*low*/

                   g_target= 2.0;

         else

                   g_target= 0;

   return 0;

}

 

七、驻车监控功能:

在DVR关机时,设置REG_MOTION_THRESHOLD等寄存器来打开或关闭驻车监控功能。REG_MOTION_THRESHOLD设置碰撞灵敏度

static int GSENSOR_MEMS_XXX_enable_interrupt(intsensitivity){

   UINT16 Data;

MY_MSG("[GSENSOR_MEMS_XXX_enable_interrupt]sensitivity:%d",sensitivity);

   Data = 0x1B;

   GSENSOR_MEMS_XXX_Write( REG_CTRL1, Data);

   swixxh(sensitivity){

   case 0:

       Data = 0;

       GSENSOR_MEMS_XXX_Write( REG_CTRL1, Data);

       Data = 0;

       GSENSOR_MEMS_XXX_Write( REG_INT_CFG, Data);

       break;

   case 1:

        Data = 0x04;/*xx  modify as 1g*/

       GSENSOR_MEMS_XXX_Write( REG_MOTION_THRESHOLD, Data);//0x01 ~ 0x1F . 0x01= 0.25G. 0x04:1G   0x1F:7.75G

       break;

   case 2:

       Data = 0x14;

       GSENSOR_MEMS_XXX_Write( REG_MOTION_THRESHOLD, Data);

       break;

   case 3:

       Data = 0x1F;

       GSENSOR_MEMS_XXX_Write( REG_MOTION_THRESHOLD, Data);

       break;

   default:

       break;

    }

       GSENSOR_MEMS_XXX_Read(0x04, &Data);

       GSENSOR_MEMS_XXX_Read(0x05, &Data);

       GSENSOR_MEMS_XXX_Read(0x06, &Data);

       GSENSOR_MEMS_XXX_Read(0x07, &Data);

       GSENSOR_MEMS_XXX_Read(0x08, &Data);

       GSENSOR_MEMS_XXX_Read(0x09, &Data);

       GSENSOR_MEMS_XXX_Read(0x0A, &Data);

       GSENSOR_MEMS_XXX_Read(0x0B, &Data);

       Data =0x4C;

       GSENSOR_MEMS_XXX_Write( REG_INT_CFG, Data);

       /*啟動中斷 有上拉電組--高電平輸出0x5D,低電平0x55  

                                   沒上拉電組--高電平輸出0x4C,低電平0x44*/

 

  return OK;

}

八、Xxx 调试总结:

1.调试I2C 通讯:注意排除i2c 总线上的其它设备干扰、确认i2c地址是否正确、硬件上i2c 是否需滤波和上拉。

2.GSENSOR GMA305 I2C 调通之后,获取gsensor GMA305 三轴数据不准确。原因是初始化之后,打开驻车监控功能(读写寄存器)导致gsensor模式错乱造成读取数据不正确。猜想是本身IC问题。ST的 LIS3DE 无此问题。

3. 数据读取正常后,数据漂移大。

数据conclusion:

平放(Orientation 6):

[00279860][CA9] [16bit/have change tocomplement ]xdata:37, ydata:86, zdata:-32

[00279860][CA9] xTemp: 18, yTemp: 43,zTemp: -16,gx: 0.070,gy: 0.168,gz: -0.059

垂直(Orientation 1):

[00152277][CA9] [16bit/have change tocomplement ]xdata:614, ydata:128, zdata:438

[00152277][CA9] xTemp: 307, yTemp: 64,zTemp: 219,gx: 1.199,gy: 0.250,gz: 0.855

垂直(Orientation 2):

[00226348][CA9] [16bit/have change tocomplement ]xdata:71, ydata:619, zdata:492

[00226348][CA9] xTemp: 35, yTemp: 309,zTemp: 246,gx: 0.137,gy: 1.207,gz: 0.961

垂直(Orientation 3):

[00114901][CA9] [16bit/have change tocomplement ]xdata:-495, ydata:59, zdata:460

[00114901][CA9] xTemp: -247, yTemp: 29,zTemp: 230,gx: -0.961,gy: 0.113,gz: 0.898

垂直(Orientation 4):

[00302658][CA9] [16bit/have change tocomplement ]xdata:8, ydata:-452, zdata:387

[00302658][CA9] xTemp: 4, yTemp: -226,zTemp: 193,gx: 0.016,gy: -0.879,gz: 0.754

平放(Orientation 5):

[00037125][CA9] [16bit/have change tocomplement ]xdata:85, ydata:27, zdata:911

[00037125][CA9] xTemp: 42, yTemp: 13,zTemp: 455,gx: 0.164,gy: 0.051,gz: 1.777

 


猜你喜欢

转载自blog.csdn.net/qq_23400367/article/details/80922976
今日推荐