#include<STC8A.h>
#include<intrins.h>
#include<MPU_I2C.h>
#include<math.h>
#include<DMP.h>
#include<test.h>
#define q30 1073741824.0f;
uchar dmpdatas[42];
signed long dmpdata_group[4];
float q0 = 1.0f,q1 = 0.0f,q2 = 2.0f,q3 = 0.0f;//四元數
float Yaw,Pitch,Roll,Temp; //加載并配置DMP 數字運動處理引擎
uchar dmpInitialize(void)
{
uchar hwRevision,otpValid,mpuIntStatus;
uchar xgOffsetTC,ygOffsetTC,zgOffsetTC;
uint fifoCount;
I2C_writebit(PWR_MGMT_1,7,1);//復位MPU6050
Delay10ms();
I2C_writebit(PWR_MGMT_1,6,0);
I2C_send(0x6D,0x70);
I2C_send(0x6E,0x06);
I2C_Recv_t(0x6F,&hwRevision);//讀取
//hwRevision = I2C_Recv(0x6f);
I2C_send(0x6D,0); //重置內存bank選擇
readBit(0x00,0,&otpValid); //讀取otp bank 有效標志
readBits(0x00,6,6,&xgOffsetTC); //讀取陀螺儀偏置TC值 x
readBits(0x01,6,6,&ygOffsetTC); //讀取陀螺儀偏置TC值 y
readBits(0x02,6,6,&zgOffsetTC); //讀取陀螺儀偏置TC值 z
////////////////////////////////
I2C_writebit(USER_CTRL,1,1); //I2C總線主控復位
Delay10ms(); if ((loadfirmware()) == 0) return 0;//加載dmp代碼到內存
//loadfirmware();
// uart1sendstr("TEST\r\n");
if ((loadcfgupd()) ==0) return 0;//配置dmp
I2C_writebits(PWR_MGMT_1,2,3,0x03); //設置脈沖源z陀螺
I2C_send(0x38,0x12);//設置DMP和FIFO_OFLOW啟用中斷
I2C_send(0x19,4);//設置采樣率為200 hz (1khz / (1 + 4) = 200 Hz)
I2C_writebits(0x1A,5,3,0x1); //設置外部幀同步TEMP_UT_L[0]
I2C_writebits(0x1A,2,3,0x03);//設置DLPF帶寬42赫茲
I2C_writebits(0x1B,4,2,0x03);//陀螺儀靈敏度+-2000
I2C_send(0x70,0x03); //設置DMP配置字節
I2C_send(0x71,0x00); //設置DMP配置字節???
I2C_writebit(0x00,0,0);//清除otp bank 標志
I2C_writebits(0x00,6,6,xgOffsetTC); //清除陀螺儀偏置TC值 x
I2C_writebits(0x01,6,6,ygOffsetTC); //清除陀螺儀偏置TC值 y
I2C_writebits(0x02,6,6,zgOffsetTC); //清除陀螺儀偏置TC值 z dmp_update(0);
dmp_update(5);
I2C_writebit(0x6A,2,1); //復位fifo
fifoCount = getFIFOcount(); //讀取FIFO計數
I2C_writebit(0x6A,2,1); //復位fifo
///////////////////////////////////////////////////////////////////////////////////////////
I2C_send(0x1F,2); //運動檢測閾值設置為2
I2C_send(0x21,156); //零運動檢測閾值為156 (是否修改)
I2C_send(0x20,80);//設置運動檢測持續時間至80
I2C_send(0x22,0);//設置運動檢測時間0
I2C_writebit(0x6A,2,1); //復位fifo
I2C_writebit(0x6A,6,1); //使能fifo
I2C_writebit(0x6A,7,1); //使能dmp
I2C_writebit(0x6A,3,1); //復位dmp dmp_update(12);
dmp_update(17);
dmp_update(28);
while ((fifoCount = getFIFOcount()) < 3 ); //等待fifo計數大于2
I2C_writebit(0x6A,2,1);//復位fifo
I2C_Recv_t(0x3A,&mpuIntStatus);//讀取中斷狀態
//mpuIntStatus = I2C_Recv(0x3A);
// if(dmp_update(35)==0) return 0; //最后更新6/7(函數未知)dmpUpdates數組第六行
dmp_update(35);
while ((fifoCount = getFIFOcount()) < 3 );
I2C_writebit(0x6A,2,1); //復位fifo
I2C_Recv_t(0x3A,&mpuIntStatus);//讀取中斷狀態
//mpuIntStatus = I2C_Recv(0x3A);
// if(dmp_update(40)==0) return 0; //最后更新7/7(函數未知)dmpUpdates數組第七行
dmp_update(40);
I2C_writebit(0x6A,7,0); //禁用dmp
I2C_writebit(0x6A,2,1); //復位fifo
I2C_Recv_t(0x3A,&mpuIntStatus);//讀取中斷狀態
//mpuIntStatus = I2C_Recv(0x3A);
return 1;
}
uchar getDevideID(void) //驗證id
{
uchar b = 0;
readBits(0x75,6,6,&b);
return b== 0x34;
}
void init_MPU6050(void)
{
I2C_writebits(PWR_MGMT_1,2,3,0x01); //電源管理
I2C_send(GYRO_CONFIG, 0x00);
I2C_send(ACCEL_CONFIG, 0x01);
I2C_writebit(PWR_MGMT_1,6,1); //睡眠狀態
if (getDevideID())
{ if(!(dmpInitialize()))
while(1);
} I2C_writebit(0x6A,2,1); //復位fifo
I2C_writebit(0x6A,7,1); //使能dmp
}
void read_FIFO(void)
{
uchar zd;
uint i;
i = getFIFOcount();//讀取fifo計數
I2C_Recv_t(0x3A,&zd);//讀取中斷狀態 //uart1sendstr("ddd\r\n");
if ((zd & 0x10)||i>=840) //判斷fifo是否溢出
{
uart1sendstr("yichu\r\n");
I2C_writebit(0x6A,2,1); //復位fifo
}
else if (zd &0x02)
{
uart1sendstr("eee\r\n");
while (i<42) i=getFIFOcount();
if (readdmp(dmpdatas)) //讀取fifo數據
{
dmpdata_group[0] = ((long)dmpdatas[0] << 24) | ((long)dmpdatas[1] << 16) | ((long)dmpdatas[2] << 8) | dmpdatas[3];
dmpdata_group[1] = ((long)dmpdatas[4] << 24) | ((long)dmpdatas[5] << 16) | ((long)dmpdatas[6] << 8) | dmpdatas[7];
dmpdata_group[2] = ((long)dmpdatas[8] << 24) | ((long)dmpdatas[9] << 16) | ((long)dmpdatas[10] << 8) | dmpdatas[11];
dmpdata_group[3] = ((long)dmpdatas[12] << 24) | ((long)dmpdatas[13] << 16) | ((long)dmpdatas[14] << 8) | dmpdatas[15];
q0 = (float)dmpdata_group[0] / q30; //取四元數
//q0 = 131.1f;
q1 = (float)dmpdata_group[1] / q30;
q2 = (float)dmpdata_group[2] / q30;
q3 = (float)dmpdata_group[3] / q30;
// Roll = Atan2(2 *(Y * Z + W * X) , W * W -X * X -Y * Y + Z * Z)
Roll = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 42.975;
// Pitch = asin(-2 * (X * Z - W * Y))
Pitch = asin(-2 * q1 * q3 + 2 * q0* q2)* 42.975;
// Yaw = atan2(2 * (X * Y + W * Z) ,W * W + X * X - Y * Y - Z * Z)
Yaw = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 42.975; }
}
}
|