基本概念
MPU6050是通过IIC进行通信,其中包括了三轴加速度传感器,三轴陀螺仪(三轴角速度)。利用 MPU6050 芯片内部的 DMP 模块(Digital Motion Processor 数字运动处理器),可对传感器数据进行滤波、融合处理,直接通过 IIC 接口向主控器输出姿态解算后的数据,降低主控器的运算量。所采用的的通信方式采用的是IIC协议,用EEPROM进行读写存储。
编程步骤
1、先进行引脚以及IIC的初始化
void I2cMaster_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
/* Enable I2Cx clock */
RCC_APB1PeriphClockCmd(SENSORS_I2C_RCC_CLK, ENABLE);
/* Enable I2C GPIO clock */
RCC_AHB1PeriphClockCmd(SENSORS_I2C_SCL_GPIO_CLK | SENSORS_I2C_SDA_GPIO_CLK, ENABLE);
/* Configure I2Cx pin: SCL ----------------------------------------*/
GPIO_InitStructure.GPIO_Pin = SENSORS_I2C_SCL_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
/* Connect pins to Periph */
GPIO_PinAFConfig(SENSORS_I2C_SCL_GPIO_PORT, SENSORS_I2C_SCL_GPIO_PINSOURCE, SENSORS_I2C_AF);
GPIO_Init(SENSORS_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
/* Configure I2Cx pin: SDA ----------------------------------------*/
GPIO_InitStructure.GPIO_Pin = SENSORS_I2C_SDA_GPIO_PIN;
/* Connect pins to Periph */
GPIO_PinAFConfig(SENSORS_I2C_SDA_GPIO_PORT, SENSORS_I2C_SDA_GPIO_PINSOURCE, SENSORS_I2C_AF);
GPIO_Init(SENSORS_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
I2C_DeInit(SENSORS_I2C);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = I2C_OWN_ADDRESS;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
/* Enable the I2C peripheral */
I2C_Cmd(SENSORS_I2C, ENABLE);
/* Initialize the I2C peripheral */
I2C_Init(SENSORS_I2C, &I2C_InitStructure);
return;
}
2、MPU6050初始化
void MPU6050_Init(void)
{
int i=0,j=0;
//在初始化之前要延时一段时间,若没有延时,则断电后在上电数据可能会出错
for(i=0;i<1000;i++)
{
for(j=0;j<1000;j++)
{
;
}
}
MPU6050_WriteReg(MPU6050_RA_PWR_MGMT_1, 0x00); //½â³ýÐÝÃß״̬
MPU6050_WriteReg(MPU6050_RA_SMPLRT_DIV , 0x07); //ÍÓÂÝÒDzÉÑùÂÊ
MPU6050_WriteReg(MPU6050_RA_CONFIG , 0x06);
MPU6050_WriteReg(MPU6050_RA_ACCEL_CONFIG , 0x01); //ÅäÖüÓËÙ¶È´«¸ÐÆ÷¹¤×÷ÔÚ16Gģʽ
MPU6050_WriteReg(MPU6050_RA_GYRO_CONFIG, 0x18); //ÍÓÂÝÒÇ×Լ켰²âÁ¿·¶Î§£¬µäÐÍÖµ£º0x18(²»×Լ죬2000deg/s)
}
写MPU6050寄存器中
3、读取MPU6050ID(检测的作用)
4、读取加速的值
加速度数寄存器地址是0x3B
读取角速度的值
陀螺仪数寄存器地址是0x43
DMP 进行姿态解算可以得出欧拉角(偏航角,俯仰角,横滚角)
首先还是需要定义IIC的读写函数数据,进行数据的读写
宏定义中get_tick_count是可以计算出调用的间隔
使用的外部中断是15
获取欧拉角的函数
- Pitch: -180 to 180
- Roll: -90 to 90
- Yaw: -180 to 180
参数:data:欧拉角度,单位为度,q16不动点
accuracy:精度从0开始测量(最不准确)到3(最准确)
timestamp:读取此传感器时间(以毫秒为单位)
pitch(俯仰角)、yaw(偏航角)、roll(横滚角)
int inv_get_sensor_type_euler(long *data, int8_t *accuracy, inv_time_t *timestamp)
{
long t1, t2, t3;
long q00, q01, q02, q03, q11, q12, q13, q22, q23, q33;
float values[3];
q00 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[0]);
q01 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[1]);
q02 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[2]);
q03 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[3]);
q11 = inv_q29_mult(eMPL_out.quat[1], eMPL_out.quat[1]);
q12 = inv_q29_mult(eMPL_out.quat[1], eMPL_out.quat[2]);
q13 = inv_q29_mult(eMPL_out.quat[1], eMPL_out.quat[3]);
q22 = inv_q29_mult(eMPL_out.quat[2], eMPL_out.quat[2]);
q23 = inv_q29_mult(eMPL_out.quat[2], eMPL_out.quat[3]);
q33 = inv_q29_mult(eMPL_out.quat[3], eMPL_out.quat[3]);
/* X component of the Ybody axis in World frame */
t1 = q12 - q03;
/* Y component of the Ybody axis in World frame */
t2 = q22 + q00 - (1L << 30);
values[2] = -atan2f((float) t1, (float) t2) * 180.f / (float) M_PI;
/* Z component of the Ybody axis in World frame */
t3 = q23 + q01;
values[0] =
atan2f((float) t3,
sqrtf((float) t1 * t1 +
(float) t2 * t2)) * 180.f / (float) M_PI;
/* Z component of the Zbody axis in World frame */
t2 = q33 + q00 - (1L << 30);
if (t2 < 0) {
if (values[0] >= 0)
values[0] = 180.f - values[0];
else
values[0] = -180.f - values[0];
}
/* X component of the Xbody axis in World frame */
t1 = q11 + q00 - (1L << 30);
/* Y component of the Xbody axis in World frame */
t2 = q12 + q03;
/* Z component of the Xbody axis in World frame */
t3 = q13 - q02;
values[1] =
(atan2f((float)(q33 + q00 - (1L << 30)), (float)(q13 - q02)) *
180.f / (float) M_PI - 90);
if (values[1] >= 90)
values[1] = 180 - values[1];
if (values[1] < -90)
values[1] = -180 - values[1];
data[0] = (long)(values[0] * 65536.f);
data[1] = (long)(values[1] * 65536.f);
data[2] = (long)(values[2] * 65536.f);
accuracy[0] = eMPL_out.quat_accuracy;
timestamp[0] = eMPL_out.nine_axis_timestamp;
return eMPL_out.nine_axis_status;
}