MPU6050.c(参考匿名的)

来源:互联网 发布:在淘宝上买到假海之蓝 编辑:程序博客网 时间:2024/06/11 11:00
#include "MPU6050.h"#include "Tim.h"u8                      mpu6050_buffer[14];                 //iic读取后存放数据S_INT16_XYZ     GYRO_OFFSET,ACC_OFFSET;         //零漂u8                      GYRO_OFFSET_OK = 1;u8                      ACC_OFFSET_OK = 1;S_INT16_XYZ     MPU6050_ACC_LAST,MPU6050_GYRO_LAST;     //最新一次读取值/**************************实现函数*****************************************************将iic读取到得数据分拆,放入相应寄存器如果上位机要计算零漂,便发回OFFSET数据****************************************************************************************/void MPU6050_Dataanl(void){    if(!GYRO_OFFSET_OK)//没有计算零偏,一开始不会计算零漂,                       //只有上位机将GYRO_OFFSET_OK置零后才将其置零    {                           static int32_t  tempgx=0,tempgy=0,tempgz=0;        static uint8_t cnt_g=0;//      LED1_ON;        if(cnt_g==0)        {            GYRO_OFFSET.X=0;            GYRO_OFFSET.Y=0;            GYRO_OFFSET.Z=0;            tempgx = 0;            tempgy = 0;            tempgz = 0;            cnt_g = 1;            return;        }        tempgx+= MPU6050_GYRO_LAST.X;        tempgy+= MPU6050_GYRO_LAST.Y;        tempgz+= MPU6050_GYRO_LAST.Z;        if(cnt_g==200)        {            GYRO_OFFSET.X=tempgx/cnt_g;//累加200次取平均值            GYRO_OFFSET.Y=tempgy/cnt_g;            GYRO_OFFSET.Z=tempgz/cnt_g;            cnt_g = 0;            GYRO_OFFSET_OK = 1;//          EE_SAVE_GYRO_OFFSET();//保存数据            return;        }        cnt_g++;    }    if(!ACC_OFFSET_OK)    {        static int32_t  tempax=0,tempay=0,tempaz=0;        static uint8_t cnt_a=0;//      LED1_ON;        if(cnt_a==0)        {            ACC_OFFSET.X = 0;            ACC_OFFSET.Y = 0;            ACC_OFFSET.Z = 0;            tempax = 0;            tempay = 0;            tempaz = 0;            cnt_a = 1;            return;        }        tempax+= MPU6050_ACC_LAST.X;        tempay+= MPU6050_ACC_LAST.Y;        //tempaz+= MPU6050_ACC_LAST.Z;        if(cnt_a==200)        {            ACC_OFFSET.X=tempax/cnt_a;            ACC_OFFSET.Y=tempay/cnt_a;            ACC_OFFSET.Z=tempaz/cnt_a;            cnt_a = 0;            ACC_OFFSET_OK = 1;//          EE_SAVE_ACC_OFFSET();//保存数据            return;        }        cnt_a++;            }}/*****************  底层的读取MPU6050_ACC_LAST,MPU6050_GYRO_LAST  数据  *****************/void MPU6050_Read(void){      MPU_Get_Accelerometer(&MPU6050_ACC_LAST.X ,&MPU6050_ACC_LAST.Y ,&MPU6050_ACC_LAST.Z );    //得到加速度传感器数据            MPU_Get_Gyroscope(&MPU6050_GYRO_LAST.X ,&MPU6050_GYRO_LAST.Y ,&MPU6050_GYRO_LAST.Z );   //得到陀螺仪数据}/************************** 初始化     MPU6050 以进入可用状态  *****************************/u8 MPU6050_Init(void){     u8 res;     MPU_IIC_Init();//初始化IIC总线    MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X80); //复位MPU6050 delay_ms(100);    MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X00); //唤醒MPU6050     MPU_Set_Gyro_Fsr(3);                    //陀螺仪传感器,±2000dps    MPU_Set_Accel_Fsr(0);                   //加速度传感器,±2g    MPU_Set_Rate(50);                       //设置采样率50Hz    MPU_Write_Byte(MPU_INT_EN_REG,0X00);    //关闭所有中断    MPU_Write_Byte(MPU_USER_CTRL_REG,0X00); //I2C主模式关闭    MPU_Write_Byte(MPU_FIFO_EN_REG,0X00);   //关闭FIFO    MPU_Write_Byte(MPU_INTBP_CFG_REG,0X80); //INT引脚低电平有效    res=MPU_Read_Byte(MPU_DEVICE_ID_REG);     if(res==MPU_ADDR)//器件ID正确    {        MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01); //设置CLKSEL,PLL X轴为参考        MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00); //加速度与陀螺仪都工作        MPU_Set_Rate(50);                       //设置采样率为50Hz    }else return 1;    return 0;}/**********************   设置MPU6050的传感器   ********************************///陀螺仪传感器满量程范围//fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps//返回值:0,设置成功//    其他,设置失败 u8 MPU_Set_Gyro_Fsr(u8 fsr){    return MPU_Write_Byte(MPU_GYRO_CFG_REG,fsr<<3);//设置陀螺仪满量程范围  }//设置MPU6050加速度传感器满量程范围//fsr:0,±2g;1,±4g;2,±8g;3,±16g//返回值:0,设置成功//    其他,设置失败 u8 MPU_Set_Accel_Fsr(u8 fsr){    return MPU_Write_Byte(MPU_ACCEL_CFG_REG,fsr<<3);//设置加速度传感器满量程范围  }//设置MPU6050的数字低通滤波器//lpf:数字低通滤波频率(Hz)//返回值:0,设置成功//    其他,设置失败 u8 MPU_Set_LPF(u16 lpf){    u8 data=0;    if(lpf>=188)data=1;    else if(lpf>=98)data=2;    else if(lpf>=42)data=3;    else if(lpf>=20)data=4;    else if(lpf>=10)data=5;    else data=6;     return MPU_Write_Byte(MPU_CFG_REG,data);//设置数字低通滤波器  }//设置MPU6050的采样率(假定Fs=1KHz)//rate:4~1000(Hz)//返回值:0,设置成功//    其他,设置失败 u8 MPU_Set_Rate(u16 rate){    u8 data;    if(rate>1000)rate=1000;    if(rate<4)rate=4;    data=1000/rate-1;    data=MPU_Write_Byte(MPU_SAMPLE_RATE_REG,data);  //设置数字低通滤波器    return MPU_Set_LPF(rate/2); //自动设置LPF为采样率的一半}/***********************  读取六轴以及温度原始数据,并减去零偏  **************************///得到温度值//返回值:温度值(扩大了100倍)short MPU_Get_Temperature(void){    u8 buf[2];     short raw;    float temp;    MPU_Read_Len(MPU_ADDR,MPU_TEMP_OUTH_REG,2,buf);     raw=((u16)buf[0]<<8)|buf[1];      temp=36.53+((double)raw)/340;      return temp*100;;}//得到陀螺仪值(原始值)//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)//返回值:0,成功//    其他,错误代码u8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz){    u8 buf[6],res;      res=MPU_Read_Len(MPU_ADDR,MPU_GYRO_XOUTH_REG,6,buf);    if(res==0)    {        *gx=(((u16)buf[0]<<8)|buf[1])-GYRO_OFFSET.X;          *gy=(((u16)buf[2]<<8)|buf[3])-GYRO_OFFSET.Y;          *gz=(((u16)buf[4]<<8)|buf[5])-GYRO_OFFSET.Z;    }       return res;;}//得到加速度值(原始值)//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)//返回值:0,成功//    其他,错误代码u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az){    u8 buf[6],res;      res=MPU_Read_Len(MPU_ADDR,MPU_ACCEL_XOUTH_REG,6,buf);    if(res==0)    {        *ax=(((u16)buf[0]<<8)|buf[1])-ACC_OFFSET.X;          *ay=(((u16)buf[2]<<8)|buf[3])-ACC_OFFSET.Y;          *az=(((u16)buf[4]<<8)|buf[5])-ACC_OFFSET.Z;    }       return res;;}/***************************  IIC读写器件寄存器函数  ******************************************///IIC连续写//addr:器件地址 //reg:寄存器地址//len:写入长度//buf:数据区//返回值:0,正常//    其他,错误代码u8 MPU_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf){    u8 i;     MPU_IIC_Start();     MPU_IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令     if(MPU_IIC_Wait_Ack())  //等待应答    {        MPU_IIC_Stop();              return 1;           }    MPU_IIC_Send_Byte(reg); //写寄存器地址    MPU_IIC_Wait_Ack();     //等待应答    for(i=0;i<len;i++)    {        MPU_IIC_Send_Byte(buf[i]);  //发送数据        if(MPU_IIC_Wait_Ack())      //等待ACK        {            MPU_IIC_Stop();              return 1;                }           }        MPU_IIC_Stop();      return 0;   } //IIC连续读//addr:器件地址//reg:要读取的寄存器地址//len:要读取的长度//buf:读取到的数据存储区//返回值:0,正常//    其他,错误代码u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf){     MPU_IIC_Start();     MPU_IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令     if(MPU_IIC_Wait_Ack())  //等待应答    {        MPU_IIC_Stop();              return 1;           }    MPU_IIC_Send_Byte(reg); //写寄存器地址    MPU_IIC_Wait_Ack();     //等待应答    MPU_IIC_Start();    MPU_IIC_Send_Byte((addr<<1)|1);//发送器件地址+读命令     MPU_IIC_Wait_Ack();     //等待应答     while(len)    {                                     //可以连续读取6各数据,而不用写6个寄存器地址        if(len==1)*buf=MPU_IIC_Read_Byte(0);//读数据,发送nACK,直到此时读取完毕         else *buf=MPU_IIC_Read_Byte(1);     //读数据,发送ACK,接着读取下一个地址的寄存器中的数据          len--;        buf++;     }        MPU_IIC_Stop(); //产生一个停止条件     return 0;   }//IIC写一个字节 //reg:寄存器地址//data:数据//返回值:0,正常//    其他,错误代码u8 MPU_Write_Byte(u8 reg,u8 data)                {     MPU_IIC_Start();     MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令     if(MPU_IIC_Wait_Ack())  //等待应答    {        MPU_IIC_Stop();              return 1;           }    MPU_IIC_Send_Byte(reg); //写寄存器地址    MPU_IIC_Wait_Ack();     //等待应答     MPU_IIC_Send_Byte(data);//发送数据    if(MPU_IIC_Wait_Ack())  //等待ACK    {        MPU_IIC_Stop();          return 1;            }            MPU_IIC_Stop();      return 0;}//IIC读一个字节 //reg:寄存器地址 //返回值:读到的数据u8 MPU_Read_Byte(u8 reg){    u8 res;    MPU_IIC_Start();     MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令     MPU_IIC_Wait_Ack();     //等待应答     MPU_IIC_Send_Byte(reg); //写寄存器地址    MPU_IIC_Wait_Ack();     //等待应答    MPU_IIC_Start();    MPU_IIC_Send_Byte((MPU_ADDR<<1)|1);//发送器件地址+读命令     MPU_IIC_Wait_Ack();     //等待应答     res=MPU_IIC_Read_Byte(0);//读取数据,发送nACK     MPU_IIC_Stop();         //产生一个停止条件     return res;     }
原创粉丝点击