#前言: 陀螺仪的用处还是挺多滴,俺最近搬了15646块大理石终于凑齐了买一块正点原子的MPU6050的钱了,下面分享一下怎么配套STM32使用,主要分享一下应用部分,原理部分这里省略15000个字
硬件连接
MPU6050引脚图
🐟STM32的接线
@俺使用的单片机是stm32f103c8t6
PB10 -------> SCL
PB11 -------> SDA
VCC --------> 3.3V
GND --------> GND
INT|AD0 -------->悬空
其中SCL 和 SDA 是iic的时钟线和数据线 ,用于和客户端进行数据的通信 ,配置为开漏输出高速上拉模式(俺用的是软件IIC)
AD0用于设置 iic的地址,AD0接地或者不接的时候,iic的通信地址是0x68,AD0接vcc通信地址是0x69
//如果AD0脚(9脚)接地,IIC地址为0X68(不包含最低位).
//如果接V3.3,则IIC地址为0X69(不包含最低位).
#define MPU_ADDR 0x68
软件支持
底层库的支持
MPU6050的初始化
@MPU6050的初始化主要两个方面:MPU的初始化和DMP的初始化
MPU的初始化
上代码!
/**
* @brief 初始化MPU6050
* @param void
* @retval 0,成功
* 其他,错误代码
*/
unsigned char MPU_Init(IIC_PIN_Typedef *iic_pin)
{
unsigned char res;
/* 初始化IIC总线 */
IIC_Init(iic_pin);
IIC_Device_Write_Byte(iic_pin,MPU_ADDR,MPU_PWR_MGMT1_REG,0X80); //复位MPU6050
HAL_Delay(100);
IIC_Device_Write_Byte(iic_pin,MPU_ADDR,MPU_PWR_MGMT1_REG,0X00); //唤醒MPU6050
MPU_Set_Gyro_Fsr(iic_pin,3); //陀螺仪传感器,±2000dps
MPU_Set_Accel_Fsr(iic_pin,80); //加速度传感器,±2g
MPU_Set_Rate(iic_pin,1000); //设置采样率1000Hz
IIC_Device_Write_Byte(iic_pin,MPU_ADDR,MPU_INT_EN_REG,0X00); //关闭所有中断
IIC_Device_Write_Byte(iic_pin,MPU_ADDR,MPU_USER_CTRL_REG,0X00); //I2C主模式关闭
IIC_Device_Write_Byte(iic_pin,MPU_ADDR,MPU_FIFO_EN_REG,0X00); //关闭FIFO
IIC_Device_Write_Byte(iic_pin,MPU_ADDR,MPU_INTBP_CFG_REG,0X80); //INT引脚低电平有效
res = IIC_Device_Read_Byte(iic_pin,MPU_ADDR,MPU_DEVICE_ID_REG);
if(res == MPU_ADDR) //器件ID正确
{
IIC_Device_Write_Byte(iic_pin,MPU_ADDR,MPU_PWR_MGMT1_REG,0X01); //设置CLKSEL,PLL X轴为参考
IIC_Device_Write_Byte(iic_pin,MPU_ADDR,MPU_PWR_MGMT2_REG,0X00); //加速度与陀螺仪都工作
MPU_Set_Rate(iic_pin,1000); //设置采样率为50Hz
}else return 1;
return 0;
}
概括起来就是5个步骤
1 初始化IIC接口
2 复位MPU6050
3 设置角速度传感器和加速度传感器的满量程
4 设置其他参数(关闭中断、关闭 AUX IIC 接口、禁止 FIFO、设置陀螺
仪采样率和设置数字低通滤波器等)
5 配置系统时钟源并使能角速度传感器和加速度传感器
DMP初始化
DMP是讲MPU读出来的原始数据转化为“人话”的一个模块
/**
* @brief mpu6050,dmp初始化
* @param const signed char *row
* @retval 0,正常
* 其他,失败
*/
unsigned char mpu_dmp_init(void)
{
unsigned char res=0;
IIC_Init(&MPU6050_IIC_PIN); //初始化IIC总线
if(mpu_init()==0) //初始化MPU6050
{
res=mpu_set_sensors(INV_XYZ_GYRO|INV_XYZ_ACCEL); //设置所需要的传感器
if(res)return 1;
res=mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL); //设置FIFO
if(res)return 2;
res=mpu_set_sample_rate(DEFAULT_MPU_HZ); //设置采样率
//res=mpu_set_sample_rate(1000); //设置采样率
if(res)return 3;
res=dmp_load_motion_driver_firmware(); //加载dmp固件
if(res)return 4;
res=dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation));//设置陀螺仪方向
if(res)return 5;
res=dmp_enable_feature(DMP_FEATURE_6X_LP_QUAT|DMP_FEATURE_TAP| //设置dmp功能
DMP_FEATURE_ANDROID_ORIENT|DMP_FEATURE_SEND_RAW_ACCEL|DMP_FEATURE_SEND_CAL_GYRO|
DMP_FEATURE_GYRO_CAL);
if(res)return 6;
res=dmp_set_fifo_rate(DEFAULT_MPU_HZ); //设置DMP输出速率(最大不超过200Hz)
if(res)return 7;
res=run_self_test(); //自检
if(res)return 8;
res=mpu_set_dmp_state(1); //使能DMP
if(res)return 9;
}
return 0;
}
代码片
每个函数的作用都在注释写着,虽然每个英文字母我们都见过,但是连起来就是读不懂,其实每个函数都是大同小异的操作方式,概括起来就是:用IIC的写函数向一个寄存器地址写特定的位去实现某个功能,这些寄存器的地址在MPU6050的手册上面都有,建议先应用再一步步深究每个函数是怎么实现的
具体使用
使用起来并不困难,初始化就两行代码
MPU_Init(); //初始化MPU6050
mpu_dmp_init() //初始化DMP
下面是读取数据
int main()
{
temp=MPU_Get_Temperature(); //得到温度值
MPU_Get_Accelerometer(&aacx,&aacy,&aacz); //得到加速度传感器数据
MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz); //得到陀螺仪数据
}
就是这么思华!
遇到的问题
1 刚上手的时候用的是别人的iic库,然后因为是f4移植到f1 GPIO的一些寄存器不一样,所以导致IO口的输入输出模式没有写对,然后就会一直卡在DMP的init,小伙伴们多注意
2 理论上AD0和INT是要接的, 但是俺接了以后反而运行不了, 具体什么原因俺还没弄清清楚,不接就好了hhh
官方例程
官方例程俺放在下一篇文章啦!