MPU60506轴陀螺仪的使⽤与校准
1 MPU6050初始化
①初始化IIC接⼝。
②初始化MPU6050。由电源管理寄存器1(0X6B)控制。
③设置⾓速度传感器和加速度传感器的满量程范围。由陀螺仪配置寄存器(0X1B)和加速度传感器配置寄存器(0X1C)设置 。
④设置其他参数。配置中断,由中断使能寄存器(0X38)控制;设置AUX IIC接⼝,由户控制寄存器(0X6A)控制;设置FIFO,由FIFO使能寄存器(0X23)控制;陀螺仪采样率 ,由采样率分频寄存器(0X19)控制;设置数字低通滤波器,由配置寄存器(0X1A)控制。
⑤设置系统时钟。由电源管理寄存器1(0X6B)控制。⼀般选择x轴陀螺PLL作为时钟源,以获得更⾼精度的时钟。
⑥**使能⾓速度传感器(陀螺仪)和加速度传感器。**由电源管理寄存器2(0X6C)控制
注:如果是使⽤MPU6050的标准函数,只需要依次调⽤这三个函数即可
IIC_Init(); //=====IIC初始化
MPU6050_initialize(); //=====MPU6050初始化
DMP_Init(); //=====初始化DMP
下⾯主要解释这三个函数的配置:
2 IIC_Init()函数的使⽤
2.1 IIC是什么
IIC串⾏总线⼀般有两根信号线,⼀根是双向的数据线SDA,另⼀根是时钟线SCL。所有接到I2C总线设备上的串⾏数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。
设备上的串⾏数据线SDA接⼝电路应该是双向的,输出电路⽤于向总线上发送数据,输⼊电路⽤于接收总线上的数据。⽽串⾏时钟线也应是双向的,作为控制总线数据传送的主机,⼀⽅⾯要通过SCL输出电路发送时钟信号,另⼀⽅⾯还要检测总线上的SCL电平,以决定什么时候发送下⼀个时钟脉冲电平;作为接受主机命令的从机,要按总线上的SCL信号发出或接收SDA上的信号,也可以向SCL线发出低电平信号以延长总线时钟信号周期。
雅思视频教程
总线空闲时,因各设备都是开漏输出,上拉电阻Rp使SDA和SCL线都保持⾼电平。任⼀设备输出的低电平都将使相应的总线信号线变低,也就是说:各设备的SDA是“与”关系,SCL也是“与”关系。
2.2 IIC在stm32中的初始化
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);//先使能外设IO PORTB时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13; // 端⼝配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO⼝速度为50MHz
GPIO_Init(GPIOD, &GPIO_InitStructure); //根据设定参数初始化GPIO
GPIO_SetBits(GPIOD,GPIO_Pin_12|GPIO_Pin_13);
}厦门大学2013录取分数线
在.h⽂件中最好将SDA与SCL进⾏预处理⽅便移植和使⽤:
#define IIC_SCL PDout(12) //SCL
#define IIC_SDA PDout(13) //SDA
#define READ_SDA PDin(13) //输⼊SDA
其他的IIC读取和写⼊函数在例程中已完成,我们主要的⼯作是将任意两端⼝配置为IIC的SDA和SCL.
3 MPU6050初始化
/**************************实现函数********************************************
*函数原型: void MPU6050_initialize(void)
*功 能: 初始化 MPU6050 以进⼊可⽤状态。
*******************************************************************************/
void MPU6050_initialize(void)
{
MPU6050_tClockSource(MPU6050_CLOCK_PLL_ZGYRO); //设置时钟
meditation什么意思
MPU6050_tFullScaleGyroRange(MPU6050_GYRO_FS_1000);//陀螺仪最⼤量程 +-1000度每秒
MPU6050_tFullScaleAccelRange(MPU6050_ACCEL_FS_2); //加速度度最⼤量程 +-2G
silent night
MPU6050_tSleepEnabled(0); //进⼊⼯作状态
MPU6050_tI2CMasterModeEnabled(0); //不让MPU6050 控制AUXI2C
MPU6050_tI2CBypassEnabled(0); //主控制器的I2C与 MPU6050的AUXI2C 直通。控制器可以直接访问HMC5883L
}
此配置的相关函数在mpu6050.h和iic.h中.
4 重点:DMP初始化
DMP是MPU6050官⽅给出的⼀种直接读取四元数的⽅法,上⼿⼗分⽅便,作为初学MPU6050,我们以此为例程.
void DMP_Init(void)
{
u8 temp[1] = {0};
i2cRead(0x68, 0x75, 1, temp);
printf("mpu_t_nsor complete ......\r\n");
if(temp[0] != 0x68)
NVIC_SystemRet();
if(!mpu_init())
{
if(!mpu_t_nsors(INV_XYZ_GYRO | INV_XYZ_ACCEL))
printf("mpu_t_nsor complete ......\r\n")
if(!mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL))
printf("mpu_configure_fifo complete ......\r\n");
if(!mpu_t_sample_rate(DEFAULT_MPU_HZ))
printf("mpu_t_sample_rate complete ......\r\n");
if(!dmp_load_motion_driver_firmware())
printf("dmp_load_motion_driver_firmware complete ......\r\n");
if(!dmp_t_orientation(inv_orientation_matrix_to_scalar(gyro_orientation)))
printf("dmp_t_orientation complete ......\r\n");
if(!dmp_enable_feature(DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP |
DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO | DMP_FEATURE_GYRO_CAL));
printf("dmp_enable_feature complete ......\r\n");
if(!dmp_t_fifo_rate(DEFAULT_MPU_HZ))
printf("dmp_t_fifo_rate complete ......\r\n");
run_lf_test();
if(!mpu_t_dmp_state(1))
printf("mpu_t_dmp_state complete ......\r\n");
}
}
此函数主要是对DMP进⾏初始化,如果想要了解每个函数具体是初始化的什么内容,请看printf函数输出的内容即可.
我们主要讲:陀螺仪是如何进⾏开机校准,或者设置开机不校准.
将⽬光放到**run_lf_test();**这个函数,这是⽤来设置校准的函数.
static void run_lf_test(void)
wirelesslan{
int result;
long gyro[3], accel[3];
result = mpu_run_lf_test(gyro, accel); //返回值是使⽤陀螺仪的型号,MPU6050对应的是0x03
if (result == 0x03)
{
/* Test pasd. We can trust the gyro data here, so let's push it down
* to the DMP.
*/
float ns;
eachotherdeath noteunsigned short accel_ns;
mpu_get_gyro_ns(&ns); //读取当前陀螺仪的状态
//ns=0;
英语教师网
gyro[0] = (long)(gyro[0] * ns);
gyro[1] = (long)(gyro[1] * ns);
gyro[2] = (long)(gyro[2] * ns);
dmp_t_gyro_bias(gyro); //根据读取的状态进⾏校准
mpu_get_accel_ns(&accel_ns); //读取当前加速度计的状态
accel[0] *= accel_ns;
accel[1] *= accel_ns;
accel[2] *= accel_ns;英文转换
dmp_t_accel_bias(accel); //根据读取的状态进⾏校准
printf("tting bias succesfully ......\r\n");
}
}
这样的话,mpu6050校准的过程就明确了.
如果不需要开机校准,可以是if(result==0x03)这个条件不满⾜,不进⼊处理,或者将陀螺仪 加速度计的基准设置函数t_bias不执⾏即可.
如果需要开机校准,保证整个校准流程正常执⾏就⾏.
4 陀螺仪漂移的解决⽅法
横滚⾓和俯仰⾓的偏差可以通过卡尔曼滤波或者⼀阶互补滤波即可消除漂移量.
但是**航向⾓存在的偏差很难由⾃⾝来校准,**这是由于:
Z轴在静⽌状态下没有漂移,运动情况下有累积误差。因为Z轴⾓度是通过对⾓速度积分计算出来的,没有观测量滤波,所以漂移是不可避免的。X、Y轴的⾓度是根据重⼒加速度分量计算,X,Y轴是有重⼒场滤波,所以不会有漂移。Z轴只能⽤短时间内的相对测量量。 就是相邻两次的⾓度差来计算转过的⾓度。
可以采⽤带地磁的9轴陀螺仪来降低漂移量,但是仍然⽆法完全解决这个问题.⽽且地磁计对周围磁场的变化敏感,多磁场和多电机的⼯作环境都会导致地磁计不准.
bbq是什么意思