一、引脚接法:
VCC接电源正极
GND接电源负极
SCL和SDA接单片机IO口(依据程序的定义接口接,IIC通信)
XDA和XCL接外围传感器(一般不接直接悬空)
AD0 接地/VCC 由MPU硬件地址决定
INIT外部中断(悬空)
#define MPU_ADDR 0X68 //AD0接高电平为0X68接低电平为0X69
二、初始化MPU6050
MPU6050的数据写入和读出均通过其芯片内部的寄存器实现,这些寄存器的地址都是1个字节,也就是8位的寻址空间
/**
**********************************
* @brief MPU6050初始化
* @param None
* @retval 0:成功初始化
**********************************
*/
unsigned char MPU6050_Init(void)
{
unsigned char res, d;
MPU_IIC_Init(); //模拟IIC PA0_SDA PA1_SCL
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);
MPU_Set_LPF(50);
if (res == MPU_ADDR && d == 0)//器件ID正确
{
MPU_Write_Byte(MPU_PWR_MGMT1_REG, 0X01); //设置CLKSEL,PLL X轴为参考
MPU_Write_Byte(MPU_PWR_MGMT2_REG, 0X00); //加速度与陀螺仪都工作
MPU_Set_Rate(100); //设置采样率为50Hz
}
else
return 1;
return 0;
}
/**
**********************************
* @brief 采集MPU6050陀螺仪原始数据
* @param gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
* @retval 0:成功
**********************************
*/
unsigned char MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
{
unsigned char 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];
*gy = ((u16)buf[2] << 8) | buf[3];
*gz = ((u16)buf[4] << 8) | buf[5];
}
return res;
}
//角度计算
void Angle_Calcu(void)
{
//范围为2g时,换算关系:16384 LSB/g
//deg = rad*180/3.14
float x=0, y=0, z=0;
Accel_x = aacx; //x轴加速度值暂存
Accel_y = aacy; //y轴加速度值暂存
Accel_z = aacz; //z轴加速度值暂存
Gyro_x = gyrox; //x轴陀螺仪值暂存
Gyro_y = gyroy; //y轴陀螺仪值暂存
Gyro_z = gyroz; //z轴陀螺仪值暂存
//处理x轴加速度
if (Accel_x<32764) x = Accel_x / 16384;
else x = 1 - (Accel_x - 49152) / 16384;
//处理y轴加速度
if (Accel_y<32764) y = Accel_y / 16384;
else y = 1 - (Accel_y - 49152) / 16384;
//处理z轴加速度
if (Accel_z<32764) z = Accel_z / 16384;
else z = (Accel_z - 49152) / 16384;
//用加速度计算三个轴和水平面坐标系之间的夹角
Angle_x_temp = (atan2(z , y)) * 180 / Pi;
Angle_y_temp = (atan2(x , z)) * 180 / Pi;
Angle_z_temp = (atan2(y , x)) * 180 / Pi;
//角度的正负号
if (Accel_y<32764) Angle_y_temp = +Angle_y_temp;
if (Accel_y>32764) Angle_y_temp = -Angle_y_temp;
if (Accel_x<32764) Angle_x_temp = +Angle_x_temp;
if (Accel_x>32764) Angle_x_temp = -Angle_x_temp;
if (Accel_z<32764) Angle_z_temp = +Angle_z_temp;
if (Accel_z>32764) Angle_z_temp = -Angle_z_temp;
//角速度
//向前运动
if (Gyro_x<32764) Gyro_x = -(Gyro_x / 16.4);//范围为2000deg/s时,换算关系:16.4 LSB/(deg/s)
//向后运动
if (Gyro_x>32764) Gyro_x = +(65535 - Gyro_x) / 16.4;
//向前运动
if (Gyro_y<32764) Gyro_y = -(Gyro_y / 16.4);//范围为2000deg/s时,换算关系:16.4 LSB/(deg/s)
//向后运动
if (Gyro_y>32764) Gyro_y = +(65535 - Gyro_y) / 16.4;
//向前运动
if (Gyro_z<32764) Gyro_z = -(Gyro_z / 16.4);//范围为2000deg/s时,换算关系:16.4 LSB/(deg/s)
//向后运动
if (Gyro_z>32764) Gyro_z = +(65535 - Gyro_z) / 16.4;
yijiehubu_P(Angle_y_temp, Gyro_y);
Erjielvbo(Angle_y_temp, Gyro_y);
//Angle_gy = Angle_gy + Gyro_y*0.025; //角速度积分得到倾斜角度.越大积分出来的角度越大
Kalman_Filter_X(Angle_x_temp, Gyro_x); //卡尔曼滤波计算X倾角
Kalman_Filter_Y(Angle_y_temp, Gyro_y); //卡尔曼滤波计算Y倾角
Kalman_Filter_Z(Angle_z_temp, Gyro_z); //卡尔曼滤波计算Z倾角
}
mpu6050对原始数据角度计算中关于16384 与 16.4两个参数来历.
六轴采集原始数据用的都是16位的ADC,所以显示的数字是从-32768——+32768,要看自己选择的量程进行换算,量程选择在配置里面找,比如选择-250——+250量程,那么-32768——+32768就对应-250——+250 进行换算就可以了。
我的为 +—32768 +—2000所以判定 头文件初始化的为最大小量程 +—2g +—2000ax/16384.0=x方向的加速度 单位g ,加速度计算角度用上面的方法gx/16.4=x轴向角速度 (单位 度/秒 )
四、增加MPU6050的翻译手册,内容很有指导意义,帮助理解MPU的操作方式
google下载链接:
http://file1.dzsc.com/product/14/08/19/897314_133615795.pdf