这篇文章主要是个人的学习经验,想分享出来供大家提供思路,如果其中有不足之处请批评指正哈。
废话不多说直接开始主题,本人是基于STM32F407VET6芯片,但是意在你看懂这篇文章后,不管是F1,F4,H7等一系列MPU6050通讯硬件寄存器配置部分都能明白如何通过参考手册去学习配置。而不是Ctrl c,Ctrl v。这篇文章大致的简述一下MPU6050硬件基础知识基于STM32F407VET6,以及MPU6050寄存器相关配置。
摘要:对硬件大致介绍,本人这篇文章是在正点原子的资料的基础上继续分析的,是对正点原子资料与官方寄存器手册的总结与分享,对寄存器的配置进行讲解,供开发者们借鉴学习。
硬件介绍
**以下内容是引用于正点原子,并对其进行总结概述。**
MPU6050 内部整合了 3 轴陀螺仪和 3 轴加速度传感器,并且含有一个第二 IIC 接口,可用于连接外部磁力传感器,并利用自带的数字运动处理器(DMP: Digital Motion Processor)硬件加速引擎,通过主 IIC 接口,向应用端输出完整的 9 轴融合演算数据。
①欧拉角格式(Euler Angle forma)的融合演算数据(需DMP 支持)
② 具有 131 LSBs/°/sec 敏感度与全格感测范围为±250、±500、±1000 与±2000°/sec 的 3 轴角速度感测器(陀螺仪)
③ 集成可程序控制,范围为±2g、±4g、±8g 和±16g 的 3 轴加速度传感器
④ 移除加速器与陀螺仪轴间敏感度,降低设定给予的影响与感测器的飘移
⑤ 自带数字运动处理(DMP: Digital Motion Processing)引擎可减少MCU复杂的融合演算数据、感测器同步化、姿势感应等的负荷
⑥ VDD供电电压为 2.5V±5%、3.0V±5%、3.3V±5%;VLOGIC 可低至 1.8V± 5%
其中,SCL和 SDA是连接MCU的 IIC 接口,MCU通过这个 IIC 接口来控制MPU6050,另外还有一个 IIC 接口AUX_CL 和 AUX_DA,这个接口可用来连接外部从设备,比如磁传感器,这样就可以组成一个九轴传感器。VLOGIC 是 IO 口电压,该引脚最低可以到 1.8V,我们一般直接接 VDD (3.3V)即可。AD0 是从 IIC 接口(接 MCU)的地址控制引脚,该引脚控制IIC 地址的最低位。如果接 GND,则 MPU6050 的 IIC 地址是:0X68,如果接 VDD,则是0X69
初始化寄存器步骤
1)初始化 IIC接口
所以我们需要先初始化与MPU6050 连接的 SDA和 SCL数据线简称接线。
2)复位MPU6050
第一步让MPU6050 内部所有寄存器恢复默认值。通过对电源管理寄存器 1(0X6B)的bit7 写 1 实现。
寄存器手册P42写到,当DEVICE_RESET设置为1时,该位将所有内部寄存器复位为其默认值。复位完成后,该位自动清0。
但是Section3中寄存器手册P8写到,除以下寄存器外,所有寄存器的复位值均为0x00。 所以复位后,电源管理寄存器 107 恢复默认值(0X40),而0x40对应的是0100,0000 SLEEP为1,MPU-60X0会进入低功耗睡眠模式。并不需要其进入这个模式,所以必须设置该寄存器为0X00,也就是CLKSEL[2:0]=0;也就是使用外部8M晶振模式。
以唤醒MPU6050,进入正常工作状态。
//电源寄存器配置代码,严格按照寄存器要求编写代码
//1.初始化电源,AD0悬空、GND IIC地址0x68
#define MPU_ADDR 0X68
#define MPU_PWR_MGMT1_REG 0X6B //电源管理寄存器1
MPU_Write_Byte(MPU_ADDR, MPU_PWR_MGMT1_REG, 0X80); //复位MPU6050 0x6B第bit7写1=1000,0000=0x80
HAL_Delay(100); //延时100ms
//2.复位后电源管理寄存器自动恢复默认值0x40
//3.设置该寄存器为0x00唤醒MPU6050,正常工作状态
MPU_Write_Byte(MPU_ADDR, MPU_PWR_MGMT1_REG, 0X00); //唤醒MPU6050
3)设置角速度传感器(陀螺仪)和加速度传感器的满量程范围
设置两个传感器的满量程范围(FSR),分别通过陀螺仪配置寄存器(0X1B)和加速度传感器配置寄存器(0X1C)设置。我们一般设置陀螺仪的满量程范围为±2000dps,加速度传感器的满量程范围为±2g。
寄存器手册P14写到通过控制此寄存器的XG_ST、YG_ST和ZG_ST位,可以激活陀螺仪各轴的自检。由于暂时不需要自检不用配置。FS_SEL根据下表选择陀螺仪输出的满量程范围,配置成模式3也就是往寄存器中写入00011000。
//陀螺仪寄存器配置代码,严格按照寄存器要求编写代码
#define MPU_GYRO_CFG_REG 0X1B //陀螺仪配置寄存器
MPU_Set_Gyro_Fsr(3); //陀螺仪传感器,±2000dps 0X1B写入0001,1000=3左移3位=0110左移三位
u8 MPU_Set_Gyro_Fsr(u8 fsr) //将3左移三位也就是0001,1000
{
return MPU_Write_Byte(MPU_ADDR, MPU_GYRO_CFG_REG, fsr << 3); //设置陀螺仪满量程范围3,±2000dps
}
同理加速度传感器配置寄存器(0X1C)配置 AFS_SEL根据下表选择加速度计输出的满量程范围,加速度传感器的满量程范围为±2g,寄存器配置也就是0000,0000。
//加速度计寄存器配置代码,严格按照寄存器要求编写代码
#define MPU_ACCEL_CFG_REG 0X1C //加速度计配置寄存器
MPU_Set_Accel_Fsr(0); //加速度传感器,±2g 0x1C写入0000,0000 左移3位=0000,0000
u8 MPU_Set_Accel_Fsr(u8 fsr) //不用左移3位也没事
{
return MPU_Write_Byte(MPU_ADDR, MPU_ACCEL_CFG_REG, fsr << 3); //设置加速度传感器满量程范围
}
4)设置其他参数
我们还需要配置的参数有:1.关闭中断、2.关闭AUX IIC 接口、3.禁止 FIFO、4.设置陀螺仪采样率和设置数字低通滤波器(DLPF)等,一步一步来。
1.关闭中断
我们不用中断方式读取数据,所以关闭中断,关闭中断相关配置的寄存器是0X38
根据寄存器手册知不需要中断的话以上4个标志位需要为0,也就是寄存器配置成X0X0,0XX0即可,电源寄存器配置时56已经至0x00但是还是重新配置一下较好,配置成0x00,不要配置成X0X0,0XX0给自己整活。
//关闭中断寄存器配置代码,严格按照寄存器要求编写代码
#define MPU_INT_EN_REG 0X38 //中断使能寄存器
MPU_Write_Byte(MPU_ADDR, MPU_INT_EN_REG, 0X00); //关闭所有中断
2.关闭AUX IIC 接口
没用到 AUX IIC 接口外接其他传感器,所以也关闭这个接口。关闭AUX IIC相关配置的寄存器是0X6A。
根据寄存器手册P39,写到如果是MPU6050,I2C_IF_DIS必须为0.
FIFO_EN:该位设为1时,使能FIFO操作。当此位清0时,FIFO缓冲器禁用。禁用时,无法写入或读取FIFO缓冲区。FIFO缓冲器的状态不会改变,除非MPU-60 X 0重新上电。
I2C_MST_EN:该位设为1时,使能I2C主机模式。当该位清0时,辅助I2C总线(AUX_DA和AUX_CL)由主I2C总线(SDA和SCL)逻辑驱动。
I2C_IF_DIS:MPU-6050 Always write this bit as zero
I2C_MST_RESET:当I2C_MST_EN置1时,此位使I2C主机复位。触发重置后,该位自动清0。
SIG_COND_RESET:设置为1时,该位复位所有传感器(陀螺仪、加速度计和温度传感器)的信号路径。此操作还将清除传感器寄存器。触发复位后,该位自动清0。
综上不需要使用时,0X6A配置成0x00即可。
//关闭AUX IIC 接口寄存器配置代码,严格按照寄存器要求编写代码
#define MPU_USER_CTRL_REG 0X6A //用户控制寄存器
MPU_Write_Byte(MPU_ADDR, MPU_USER_CTRL_REG, 0X00); //I2C主模式关闭
3.禁止 FIFO
MPU6050 可以使用 FIFO 存储传感器数据,不过本章我们没有用到,所以关闭所有 FIFO 通道,这个通过 FIFO 使能寄存器(0X23)控制,默认都是 0(即禁止 FIFO),所以用默认值就可以了0X00。
如果配置FIFO的话需要进一步对FIFO相关的寄存器进行配置,从65至96
//禁止FIFO寄存器配置代码,严格按照寄存器要求编写代码
#define MPU_FIFO_EN_REG 0X23 //FIFO使能寄存器
MPU_Write_Byte(MPU_ADDR, MPU_FIFO_EN_REG, 0X00); //关闭FIFO
4.设置陀螺仪采样率和设置数字低通滤波器(DLPF)
陀螺仪采样率通过采样率分频寄存器(0X19)控制,采样率我们一般设置为 50 即可。
SMPLRT_DIV生成采样速率:Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV)。当DLPF禁用(DLPF_CFG = 0或7)时,陀螺仪输出速率= 8 kHz;当DLPF使能(参见寄存器26)时,陀螺仪输出速率= 1 kHz。
所以还要参考26寄存器。
此寄存器配置陀螺仪和加速度计的外部帧同步(FSYNC)引脚采样和数字低通滤波器(DLPF)设置。
DLPF由DLPF_CFG配置。加速度计和陀螺仪根据DLPF_CFG的值进行滤波,如下表所示。
决定你寄存器的取值取决于你的工作频率,数字低通滤波器(DLPF)则通过配置寄存器(0X1A)设置,一般设置DLPF 为带宽的 1/2 即可。即50HZ/2=25HZ,带宽21<25<44,选择4即可。带入公式Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV)。最终得算采样速率=1000HZ/(1+4)=200HZ
//设置陀螺仪采样率和设置数字低通滤波器寄存器配置代码,严格按照寄存器要求编写代码
#define MPU_CFG_REG 0X1A //配置寄存器
#define MPU_SAMPLE_RATE_REG 0X19 //采样频率分频器
MPU_Set_Rate(50); //设置采样率50Hz
//设置MPU6050的采样率(假定Fs=1KHz)
//rate:4~1000(Hz)
//返回值:0,设置成功
// 其他,设置失败
u8 MPU_Set_Rate(u16 rate)
{
u8 data;
if (rate > 1000) rate = 1000;
if (rate < 4) rate = 4;
data = 1000 / rate - 1;
data = MPU_Write_Byte(MPU_ADDR, MPU_SAMPLE_RATE_REG, data); //设置数字低通滤波器
return MPU_Set_LPF(rate / 2); //自动设置LPF为采样率的一半
}
//设置MPU6050的数字低通滤波器
//lpf:数字低通滤波频率(Hz)
//返回值:0,设置成功
// 其他,设置失败
u8 MPU_Set_LPF(u16 lpf)
{
u8 data = 0;
if (lpf >= 188) data = 1;
else if (lpf >= 98) data = 2;
else if (lpf >= 42) data = 3;
else if (lpf >= 20) data = 4;
else if (lpf >= 10) data = 5;
else data = 6;
return MPU_Write_Byte(MPU_ADDR, MPU_CFG_REG, data); //设置数字低通滤波器
}
5)配置系统时钟源并使能角速度传感器和加速度传感器
在此之前读取一下MPU6050的IIC地址,AD0引脚改变地址状态。读取地址0x75。
此寄存器用于验证设备的身份。WHO_AM_I的内容是MPU-60X0的7位I2C地址的高6位。MPU-60X0的I2C地址的最低有效位由AD 0引脚的值决定。AD0引脚的值不反映在此寄存器中。说明:寄存器的默认值为0x68。系统时钟源同样是通过电源管理寄存器 1(0X6B)来设置,该寄存器的最低三位用于设置系统时钟源选择,默认值是 0(内部8M RC震荡),不过我们一般设置为 1,选择 x 轴陀螺 PLL作为时钟源,以获得更高精度的时钟。同时,使能角速度传感器和加速度传感器,这两个操作通过电源管理寄存器 2(0X6C)来设置,设置对应位为 0 即可开启。至此,MPU6050 的初始化就完成了,可以正常工作了(其他未设置的寄存器全部采用默认值即可),接下来,我们就可以读取相关寄存器,得到加速度传感器、角速度传感器和温度传感器的数据了。
//配置系统时钟源并使能角速度传感器和加速度传感器寄存器配置代码,严格按照寄存器要求编写代码
res = MPU_Read_Byte(MPU_ADDR, MPU_DEVICE_ID_REG);
if (res == MPU_ADDR) //器件ID正确
{
MPU_Write_Byte(MPU_ADDR, MPU_PWR_MGMT1_REG, 0X01); //设置CLKSEL,PLL X轴为参考
MPU_Write_Byte(MPU_ADDR, MPU_PWR_MGMT2_REG, 0X00); //加速度与陀螺仪都工作
}
else
return 1;
return 0;