Skip to content

概述

MPU6050 是经典的六轴运动传感器,六轴 = 三轴加速度计(测量物体在 X/Y/Z 三个方向受到的加速度,单位 g,1g≈9.8m/s²)+ 三轴陀螺仪(测量绕三个轴转动的快慢,单位 度/秒)。它是手机「横竖屏自动旋转」的核心器件。本教程用 Ai-WB2 开发板通过 I2C 总线(两根线的串行通信,一根时钟 SCL、一根数据 SDA)读取 MPU6050 的 6 个数值,串口实时打印,并走完 接线 → 代码编写 → 编译 → 烧录(把编译好的程序写进开发板芯片)→ 运行验证 的完整流程。

用大白话讲:MPU6050 内部有"一杆秤"(加速度计)和"一个陀螺"(陀螺仪)。手机横竖屏自动旋转就是靠它:平放时"秤"称出竖直方向受力约 1g,把手机竖起来,"秤"称出的受力方向就变了,系统据此判断手机姿态。本教程把这两组数据读出来打到串口:模块平放时,加速度 Z 轴应约为 1.0g,其他轴约 0;转动模块,陀螺仪数值跟着变。

本教程基于安信可官方 SDKAi-Thinker-Open/Ai-Thinker-WB2,版本 release_bl_iot_sdk_1.6.40)的官方示例 applications/iot-solution/demo_mpu6050 编写,代码可在本地 SDK 中直接找到。

🎯本页目标通过 I2C 读取 MPU6050 六轴数据(加速度 g + 陀螺仪 度/秒),串口每秒打印一次,理解寄存器型 I2C 设备与多文件驱动工程结构。
🧰前置条件① Ai-WB2 开发板 + MPU6050 六轴传感器模块 ② 已按 [SDK 安装](../sdk/sdk_intro) 完成环境搭建,并完成 [GPIO输出(点亮LED)](../basic/gpio_led)。
🔗相关章节I2C 基础原理见 [I2C 协议](../basic/i2c);其他 I2C 传感器见 [SHT30 温湿度传感器](./sht3x) 与 [BH1750 光照度传感器](./bh1750)。

硬件接线

按官方示例接线(见 SDK applications/iot-solution/demo_mpu6050/README.md),用杜邦线(两端带插针的连接线)连接:

Ai-WB2 引脚 MPU6050 引脚
IO4 SCL
IO5 SDA
3V3 VCC
GND GND

💡 MPU6050 是 I2C 设备,VCC 接 3.3V(多数模块板载稳压与上拉,供电更稳)。 💡 AD0 引脚决定 I2C 地址(门牌号):AD0 接 GND/悬空时地址为 0x68,接 3V3 时地址为 0x69。本教程代码默认 AD0 接低(MPU6050_ADDRESS_AD0_LOW),若你的模块 AD0 已接高,需要修改代码。 💡 注意本示例 I2C 时钟只有 25kHzfreq = 25000),比 100kHz 慢,这是驱动为了兼容长线、减少干扰的保守设置,不用改。

进入示例工程

本教程直接使用官方 SDK 自带的 demo_mpu6050 示例工程,打开终端进入该工程目录:

cd ~/Ai-Thinker-WB2/applications/iot-solution/demo_mpu6050

说明:cd 是「进入目录」命令,这里进入 MPU6050 示例工程目录;后续的 make 编译、make flash 烧录命令都必须先在这个目录里执行。

本工程是多文件工程:主程序 + 官方移植的 MPU6050 驱动库(源自开源 LibDriver 驱动,通过 I2C 读写芯片内部寄存器),结构如下:

文件 作用
demo_mpu6050/main.c 主程序源码,本教程主要查看的文件
demo_mpu6050/driver_mpu6050_basic.c/h 基础读写接口(初始化、读六轴数据)
demo_mpu6050/driver_mpu6050.c/h 寄存器级驱动核心(读写芯片内部寄存器配置)
demo_mpu6050/driver_mpu6050_fifo.c/h 数据 FIFO(先入先出缓存)功能,本教程未用到
demo_mpu6050/driver_mpu6050_dmp.c/h DMP(芯片内部姿态解算引擎),本教程未用到
demo_mpu6050/driver_mpu6050_interface_bl602.c 平台适配层:把 I2C 读写接到 WB2 的 IO4/IO5 上
Makefile 编译入口,一般无需修改
编写代码

打开 demo_mpu6050/main.c,本步完整代码已移至文末,见:

📜 完整代码 — 位于本页「完整代码」章节,默认折叠,点击展开,与官方示例(applications/iot-solution/demo_mpu6050/demo_mpu6050/main.c)完全一致。

代码要点:

代码 作用
mpu6050_basic_init(MPU6050_ADDRESS_AD0_LOW) 按 AD0 接低的地址(0xD0 >> 1 = 0x68)初始化芯片并配置量程(加速度 ±2g、陀螺仪 ±2000°/s),地址与接线不符就找不到芯片
mpu6050_basic_read(accel, gyro) 读三轴加速度(单位 g)与三轴陀螺仪(单位 度/秒)各 3 个 float,读失败返回 1
blog_info("accel: %.2f %.2f %.2f\tgyro: ...", ...) 串口打印 6 个数值,不打印就看不到测量结果
vTaskDelay(pdMS_TO_TICKS(1000)) 每 1 秒采样一次;太快占用 I2C 总线且数据变化不大,没必要
编译工程

在工程目录执行编译:

make -j8

说明:make 是「编译工程」命令,把代码变成开发板能运行的固件(程序文件);-j8 表示用 8 个核并行编译,速度更快。

编译成功后生成固件 build_out/demo_mpu6050.bin

⚠️ 若提示 riscv64-unknown-elf-gcc: command not found,说明工具链权限未配置,先执行 cd toolchain/riscv/Linux && . chmod755.sh 再重新编译。

烧录固件

开发板保持 USB 连接,确认串口设备号(Linux 下通常为 /dev/ttyUSB0),执行烧录:

make flash p=/dev/ttyUSB0 b=921600

说明:make flash 是「烧录」命令,把编译好的固件写进开发板芯片。p= 后面是串口设备号(要改成你电脑上实际的串口,可用 ls /dev/ttyUSB* 查看),b= 是烧录波特率(传输速度)。

⏳ 烧录过程中按提示长按开发板 EN 键进入下载模式(部分开发板自动进入),等待进度条完成即烧录成功。 Windows 平台烧录方法见 Windows 平台快速开始

运行验证

烧录完成后开发板自动重启运行,打开串口助手(波特率 921600,波特率 = 串口传输速度,收发两端必须设成一样),每 1 秒打印一次六轴数据:

accel: -0.01 0.02 1.00	gyro: 0.01 -0.02 0.03
accel: -0.01 0.02 1.00	gyro: 0.02 -0.01 0.04
...

观察要点:

  • 模块平放不动时,加速度 Z 轴(第三个值)应约等于 1.00(重力 1g),X/Y 轴约等于 0;陀螺仪三个值都接近 0(不动就不转)。
  • 翻转/转动模块时,加速度各轴数值随姿态变化,陀螺仪数值随转动速度变化。

看到串口每秒打印 accel/gyro 两组数、且数值随模块姿态变化即为成功;如果一直打印全 0 或没有打印,说明还没成功,对照文末「常见问题与踩坑提示」排查。

💡 用逻辑分析仪观察 IO4/IO5 波形,可看到 I2C 的寄存器读写时序(见官方示例 img/logic_analyzer.jpg)。

代码执行流程

例程从启动到运行的完整流程如下(图中的循环箭头表示反复执行):


本文 API 汇总

mpu6050_basic_init(addr_pin)

按指定 I2C 地址初始化 MPU6050:配置时钟源、采样率、低通滤波、加速度量程(默认 ±2g)与陀螺仪量程(默认 ±2000°/s)。

参数

  • addr_pin:I2C 设备地址枚举,可选值:MPU6050_ADDRESS_AD0_LOW(AD0 接低,地址 0x68,本教程默认)/ MPU6050_ADDRESS_AD0_HIGH(AD0 接高,地址 0x69)。与硬件接线不符则初始化失败

返回值:成功返回 0;失败返回 1(如芯片无应答)。驱动实现见 demo_mpu6050/driver_mpu6050_basic.c

mpu6050_basic_read(g, dps)

从芯片数据寄存器读回六轴原始值并换算为物理量:加速度单位 g(重力加速度),陀螺仪单位 度/秒。

参数

  • gfloat g[3] 输出数组,依次收到 X/Y/Z 三轴加速度(单位 g),必填
  • dpsfloat dps[3] 输出数组,依次收到 X/Y/Z 三轴角速度(单位 度/秒),必填

返回值:成功返回 0;失败返回 1(读失败)。驱动实现见 demo_mpu6050/driver_mpu6050_basic.c

blog_info(fmt, ...)

输出一条 INFO 级日志(UART0,受级别过滤),本教程打印六轴数据。

参数

  • fmt:格式化字符串,同 printf 用法,必填
  • ...:变参,与 fmt 占位符对应,可省略

返回值:无

vTaskDelay(ms)

让当前任务挂起指定毫秒数,期间让出 CPU 给其他任务。

参数

  • ms:延时毫秒数,可选值:任意非负整数(内部经 pdMS_TO_TICKS 换算为系统节拍)

返回值:无


完整代码

以下为 demo_mpu6050/main.c 完整源码,与官方示例(applications/iot-solution/demo_mpu6050/demo_mpu6050/main.c)完全一致。本工程为多文件工程,其余驱动文件(driver_mpu6050*.c/hdriver_mpu6050_interface_bl602.c)位于同一目录,无需修改:

📜 点击展开 demo_mpu6050/main.c 完整代码
c
#include <stdio.h>

#include <FreeRTOS.h>
#include <task.h>
#include <blog.h>
#include "driver_mpu6050.h"
#include "driver_mpu6050_basic.h"

int main(void)
{
    mpu6050_basic_init(MPU6050_ADDRESS_AD0_LOW);
    
    for (;;) {
        float accel[3];
        float gyro[3];
        mpu6050_basic_read(accel, gyro);
        blog_info("accel: %.2f %.2f %.2f\tgyro: %.2f %.2f %.2f\r\n", accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
        vTaskDelay(pdMS_TO_TICKS(1000));
    }

    return 0;
}

常见问题与踩坑提示

⚠️ 一直打印全 0(读不到数据)
原因:I2C 接线错误、AD0 引脚状态与代码不一致(接高时地址为 0x69)、或芯片损坏
解决:对照接线表核对 IO4/IO5/3V3/GND;确认模块 AD0 接地或悬空;若 AD0 接 3V3,把 mpu6050_basic_init 参数改为 MPU6050_ADDRESS_AD0_HIGH 后重新编译烧录

⚠️ 串口不打印任何内容
原因:接线错误、VCC 供电不足、开发板与模块未共地(GND 没接),或杜邦线接触不良
解决:确认 VCC 接 3V3、GND 接 GND(共地 = 两个设备的地线必须接在一起,否则电压没有参考点);重新插紧杜邦线

⚠️ 数值乱跳或静止时不为 1g
原因:模块放在抖动/震动环境中、供电不稳,或模块未固定
解决:把模块平放在桌面上静止观察;确认供电稳定;加速度有微小波动(±0.05)属正常,波动过大检查供电

⚠️ 找不到串口设备或提示无权限
原因:Linux 下 /dev/ttyUSB0 不存在或权限不足,Windows 下未安装 USB 转串口驱动
解决:Linux 用 ls /dev/ttyUSB* 确认设备号,权限不足执行 sudo usermod -aG dialout $USER 后重新登录;Windows 在设备管理器安装驱动并确认 COM 口号

⚠️ 烧录一直卡住等待,进度条不动
原因:未进入下载模式,或数据线只能充电不能传数据
解决:烧录时按提示长按 EN 键进入下载模式;换一根能传数据的 Type-C 数据线后重试

⚠️ 执行 make 报找不到 Makefile
原因:在错误的目录执行了编译命令(必须在示例工程目录内)
解决:先执行 cd ~/Ai-Thinker-WB2/applications/iot-solution/demo_mpu6050 进入工程目录,再执行 make -j8

运行自检

串口每秒打印 accel/gyro 两组数据,平放时加速度 Z 轴约 1.00g,转动模块数值随之变化,即 MPU6050 六轴测量验证通过。

遇到问题?

如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

Released under the MIT License. Build Time 2026-09-11 14:52:23