> For the complete documentation index, see [llms.txt](https://libooogo.gitbook.io/esplane/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://libooogo.gitbook.io/esplane/developer-guide/09esp32+-tuo-luo-yi-jia-su-du-ji-mpu6050-yi-zhi-yu-tiao-shi.md).

# 06 Gyro and Accelerometer MPU6050 Driver

| 文章更新版本 | 时间                     | 备注            |
| ------ | ---------------------- | ------------- |
| V0.1   | 发布于2019-08-29 11:14:22 | 初始版本          |
| V0.2   | 更新于2019-12-23 18:12:16 | 增加mpu6050方向定义 |

## 一、开发笔记

**1. 数字陀螺仪传感器工作原理**

* 陀螺仪:当陀螺仪围绕任何感应轴旋转时,科里奥利效应就会产生电容式传感器检测到的振动. 所得到的信号被放大,解调和滤波产生与角速度成比例的电压.
* 电子加速度计:加速沿着一条特定轴在相应的检测质量上引起位移,引起电容式传感器检测电容的变化.

**2. 数字运动处理器(DMP)**

* MPU6050自带一个数字运动处理单元,可以计算四元数等,减轻主控制器压力.
* DMP可以通过引脚触发中断.

**3. 辅助I2C串行接口**

* MPU-60X0 具有一个辅助 I2C 总线,用于与片外3轴数字输出磁力计进行通信或其他传感器.
* 辅助I2C串行接口有两种工作模式:I2C Master Mode和Pass-Through Mode.

**4. MPU-60X0 FIFO**

* MPU-60X0包含一个可通过串行接口访问的1024字节FIFO寄存器. FIFO配置寄存器决定哪个数据写入FIFO. 可能的选择包括陀螺仪数据,加速计数据,温度读数,辅助传感器读数和 FSYNC 输入.

**5. 数字低通滤波器(DLPF)**

* MPU6050自带低通滤波器,可以通过配置寄存器26控制低通滤波频段,减少高频干扰.但是会降低传感器输入速率(开启DLPF加速度计输出1kHZ,关闭DLPF可以输出8Khz)

**6. FSYNC帧同步采样引脚**

* 寄存器26-EXT\_SYNC\_SET,用于配置外部帧同步引脚的采样

**7. MPU6050方向定义**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20191223181043862.jpg)

## 二、MPU6050初始化步骤

1. 恢复寄存器默认值

   设置PWR\_MGMT\_1 bit7为1,恢复后bit7为0,bit6自动设置为1,进入sleep模式.
2. 设置PWR\_MGMT\_1 bit6为0,唤醒传感器
3. 设置时钟源
4. 设置量程

   分别设置陀螺仪和加速度计量程.
5. 设置采样率
6. 设置数字低通滤波器(选配)

## 三、MPU6050几个重要寄存器

### 寄存器典型值

|      寄存器      |  典型值 |             功能             |
| :-----------: | :--: | :------------------------: |
|  PWR\_MGMT\_1 | 0x00 |            正常启用            |
|  SMPLRT\_DIV  | 0x07 |        陀螺仪采用率 125Hz        |
|     CONFIG    | 0x06 |        低通滤波器频率为 5Hz        |
|  GYRO\_CONFIG | 0x18 | 陀螺仪不自检,输出满量程范围为 ± 2000 °/s |
| ACCEL\_CONFIG | 0x01 |    加速度计不自检,输出的满量程范围为± 2g   |

### 寄存器117-设备地址-WHO\_AM\_I

\[6:1] 保存设备地址,默认为 0x68,不反应AD0引脚值.

![WHO\_AM\_I](https://img-blog.csdnimg.cn/20191031210406623.png)

### 寄存器107-电源管理1-PWR\_MGMT\_1

![PWR\_MGMT\_1](https://img-blog.csdnimg.cn/20191031210509627.png)

DEVICE\_RESET:设置为1时,寄存器值设置为默认. SLEEP 当该位置1时,该位将MPU-60X0置于睡眠模式. CYCLE 当该位设置为1且SLEEP被禁止时,MPU-60X0将循环在睡眠模式和唤醒之间以LP\_WAKE\_CTRL(寄存器108)确定的速率从活动传感器获取单个样本数据.

### 寄存器26-配置数字低通滤波器 -CONFIG

![CONFIG](https://img-blog.csdnimg.cn/20191031210607814.png)

数字低通滤波器(DLPF)取值与滤波频段关系:

![DLPF](https://img-blog.csdnimg.cn/2019103121071933.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIwNTE1NDYx,size_16,color_FFFFFF,t_70)

### 寄存器27 - 陀螺仪量程配置-GYRO\_CONFIG

![GYRO\_CONFIG](https://img-blog.csdnimg.cn/20191031210757849.png)

XG\_ST-X轴陀螺仪自检,FS\_SEL用于配置陀螺仪量程:

![FS\_SEL](https://img-blog.csdnimg.cn/20191031210847714.png)

### 寄存器28 - 加速度计量程配置-ACCEL\_CONFIG

![ACCEL\_CONFIG](https://img-blog.csdnimg.cn/20191031210931640.png)

![加速度计量程配置](https://img-blog.csdnimg.cn/20191031211013376.png)

### 寄存器25 - 采样速率分频器-SMPRT\_DIV

该寄存器指定用于产生MPU-60X0采样率的陀螺仪输出速率的分频器.传感器寄存器输出,FIFO输出和DMP采样都基于采样率.采样率是通过将陀螺仪输出速率除以 SMPLRT\_DIV 产生的.

![SMPRT\_DIV](https://img-blog.csdnimg.cn/20191029104332197.png)

> Sample Rate = Gyroscope Output Rate / (1 + SMPLRT\_DIV) where Gyroscope Output Rate = 8kHz when the DLPF is disabled (DLPF\_CFG = 0 or 7), and 1kHz when the DLPF is enabled (see Register 26)

在不开启DLPF的情况下,设置SMPLRT\_DIV 为7可以时芯片产生1khz的中断信号.

![SMPLRT\_DIV=7](https://img-blog.csdnimg.cn/20191029104955198.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIwNTE1NDYx,size_16,color_FFFFFF,t_70)

### 寄存器59到64-加速度计测量值

![加速度计测量值](https://img-blog.csdnimg.cn/20191031211109139.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIwNTE1NDYx,size_16,color_FFFFFF,t_70)

大数端存放:地址地位存放数据高位,地址高位存放数据地位. 补码存放:因为测量值为有符号整数,因此采用补码方式存放

### 寄存器65和66 - 温度测量

![温度测量值](https://img-blog.csdnimg.cn/20191031211137105.png)

### 寄存器67至72 - 陀螺仪测量值

![陀螺仪测量值](https://img-blog.csdnimg.cn/20191031211243676.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIwNTE1NDYx,size_16,color_FFFFFF,t_70)

## 四、 MPU6050传感器DMP功能

惯性传感器芯片内部一般会集成一个DMP(Digital Motion Processor)处理器,可以直接硬件解算四元数,解放主控资源. 注意关注一下硬件姿态解算,并不是之前印象中的那么难用,在crazypony开源项目中,开发者测试直接从MPU6050的DMP输出四元数,可以做的更加稳定,如果再外加一个磁力计,可以直接输出带有东西南北绝对位置.

![MPU6050 DMP](https://img-blog.csdnimg.cn/20190809121649654.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIwNTE1NDYx,size_16,color_FFFFFF,t_70)

## 五、I2C相关知识

* 数据传输:SCL为高电平时,SDA线若保持稳定,那么SDA上是在传输数据bit；若SDA发生跳变,则用来表示一个会话的开始或结束.
* 数据改变:SCL为低电平时,SDA线才能改变传输的bit.
* 处理繁忙:如果从机处于繁忙状态,并且现在不方便接受下一个字节,可以保持SCL为低电平,从而强制主机进入等待状态,等准备号后释放时钟线.
* 处理应答:应答时钟由主机控制,应答信号-在第9个时钟周期,SCL为高,SDA为低.拒绝应答-在第9个时钟周期,SDA一直为高.

![I2C信号](https://img-blog.csdnimg.cn/20191031211402937.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIwNTE1NDYx,size_16,color_FFFFFF,t_70)

![单字节写](https://img-blog.csdnimg.cn/2019103121150031.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIwNTE1NDYx,size_16,color_FFFFFF,t_70)

![双字节写](https://img-blog.csdnimg.cn/20191031211510492.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIwNTE1NDYx,size_16,color_FFFFFF,t_70)

![单字节读](https://img-blog.csdnimg.cn/20191031211519173.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIwNTE1NDYx,size_16,color_FFFFFF,t_70)

![双字节读](https://img-blog.csdnimg.cn/20191031211528953.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIwNTE1NDYx,size_16,color_FFFFFF,t_70)

## 六、调试记录

* 初始化异常报错

  检查连接和代码都没有问题,更换传感器模块后正常.此错误为传感器模块质量问题,导致通信不正常.

```
E (262) I2Cbus: [port:0, slave:0x68] Failed to read 1 bytes from register 0x75, error: 0xFFFFFFFF
E (272) MPU6050: func:uint8_t mpud::MPU::whoAmI() @ line:162, expr:"readByte(regs::WHO_AM_I, buffer)", error:0xFFFFFFFF 
E (282) MPU6050: func:esp_err_t mpud::MPU::testConnection() @ line:143, expr:"lastError()", error:0xFFFFFFFF 
E (292) example: Failed to connect to the MPU, error=0XFFFFFFFF
```

更换模块后输出正常(未减去基准值)

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190826205406353.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIwNTE1NDYx,size_16,color_FFFFFF,t_70)

## 七、参考链接

1. [MPU6050开发 -- 基本概念简介](https://blog.csdn.net/qq_29350001/article/details/78603714)
2. [MPU6050开发 -- 进阶之I2C/SPI通信协议](https://blog.csdn.net/qq_29350001/article/details/78611309)
3. [MPU6050开发 -- 测试程序分析](https://blog.csdn.net/qq_29350001/article/details/78623928)
4. [esp32-MPU-driver](https://github.com/natanaeljr/esp32-MPU-driver)
