Foreword: I haven't written an article in recent months, because there are really a lot of things this semester, but after thinking about it, the article still needs to be updated. It is really important to summarize the knowledge I have learned! ! !
Not much nonsense, the text begins:
1. Introduction to MPU6050
MPU6050 is the world's first integrated 6-axis motion processing component launched by InvenSense . Compared with multi-component solutions, it eliminates the problem of inter-axis difference when combining gyroscopes and accelerators, and reduces the installation space. The MPU6050 integrates a 3-axis gyroscope and a 3-axis acceleration sensor , and contains a second IIC interface , which can be used to connect external magnetic sensors, namely AUX_CL and AUX_DA, and use the built-in digital motion processor (DMP: DigitalMotion Processor) hardware acceleration The engine outputs complete 9-axis fusion calculation data to the application side through the main IIC interface. With DMP, we can use the motion processing database provided by InvenSense to realize attitude calculation very conveniently, reduce the load of motion processing calculation on the operating system, and greatly reduce the difficulty of development.
2. Introduction to initialization steps and registers
(i) First, initialize the IIC communication protocol, initialize the SCL and SDA interfaces, and ensure that the mpu6050 can communicate with the STM32 motherboard.
(ii) Reset MPU6050 and wake up MPU6050
When resetting the MPU6050, set Bit7 [DEVICE_RESET] to 1 to reset it. At the same time, the SLEEP bit will become 1 [1: sleep mode 0: normal working mode], so it is necessary to wake up the MPU6050, which will be changed to Set it to 0 to proceed to the next step. TEMP_DIS is used to set whether to enable the temperature sensor, and set it to 0 to enable it.
MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X80); //复位MPU6050
delay_ms(100);
MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X00); //唤醒MPU6050
(iii) Initialize the gyroscope sensor [angular velocity sensor]
The register needs to pay attention to the two bits of FS_SEL, which is the range of the angular velocity range
The concept of the full scale of this gyroscope is:
The range refers to the maximum range. For example, if you choose FS_SEL == 2 ---> ±1000°/s, it can be detected within 1000 per second, but when it is greater than 1000°, it cannot be detected.
(iv) Acceleration sensor
Same as above, pay attention to these two FS_SEL.
eg: 2g == two gravitational accelerations = 19.6m/s², and so on to determine the maximum range.
The sensitivity is: 65536
(2^16) /4000
(2000*2)=16384LSB/g。
But generally we use the mpu6050 to choose ±1000°/s and ±2g.
MPU_Set_Gyro_Fsr(3); //陀螺仪传感器,±2000dps
MPU_Set_Accel_Fsr(0); //加速度传感器,±2g
(v) FIFO enable register
Set ACCEL_FIFO_EN to 1, then turn on FIFO, then turn on the three bits of the acceleration sensor, set it to 0, then turn off FIFO. The angular velocity sensor needs to be individually controlled to be turned on or not.
MPU_Write_Byte(MPU_FIFO_EN_REG,0X00); //关闭FIFO
(vi) Gyroscope Sampling Rate Divider Register
(vii) Configuration registers
Mainly look at the lower three settings:
Generally set bandwidth = sampling frequency/2.
(viii) Acceleration output register, gyroscope output register, temperature output register
The temperature conversion formula is:
Temperature = 36.53 + regval/340.
These three are the values of the output sensor, the high byte is in front, and the low byte is in the back.
//得到温度值
//返回值:温度值(扩大了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];
*gy=((u16)buf[2]<<8)|buf[3];
*gz=((u16)buf[4]<<8)|buf[5];
}
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];
*ay=((u16)buf[2]<<8)|buf[3];
*az=((u16)buf[4]<<8)|buf[5];
}
return res;;
}
Understand a line of code:
((u16)buf[0]<<8)|buf[1]
Force-convert buf[0] to 16int type data, then shift it to the left by eight bits, so that the lower eight bits are vacated, move the eight bits of buf[1] into the lower eight bits, and form 16-bit data. Then send it out.
(ix) Simple explanation of DMP
The DMP will transmit the values of the gyroscope sensor and the acceleration sensor, and output the quaternion [q30 format] with the help of the DMP, which is enlarged by 2 to the 30th power, so it needs to be divided back.
q0 = quat[0] / q30; //q30 format is converted to a floating point number
q1 = quat[1] / q30;
q2 = quat[2] / q30;
q3 = quat[3] / q30;
Then convert to angle with the help of formula. Divide by 57.3 to convert radians to degrees
*pitch = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; // pitch
*roll = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2 * q2 + 1)* 57.3; // roll
*yaw = atan2(2*(q1*q2 + q0*q3), q0*q0+q1*q1-q2*q2-q3*q3) * 57.3; //yaw
Note: If you need OLED display, you only need to configure an OLED IIC communication normally, then set the character size you need, and then set the corresponding required font and variables, so that it can be displayed on the display screen, or you can also You can choose the serial port 1printf output.
Physical map: