声明
文中内容为观看 BiliBili 视频【STM32入门教程-2023版 细致讲解 中文字幕】后学习并扩展总结。
本文章为个人学习使用,版面观感若有不适请谅解,文中知识仅代表个人观点,若出现错误,欢迎各位批评指正。
一、I2C 通信协议
1.1 简介
I2C(Inter IC Bus,集成电路间总线) 是由荷兰 Philips 公司(现 NXP 半导体公司)于 20 世纪 80 年代初开发的通用串行数据总线,旨在解决集成电路间短距离、低速率数据传输问题,简化板内器件连接,降低系统成本与功耗,目前已纳入国际标准(IEC 62386),广泛应用于嵌入式系统、消费电子等领域。其核心特性由下表所示:
| 核心特性 | 具体说明 |
|---|---|
| 通信线组成 | 仅2根双向线:SCL(串行时钟线,主设备控制,同步通信节奏)、SDA(串行数据线,传输数据与控制信号) |
| 通信时序 | 同步通信(遵循SCL时钟信号),半双工传输(同一时刻仅单向通信,支持读写切换) |
| 数据保障机制 | 带数据应答(ACK/NACK):每传1字节,接收方在SCL第9时钟周期反馈,确保传输可靠 |
| 设备挂载能力 | 支持多设备挂载,可实现一主多从(单主设备控时序)、多主多从(总线仲裁防冲突)拓扑 |
SCL 的时钟频率 决定 I2C 通信速率 ,常见标准模式(100kbps)、快速模式(400kbps)等,总线空闲时,SCL 与 SDA 均由上拉电阻维持高电平。半双工设计虽限制了通信效率,但简化了控制逻辑,降低了硬件设计难度。
数据应答机制 是通信可靠性的关键:接收方成功接收数据则反馈低电平 ACK,主设备继续传输;接收异常则反馈高电平 NACK,主设备停止或重发,有效避免误码、丢包。
多设备挂载 特性大幅简化了系统布线,从设备通过唯一 7 位 / 10 位地址被主设备选中,未选中设备处于空闲状态;多主多从结构中,总线仲裁机制可解决设备竞争总线的冲突问题。
此外,I2C 还具备时钟拉伸(从设备调节时钟周期)、地址广播(同步控制所有从设备)等辅助特性,共同奠定其灵活性高、兼容性好的优势,适配各类短距离低速率嵌入式通信场景。
1.2 硬件电路
- 总线拓扑结构
I2C 总线采用多设备共享的双线串行通信架构,所有挂载于总线上的设备(包括主控 CPU 与各被控 IC)均将其串行时钟引脚(SCL)与串行数据引脚(SDA)分别并联至同一物理线路,形成共享的时钟总线与数据总线。这种拓扑结构允许多个设备在同一组物理线路上进行半双工通信,通过设备地址区分通信对象,实现系统级的器件互联与数据交互。 - 电气接口与输出模式
为支持多设备共享总线并避免信号冲突,所有 I2C 设备的 SCL 与 SDA 引脚必须配置为开漏输出(open-drain output)模式 。开漏输出的核心特性在于其输出级仅能通过下拉 MOS 管将总线拉至低电平 ,而无法主动输出高电平 ,这一设计是实现总线 "线与" 逻辑与多主设备仲裁的基础。
从器件内部电路可见,SCL 与 SDA 通道均由反相驱动的下拉 NMOS 管构成输出级:当输出使能信号(如 SCLKN1_OUT、DATAN1_OUT)为高电平时,NMOS 管导通,将对应总线拉至地(低电平);当使能信号为低电平时,NMOS 管截止,总线电平由外部上拉电阻决定,从而实现高阻态与高电平的切换。同时,各引脚内置输入缓冲器(SCLK IN、DATA IN),用于实时采样总线电平,保障设备对总线状态的可靠感知。 - 上拉电阻配置与电气特性
为确保总线在空闲状态下维持稳定的高电平,并为信号上升沿提供驱动能力,SCL 与 SDA 总线需分别外接上拉电阻至系统正电源( V D D V_{DD} VDD)。工程实践中,上拉电阻阻值通常选取 4.7 kΩ 左右,该取值需在信号完整性与功耗之间取得平衡:
(1)阻值过小会导致总线下拉时的灌电流增大,增加器件功耗与热应力;
(2)阻值过大则会延长信号上升沿时间,限制总线最高通信速率(通常 I²C 标准模式速率为 100 kbps,快速模式为 400 kbps)。
上拉电阻与总线电容共同构成 RC 充放电回路,决定了信号的上升沿斜率与噪声裕量,是保障 I2C 通信可靠性的关键硬件设计环节。 - 工作原理与通信机制
在通信过程中,主控设备(如 CPU)通过控制 SCL 与 SDA 引脚的开漏输出,交替 拉低 / 释放总线,生成符合 I2C 协议的起始条件、地址帧、数据帧与停止条件。由于开漏输出的 "线与" 特性 ,多个设备可同时拉低总线,从而实现冲突检测与多主设备仲裁;当总线被释放时,上拉电阻将其电平拉回 V D D V_{DD} VDD,为下一次通信做好准备。
这种硬件架构与电气设计共同构成了 I2C 总线的核心基础,使其成为嵌入式系统中广泛应用的低速、短距离串行通信标准。

1.3 I2C 时序基本单元
I2C 总线通信的完整时序逻辑由一系列基础操作单元构成,其核心基本时序单元主要包含六类:起始条件、终止条件、字节发送、字节接收、发送应答位及接收应答位。上述基本单元按规范组合,即可完成 I2C 总线上可靠的数据交互与设备间的同步通信。
- (1)起始条件
SCL 高电平期间,SDA 从高电平 切换到低电平。

- (2)终止条件
SCL 高电平期间,SDA 从低电平 切换到高电平。

- (3)字节发送
SCL 低电平期间,主机 将数据位依次放到 SDA 线上(高位先行),然后释放 SCL,从机将在 SCL 高电平期间读取数据位,所以 SCL 高电平期间 SDA 不允许有数据变化,依次循环上述过程 8 次,即可发送一个字节。

- (4)字节接收
SCL 低电平期间,从机 将数据位依次放到 SDA 线上(高位先行),然后释放 SCL,主机将在 SCL 高电平期间读取数据位,所以 SCL 高电平期间 SDA 不允许有数据变化,依次循环上述过程 8 次,即可接收一个字节(主机在接收之前,需要释放 SDA)。

- (5)发送应答位
主机在接收完一个字节之后,在下一个时钟发送一位数据,数据 0 表示应答,数据 1 表示非应答。

- (6)接收应答位
主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放 SDA)。

1.4 I2C 时序样例
- 指定地址写
对于指定设备(Slave Address),在指定地址(Reg Address)下,写入指定数据(Data)。

- 当前地址读
对于指定设备(Slave Address),在当前地址指针指示的地址下,读取从机数据(Data)。

- 指定地址读
对于指定设备(Slave Address),在指定地址(Reg Address)下,读取从机数据(Data)。

二、姿态传感器
2.1 MPU6050 简介
MPU6050 是由 TDK InvenSense 公司研发的一款集成式六轴微机电系统(MEMS)运动跟踪传感器 ,属于惯性测量单元(IMU)的典型代表,其核心功能是同步采集芯片自身 X、Y、Z 三个正交轴的线加速度与角速度参数 ,并通过内置数据处理单元实现多源传感数据的融合,进而解算出目标物体的姿态角 (俯仰角、横滚角),为姿态检测与运动控制提供精准的传感支撑,广泛应用于各类需要实时感知自身姿态的智能设备与控制系统中,如平衡车、小型飞行器、机器人及可穿戴设备等。
MPU6050 的核心优势在于将 3 轴加速度计(Accelerometer) 与 3 轴陀螺仪传感器(Gyroscope) 集成于同一硅基芯片之上,共享公共 MEMS 衬底,有效消除了板级层面的轴间对准误差,降低了传感器漂移与稳定时间效应,同时通过紧凑的4×4×0.9mm QFN 封装,兼顾了小型化、低功耗与低成本需求,适配空间受限、功耗敏感的嵌入式应用场景,其工作电压范围为2.375V 至 3.46V,睡眠模式电流低至5μA,具备优良的工程实用性。
3 轴加速度计(Accelerometer)是 MPU6050 的核心传感单元之一,基于电容式 MEMS 结构设计,其内部采用梳齿状可动质量块与固定电极构成差分电容对,当芯片沿某一轴向产生线加速度时,惯性作用会使可动质量块发生微小位移,导致差分电容容值产生反向变化,该变化经片内电荷放大器、滤波器及16位模数转换器(ADC)调理后,输出数字化的加速度数据。该加速度计支持 ±2g、±4g、±8g、±16g 四种可编程满量程范围,在 ±2g 量程下灵敏度可达 16384 LSB/g,分辨率约为 0.061 mg/LSB,可精准测量芯片在三个正交轴上的线加速度,静止状态下可感知重力加速度在各轴的投影,为姿态角解算提供静态基准。
3 轴陀螺仪传感器(Gyroscope) 是 MPU6050 的另一核心传感单元,同样基于 MEMS 工艺,利用科里奥利效应实现角速度的间接测量,其内部采用音叉式振动环结构,通过静电驱动使质量块在特定谐振频率下持续振动,当芯片绕任一轴发生旋转时,振动质量块会受到与旋转角速度成正比的科里奥利力,引发垂直于振动方向的二次振动,该振动通过差分电容结构检测并经片内电路处理后,输出数字化的角速度数据。该陀螺仪支持 ±250°/s、±500°/s、±1000°/s、±2000°/s 四种可编程满量程范围,可精准追踪快速与慢速旋转运动,在 ±250°/s 量程下灵敏度可达 131 LSB/(°/s),其输出不受重力影响,具备高带宽与低延迟的动态响应特性,为姿态角解算提供动态旋转信息。
MPU6050 内置数字运动处理器(DMP) ,可离线运行复杂的六轴数据融合算法,将加速度计与陀螺仪的原始数据进行融合处理,有效弥补单一传感器的固有缺陷------加速度计长期稳定性优良但动态响应较差,陀螺仪动态响应灵敏但存在零点漂移,通过互补滤波、卡尔曼滤波等融合算法,可输出高精度的姿态角数据,无需外部微控制器承担大量数据处理任务,显著降低了系统集成复杂度与计算开销。此外,该传感器通过 I2C 总线实现数据传输与配置,支持最高 400kHz 的通信速率,可通过辅助 I2C 总线连接外部磁力计等传感器,扩展为九轴运动跟踪系统,进一步提升姿态检测的完整性与精度,可解算完整的三维欧拉角(俯仰角、横滚角、偏航角)。
在实际应用场景中,MPU6050 凭借其高集成度、高性价比与可靠的性能,已广泛应用于多个领域:在机器人与平衡车领域,用于实时检测设备姿态,为闭环控制提供反馈,保障设备的平衡与稳定运行;在小型飞行器(如无人机)领域,用于采集飞行姿态数据,辅助实现姿态控制与飞行稳定;在可穿戴设备与康复监测领域,用于捕捉人体运动姿态,为运动分析与康复评估提供数据支撑;在工业领域,可用于设备振动监测与姿态校准;同时也广泛应用于航空电子教育、运动感测游戏、电子稳像等场景,成为低功耗、低成本姿态检测场景中的首选传感器之一。需要说明的是,MPU6050 目前已处于停产(EOL)状态,其推荐替代型号为 ICM-42670-P,但由于其成熟的技术、低廉的成本与广泛的应用生态,仍在各类科研、教学及民用项目中被广泛采用。

2.2 MPU6050 参数
MPU6050 配备 16 位模数转换器(ADC)用于采集传感器模拟信号,量化范围 为 -32768~32767,可实现高精度信号转换;加速度计支持 ±2g、±4g、±8g、±16g 四种满量程可配置选择,陀螺仪支持 ±250°/sec、±500°/sec、±1000°/sec、±2000°/sec 四种满量程可配置选择,适配不同精度与动态范围的应用需求;此外,该传感器集成可配置数字低通滤波器 、可配置时钟源 及可配置采样分频模块 ,可根据实际应用场景灵活调整信号滤波效果、时钟基准与采样频率;其 I2C 从机地址可通过 AD0 引脚配置,当 AD0=0 时地址为 1101000,当 AD0=1 时地址为 1101001,便于多传感器级联使用。
2.2 MPU6050 硬件电路
本电路采用 5V 输入电源,经 3.3V 低压差线性稳压器(LDO)稳压后为 MPU6050 及周边电路供电,输入侧配置 4.7μF 滤波电容,输出侧并联 10μF 与 0.1μF 电容以抑制电源纹波,并通过 1kΩ 限流电阻驱动 LED 实现电源状态指示。
MPU6050 的 VDD、VLOGIC 引脚直接接入 3.3V 电源,GND 引脚接地,REGOUT 与 CPOUT 引脚分别通过 0.1μF、2200pF 电容接地以完成内部稳压与电荷泵滤波。核心通信接口方面,SDA/SCL 引脚经 4.7kΩ 上拉电阻至 3.3V 后引出,构成 I2C 主通信总线;XDA/XCL 引脚作为辅助 I2C 接口同步引出,支持外设扩展。AD0 引脚通过 4.7kΩ 下拉电阻置 0,固定 I2C 从机地址最低位;INT 引脚经滤波后引出,用于向主控设备输出中断信号。电路通过去耦电容(0.1μF)与上拉电阻的配置,保障了电源稳定性与通信可靠性,可满足姿态检测等场景的高精度传感需求。
| 引脚 | 功能 |
|---|---|
| VCC、GND | 电源 |
| SCL、SDA | I2C 通信引脚 |
| XCL、XDA | 主机 I2C 通信引脚 |
| AD0 | 从机地址最低位 |
| INT | 中断信号输出 |

三、软件 I2C 读写 MPU6050
3.1 软件 I2C 读写 MPU6050的实现
-
首先,按下图接线方式,搭建面包板电路连接 OLED 显示屏,并将 MPU6050 的 SCL 和 SDA 分别与 PA4 和 PA5 连接,然后将 DAP-Link / ST-Link 连接到 STM32 最小系统板上,为使 OLED 显示屏的 VCC 和 GND 正确连接正负极,请先连接对应正负极跳线(或直接使用 GPIO 口进行供电)。

-
直接复制先前演示的已有文件目录,重命名并双击后缀名为 .uvprojx 的文件打开工程文件,并对 main.c 进行修改,工程中所使用的全部头文件其详细内容已放于文末。
#include "stm32f10x.h" // Device header
#include "Soft_I2C.h"
#include "OLED.h"
#include "MPU6050.h"int16_t AX, AY, AZ, GX, GY, GZ;
int main(void)
{
OLED_Init();
MPU_6050_Init();// 点名, 判断设备是否存在(有应答显示 000, 无应答显示 001)// Soft_I2C_Init();
//
// Soft_I2C_Start();
// Soft_I2C_SendByte(0xD0); // 0xD0: 1101 000 0, 0xD2: 1101 001 0
// uint8_t Ack = Soft_I2C_ReceiveAck();
// Soft_I2C_Stop();
//
// OLED_ShowNum(1, 1, Ack, 3);// MPU6050 读写操作// MPU_6050_Init();
// // 读取芯片的 ID 号, 要读的地址查看手册:WHO_AM_I 0x75
// uint8_t ID = MPU6050_ReadReg(0x75);
// OLED_ShowHexNum(1, 1, ID, 2);
//
// // 写寄存器之前, 解除睡眠模式: 0x6B
// MPU6050_WriteReg(0x6B, 0x00);
// // 采样率分频寄存器: 0x19
// MPU6050_WriteReg(0x19, 0x66);
//
// // 对写入分频寄存器的内容进行读操作, 验证是否写入成功
// uint8_t Demo = MPU6050_ReadReg(0x19);
// OLED_ShowHexNum(2, 1, Demo, 2);while (1) { MPU6050_GetData(&AX, &AY, &AZ, &GX, &GY, &GZ); OLED_ShowSignedNum(2, 1, AX, 5); OLED_ShowSignedNum(3, 1, AY, 5); OLED_ShowSignedNum(4, 1, AZ, 5); OLED_ShowSignedNum(2, 8, GX, 5); OLED_ShowSignedNum(3, 8, GY, 5); OLED_ShowSignedNum(4, 8, GZ, 5); }}
-
MPU6050 的 AD0 引脚为从机地址配置引脚,当该引脚接高电平时,设备从机地址由默认的 0xD0 切换为 0xD2:对 0xD2 地址寻址时,设备正常应答(显示 000);若仍对原地址 0xD0 寻址,设备无应答(显示 001)。

-
程序调用
MPU6050_GetData()函数读取六轴数据(三轴加速度 AX/AY/AZ、三轴角速度 GX/GY/GZ),并通过OLED_ShowSignedNum()函数将加速度数据依次显示在 OLED 屏第 2-4 行第 1 列位置,角速度数据显示在第 2-4 行第 8 列位置,所有数值均以 5 位有符号数格式呈现。
当设备保持静止且 Z 轴垂直向上时,加速度计 Z 轴(AZ)输出值约为 32768(MPU6050 加速度计满量程 ±16g 时,数值范围为 - 32768~32768),可通过公式验证重力加速度:已知换算关系:2065/32768 = 0.059296,且0.0630188 = x/16(x 为实际重力加速度,单位 g),解得x =0.0630188 × 16 = 1.0083008 ≈ 1,即该数值对应标准 1g 重力加速度,验证了加速度计 Z 轴输出与实际重力的匹配性。

四、演示代码关联的头文件与源文件说明
-
OLED 相关头文件请从 STM32 学习 ------ 个人学习笔记4(OLED 显示屏及调试工具) 文末查看,此处不重复展示。
-
Delay 相关头文件请从 STM32 学习 ------ 个人学习笔记3-1(GPIO 输出) 文末查看,此处不重复展示。
-
Soft_I2C.c
#include "stm32f10x.h" // Device header
#include "Delay.h"void Soft_I2C_W_SCL(uint8_t BitValue){
GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
Delay_us(10);
}void Soft_I2C_W_SDA(uint8_t BitValue){
GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)BitValue);
Delay_us(10);
}uint8_t Soft_I2C_R_SDA(void){
uint8_t BitValue;
BitValue = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5);
Delay_us(10);
return BitValue;
}void Soft_I2C_Init(void){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA, GPIO_Pin_4 | GPIO_Pin_5);}
void Soft_I2C_Start(void){
Soft_I2C_W_SDA(1);
Soft_I2C_W_SCL(1);
Soft_I2C_W_SDA(0);
Soft_I2C_W_SCL(0);
}void Soft_I2C_Stop(void){
Soft_I2C_W_SDA(0);
Soft_I2C_W_SCL(1);
Soft_I2C_W_SDA(1);
}void Soft_I2C_SendByte(uint8_t Byte){
uint8_t i;
for (i=0; i < 8; i++){
Soft_I2C_W_SDA(Byte & (0x80 >> i));
Soft_I2C_W_SCL(1);
Soft_I2C_W_SCL(0);
}
}uint8_t Soft_I2C_ReceiveByte(void){
uint8_t i, Byte = 0x00;
Soft_I2C_W_SDA(1);
for (i = 0; i < 8; i++){
Soft_I2C_W_SCL(1);
if (Soft_I2C_R_SDA() == 1){Byte |= (0x80 >> i);}
Soft_I2C_W_SCL(0);
}
return Byte;
}void Soft_I2C_SendAck(uint8_t AckBit){
Soft_I2C_W_SDA(AckBit);
Soft_I2C_W_SCL(1);
Soft_I2C_W_SCL(0);
}uint8_t Soft_I2C_ReceiveAck(void){
uint8_t AckBit;
Soft_I2C_W_SDA(1);
Soft_I2C_W_SCL(1);
AckBit = Soft_I2C_R_SDA();
Soft_I2C_W_SCL(0);return AckBit;}
-
Soft_I2C.h
#ifndef __SOFT_I2C_H
#define __SOFT_I2C_Hvoid Soft_I2C_Init(void);
void Soft_I2C_Start(void);
void Soft_I2C_Stop(void);
void Soft_I2C_SendByte(uint8_t Byte);
uint8_t Soft_I2C_ReceiveByte(void);
void Soft_I2C_SendAck(uint8_t AckBit);
uint8_t Soft_I2C_ReceiveAck(void);#endif
-
MPU6050.c
#include "stm32f10x.h" // Device header
#include "Soft_I2C.h"
#include "MPU6050_Reg.h"#define MPU6050_ADDRESS 0xD0
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data){
Soft_I2C_Start();
Soft_I2C_SendByte(MPU6050_ADDRESS);
Soft_I2C_ReceiveAck(); // 通过这个应答位可以判断从机是否收到数据,此处不做演示
Soft_I2C_SendByte(RegAddress);
Soft_I2C_ReceiveAck();
Soft_I2C_SendByte(Data);
Soft_I2C_ReceiveAck();
Soft_I2C_Stop();
}uint8_t MPU6050_ReadReg(uint8_t RegAddress){
uint8_t Data;Soft_I2C_Start(); Soft_I2C_SendByte(MPU6050_ADDRESS); Soft_I2C_ReceiveAck(); Soft_I2C_SendByte(RegAddress); Soft_I2C_ReceiveAck(); Soft_I2C_Start(); Soft_I2C_SendByte(MPU6050_ADDRESS | 0x01); Soft_I2C_ReceiveAck(); Data = Soft_I2C_ReceiveByte(); Soft_I2C_SendAck(1); Soft_I2C_Stop(); return Data;}
void MPU_6050_Init(void){
Soft_I2C_Init();// 配置电源管理寄存器1: 解除睡眠并选择陀螺仪时钟 MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x01); // 配置电源管理寄存器2: 6 个轴均不待机 MPU6050_WriteReg(MPU6050_PWR_MGMT_2, 0x00); // 配置采样率分频寄存器: 采样分频为 10 MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x09); // 配置 配置寄存器: 滤波参数给最大 MPU6050_WriteReg(MPU6050_CONFIG, 0x06); // 配置陀螺仪配置寄存器: 陀螺仪选择最大量程 MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18); // 配置加速度配置寄存器: 加速度计选择最大量程 MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18);}
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ,
int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ){
uint8_t DataH, DataL;DataH = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H); DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L); *AccX = (DataH << 8) | DataL; DataH = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H); DataL = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L); *AccY = (DataH << 8) | DataL; DataH = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H); DataL = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L); *AccZ = (DataH << 8) | DataL; DataH = MPU6050_ReadReg(MPU6050_GYRO_XOUT_H); DataL = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L); *GyroX = (DataH << 8) | DataL; DataH = MPU6050_ReadReg(MPU6050_GYRO_YOUT_H); DataL = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L); *GyroY = (DataH << 8) | DataL; DataH = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H); DataL = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L); *GyroZ = (DataH << 8) | DataL;}
-
MPU6050.h
#ifndef __MPU6050_H
#define __MPU6050_Hvoid MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data);
void MPU_6050_Init(void);
uint8_t MPU6050_ReadReg(uint8_t RegAddress);
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ,
int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ);#endif
-
MPU6050_Reg.h
#ifndef __MPU6050_REG_H
#define __MPU6050_REG_H#define MPU6050_SMPLRT_DIV 0x19
#define MPU6050_CONFIG 0x1A
#define MPU6050_GYRO_CONFIG 0x1B
#define MPU6050_ACCEL_CONFIG 0x1C#define MPU6050_ACCEL_XOUT_H 0x3B
#define MPU6050_ACCEL_XOUT_L 0x3C
#define MPU6050_ACCEL_YOUT_H 0x3D
#define MPU6050_ACCEL_YOUT_L 0x3E
#define MPU6050_ACCEL_ZOUT_H 0x3F
#define MPU6050_ACCEL_ZOUT_L 0x40
#define MPU6050_TEMP_OUT_H 0x41
#define MPU6050_TEMP_OUT_L 0x42
#define MPU6050_GYRO_XOUT_H 0x43
#define MPU6050_GYRO_XOUT_L 0x44
#define MPU6050_GYRO_YOUT_H 0x45
#define MPU6050_GYRO_YOUT_L 0x46
#define MPU6050_GYRO_ZOUT_H 0x47
#define MPU6050_GYRO_ZOUT_L 0x48#define MPU6050_PWR_MGMT_1 0x6B
#define MPU6050_PWR_MGMT_2 0x6C
#define MPU6050_WHO_AM_I 0x75#endif
文中部分知识参考:B 站 ------ 江协科技;百度百科