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; }
阅读全文
0 0
- MPU6050.c(参考匿名的)
- CONTROL.c(参考匿名的)
- IMU.c(参考匿名的)
- MOTO.c(参考匿名的)
- MPU6050iic.c(参考匿名的)
- RC.c(参考匿名的)
- UART1.c(参考匿名的)
- UART2.c(参考匿名的)
- usart.c(参考匿名的)
- main.c和stm32f10x_it.c(参考匿名的)
- MPU6050参考代码
- MPU6050中DMP参考面使用绝对水平面的方法
- 陀螺仪的理解(MPU6050)
- MPU6050 Motion_Detection的使用
- MPU6050的初始化
- mpu6050的使用
- MPU6050
- MPU6050
- spring cloud服务调用
- Jupyter制作slides
- L1-007. 念数字
- 【Mysql】索引
- 1007: 鸡兔同笼
- MPU6050.c(参考匿名的)
- Win 10上帝模式 的开启和高级隐藏文件
- angular2 路由策略 LocationStrategy
- For CUDA login-loop error CUDA安装循环登录问题 [Ubuntu 14.04]
- MPU6050iic.c(参考匿名的)
- USACO Section1.2 Name That Number
- mysql函数
- linux0.11环境配置
- RC.c(参考匿名的)