STM32驱动MPU6050基于IIC协议

2023-11-10

一. 简介

MPU6050是一款六轴陀螺仪,可以通过IIC协议输出三个方向上的加速度和角速度,在平衡车和飞控中较为常见。一般情况下,模块有用的引脚只有四个(其它的不常用),即VCC,GND,SDA和SCL。操作它的第一步,即编写IIC协议。


二. IIC协议

作为三大常用协议之一,掌握它是非常有必要的。IIC为主从协议,分为主机和从机。IIC协议要比SPI要简单那么一点,没有像SPI那样还有模式的配置。下面就简单说说IIC协议。
SDA: IIC的数据线
SCL:IIC的时钟线

  1. 空闲态: SDA和SCL都为高电平。
  2. 起始态: 主机将SDA拉低
  3. 数据传输: 在SCL为低电平的时候,将数据输出,在SCL为高电平的时候,将数据输入。
  4. 应答态:在SCL为高电平的时候,检测到SDA为低电平。
  5. 非应答态:在SCL为高电平的时候,检测到SDA为高电平。
  6. 停止态:在SCL为高电平的时候,将SDA由低拉高。

IIC协议一共可以分为这六种状态,接下来将简要说明如何将这六种状态组成一个完整的IIC协议,来驱动MPU6050。

(1). IIC写

数据输出是以一个byte为单位的,从机地址一般为七位,与读写标志一起组成一个byte。0为写,1为读。
开始 -》 从机地址 + 0 -》 应答 -》发送寄存器地址 -》 应答 -》 写入数据 -》 非应答(应答) -》 停止
在这里插入图片描述

(2). IIC读

IIC读数据要比IIC写数据要复杂一点,主要是步骤上多了几步,但是状态什么的都完全一样。

开始 -》 从机地址 + 0 -》 应答 -》发送读取寄存器地址 -》 应答 -》开始 -》 从机地址 + 1 -》 读取数据 -》应答 -》 停止

可以看到,只要将这几个状态实现了,按照这个流程就可以很容易实现IIC的读和写。大概的时序图如下。
在这里插入图片描述


三. 代码实现

根据上面的六个状态,定义出对应的六个函数,对应的只有五个,空闲态忽略,因为经过Stop后,IIC的时钟线和数据线都已经为高了。delay时间需要根据从机所能接受的最大速率来决定,不然的话,会出错,下面就来详细说明这几个函数。
在这里插入图片描述

(1) MPU6050IICDelay(void)

这就不用说明什么了

void MPU6050IICDelay(void)
{
    uint16_t i = 250;
    while(i--);
}
(2) MPU6050IICStart(void)

将SDA配置为输出模式。然后将SCL和SDA全部拉高,dealy后,将SDA拉低,就ok了。

void MPU6050IICStart(void)
{
    SetSDAOut();
    SCLHigh();
    SDAHigh();
    MPU6050IICDelay();
    SDALow();
    MPU6050IICDelay();
}
(3) MPU6050IICACK(void)

这里只包含了从机应答。

void MPU6050IICACK(void)
{   
    SCLLow();
    MPU6050IICDelay();
    SetSDAIn();
    MPU6050IICDelay();
    SCLHigh();
    MPU6050IICDelay();
    SDARead();
    MPU6050IICDelay();
    SCLLow();
}
(4) MPU6050IICStop(void)

停止位这里,需要先将SCL和SDA都拉低,然后先将SCL拉高,后将SDA拉高,

void MPU6050IICStop(void)
{
    SetSDAOut();
    MPU6050IICDelay();
    SCLLow();
    MPU6050IICDelay();
    SDALow();
    MPU6050IICDelay();
    SCLHigh();
    MPU6050IICDelay();
    SDAHigh();
    MPU6050IICDelay();
}
(5) MPU6050IICWrite(void)
void MPU6050IICWrite(uint8_t data)
{
    uint8_t i;
    SetSDAOut();
    MPU6050IICDelay();
    for(i = 0 ; i < 8; i++)
    {
        SCLLow();
        MPU6050IICDelay();
        if(data & 0x80)
            SDAHigh();
        else
            SDALow();
        data = data << 1;
        MPU6050IICDelay();
        SCLHigh();
        MPU6050IICDelay();
    }
}
(6) MPU6050IICRead(void)
uint8_t MPU6050IICRead(void)
{
    uint8_t i;
    uint8_t data = 0;
    SetSDAIn();
    MPU6050IICDelay();
    for(i = 0;i < 8; i++)
    {
        SCLLow();
        MPU6050IICDelay();
        SCLHigh();
        MPU6050IICDelay();
        if(SDARead())
            data = data | 0x01;
        else
            data = data | 0x00;
        data = data << 1;
        MPU6050IICDelay();
    }
    return data;
}

读写数据,可以搭配时序图来,都是将SCL为低的时候,将数据送出去。在SCL为高的时候,接收数据。
然后将上面的这几个函数依次组合成读写两个函数
在这里插入图片描述
这里IIC驱动编写完成。

四. MPU6050 初始化

初始化的实质就是对寄存器进行配置,这就要查看芯片手册,了解每一个寄存器的作用了,以及初始化的时候寄存器配置的顺序。
这里将重要的寄存器列举出来了

#define MPU6050Addr     0xD0
#define ACCEL_XOUT_H    0x3B
#define ACCEL_XOUT_L    0x3C
#define ACCEL_YOUT_H    0x3D
#define ACCEL_YOUT_L    0x3E
#define ACCEL_ZOUT_H    0x3F
#define ACCEL_ZOUT_L    0x40

#define GYRO_XOUT_H     0x43
#define GYRO_XOUT_L     0x44
#define GYRO_YOUT_H     0x45
#define GYRO_YOUT_L     0x46
#define GYRO_ZOUT_H     0x47
#define GYRO_ZOUT_L     0x48

#define PWR_MGMT_1      0x6B
#define PWR_MGMT_2      0x6C
#define SMPLRT_DIV      0x19
#define MPU_CONFIG      0x1A
#define GYRO_CONFIG     0x1B
#define ACCEL_CONFIG    0x1C

#define MPU6050ID       0x75
(1). 初始化
/*MPU6050初始化*/
void MPU6050Init(void)
{
    MPU6050GPIOInit();
    MPU6050IICWriteRegister(MPU6050Addr,PWR_MGMT_1,0x80);
    rt_thread_mdelay(100);
    MPU6050IICWriteRegister(MPU6050Addr,PWR_MGMT_1,0x00);
    MPU6050IICWriteRegister(MPU6050Addr,SMPLRT_DIV,0x00);
    MPU6050IICWriteRegister(MPU6050Addr,MPU_CONFIG,0x03);
    MPU6050IICWriteRegister(MPU6050Addr,GYRO_CONFIG,0x18);// gyro scale  :+-2000°/s
    MPU6050IICWriteRegister(MPU6050Addr,ACCEL_CONFIG,0x10);// Accel scale :+-8g (65536/16=4096 LSB/g)  
    MPU6050IICWriteRegister(MPU6050Addr,0x6B,0x01);
}   
(2)验证

通过读取芯片的ID,可以确定IIC是否有问题。

/*读取MPU6050的ID*/
uint8_t MPU6050GetId(void)
{
    return MPU6050IICReadRegister(MPU6050Addr,MPU6050ID);
}

分享一个成果图
欢迎关注 微信公众号 FPGA之旅 获取相关资料
想要完整代码的,也可以在上面联系我,商务合作也咳哟
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32驱动MPU6050基于IIC协议 的相关文章

  • 为 ARM 交叉编译 zlib

    我尝试为arm poky linux gnueabi交叉编译zlib 但启动 make 时出现错误 zlib 1 2 11 AR HOST ar CC HOST gcc RANLIB HOST ranlib configure prefix
  • 有没有办法在 Xcode 4 中为 ARM 而不是 Thumb 进行编译?

    如果有很多浮点运算正在进行 Apple 建议针对 ARM 进行编译 而不是针对拇指进行编译 我的整个应用程序几乎是一个大型浮点运算 iOS 应用程序开发工作流程指南中是这样说的 iOS 设备支持两种指令集 ARM 和 Thumb Xcode
  • ARM + gcc:不要使用一大块 .rodata 部分

    我想使用 gcc 编译一个程序 并针对 ARM 处理器进行链接时间优化 当我在没有 LTO 的情况下编译时 系统会被编译 当我启用 LTO 时 使用 flto 我收到以下汇编错误 错误 无效的文字常量 池需要更近 环顾网络 我发现这与我系统
  • ARM 调用约定是否允许函数不将 LR 存储到堆栈中?

    正如标题所示 我在理解 ARM 架构的调用约定时遇到问题 特别是 我仍然很难知道当你调用子程序时 LR 寄存器会发生什么 我认为 当您进入子程序时 处理 LR 寄存器的最明显 最安全的方法是将其存储到堆栈中 但该行为没有出现在文档中 因此我
  • 了解 ctags 文件格式

    我使用 Exhuberant ctags 来索引我的 c 项目中的所有标签 c project 是 Cortex M7 微控制器的嵌入式软件 结果是一个标签文件 我正在尝试阅读该文件并理解所写的内容 根据我找到的 ctags 和 Exhub
  • 是否可以将 SpaCy 安装到 Raspberry Pi 4 Raspbian Buster

    我一整天都在安装 SpaCy sudo pip install U spacy Looking in indexes https pypi org simple https www piwheels org simple Collectin
  • gdb 不会从外部架构读取核心文件

    我正在尝试在 Linux 桌面上读取 ARM 核心文件 但似乎无法找出我的核心文件 有什么方法可以指示 gdb 我的核心文件是什么类型吗 file daemon daemon ELF 32 bit LSB executable ARM ve
  • 为什么 GCC 交叉编译不构建“crti.o”?

    在尝试为arm构建gcc 4 x x交叉编译器时 我陷入了缺失的困境crti o文件在 BUILD DIR gcc子目录 An strace在顶层Makefile表明编译后的xgcc正在调用交联器ld with crti o 作为一个论点
  • 使用 NEON 内在函数除以浮点数

    我当时正在处理四个像素的图像 这是在armv7对于 Android 应用程序 我想分一个float32x4 t向量由另一个向量组成 但其中的数字与大约不同0 7 to 3 85 在我看来 除法的唯一方法是使用右移 但这是针对一个数字2 n
  • 如何模拟ARM处理器运行环境并加载Linux内核模块?

    我尝试加载我的vmlinux into gdb并使用 ARM 内核模拟器 但我不明白为什么我会得到Undefined target command sim 这是外壳输出 arm eabi gdb vmlinux GNU gdb GDB 7
  • ARM Chromebook 上的 Android 开发环境?

    我尝试了多次安装和使用安卓工作室 https developer android com studio index html on an ARM Chromebook C100P https archlinuxarm org platfor
  • 需要一些建议来开始在 ARM(使用 Linux)平台上编程

    我 也许 很快就会在托管 Linux 发行版的 ARM 平台上工作 我不知道哪个发行版 我知道该项目涉及视频流 但我无法告诉你更多信息 其实我只收到通知 还没见到任何人 我从来没有在这样的平台上工作过 所以我的想法是在项目开始之前进行测试
  • Android NDK 代码中的 SIGILL

    我在市场上有一个 NDK 应用程序 并获得了有关以下内容的本机崩溃报告 SIGILL信号 我使用 Google Breakpad 生成本机崩溃报告 以下是详细信息 我的应用程序是为armeabi v7a with霓虹灯支持 它在 NVIDI
  • .ko 文件是如何构建的

    我正在尝试将我自己的驱动程序移植到Beagle 板 xm arm cortex A8 在移植时我试图弄清楚如何 ko文件实际构建 在我们的Makefile我们只有一个命令来构建 o file 怎样是一个 ko文件已建立 使用Linux 2
  • 直接写入 ARM Cortex A8 分支预测器中的全局历史缓冲区 (GHB) 或 BTB?

    我有兴趣直接修改 Cortex A8 上的 BTB 分支目标缓冲区 和 GHB 的内容 ARM 手册上有这样的内容 要在指令端 GHB 数组中写入一项 例如 LDR R0 0x3333AAAA MCR p15 0 R0 c15 c1 0 M
  • GCC 变量映射和 MISRA-C

    我主要知道两种使用 GCC 声明内存映射寄存器的方法 有许多变体 使用双字段 每个外设的数据结构等 要么使用初始化为正确地址的指针 例如volatile uint32 t pMyRegister uint32 t 0xDEADBEEFUL
  • 2022年Android CPU架构分布(armeabi-v7a vs arm64-v8a)

    有没有关于 2022 年 Android 设备上的架构使用情况的官方信息 我有一个支持armeabi v7a 和arm64 v8a 的应用程序 我想要放弃对armeabi v7a的支持并且仅支持 64 位设备 arm64 v8a 但我找不到
  • 在 ARM Cortex-M3 中使用 newlib 的 malloc

    我正在为 ARM Cortex M3 NXP 的 LCP17xx 创建代码 到目前为止我一直在使用静态内存 一切都运行良好 我尝试添加动态内存支持 但是一旦调用 malloc 系统就会卡住 我正在使用 gcc 为 Arm Bare Meta
  • 如何在数据部分(RAM)中保留一定范围的内存并防止同一应用程序使用该内存的堆/堆栈?

    我想在 RAM 中保留 分配一定范围的内存 并且同一应用程序不应覆盖或使用该范围的内存进行堆 堆栈存储 如何在内存中分配一定范围的内存以防止堆栈 堆覆盖 我考虑过向应用程序本身添加 或分配 一个数组并保留内存 但它被编译器优化了 因为它在应
  • 如何在 Linux 内核中定义并触发我自己的新软中断?

    我想在 Linux 内核中创建自己的软中断 这是正确的方法吗 In the init我想触发该模块的softirq我将添加一个调用 394 void open softirq int nr void action struct softir

随机推荐

  • 高斯过程回归预测Matlab简单实现

    0 说在前面的话 如果是新手入门高斯过程回归的话建议先读这篇博客才能更好理解下面的程序哟 快速入门高斯过程回归预测 1 单点预测例题 主程序 clear close all 求解程序 x 1 5 1 0 75 0 4 0 25 0 输入测量
  • moviepy音视频开发:audio_normalize调整剪辑音量大小到正常

    前往老猿Python博文目录 概述 audio normalize函数用于将一个剪辑的音量大小调整到正常 调整的思路就是将剪辑中音频帧数据的最大值取出来 当其值小于1时 表示剪辑的音量偏小 以1为参考 将所有剪辑帧数据的值都乘以1和剪辑帧数
  • 代码重构与单元测试——测试项目(二)

    二 创建测试项目 我们已经创建了充电宝计费项目 做为我们这次重构的遗留系统 为了验证我们每次重构的正确性 我们需要一个测试项目 对我们重构的代码进行测试 接下来我们来创建这个测试项目 1 在Visual Studio 2019的 解决方案资
  • 解决无法使用gpt的问题

    1 此方法是前提你得有一台服务器之后的操作 2 地区不支持 错误代码1020可以用此方法解决 脚本地址 wget N no check certificate https gitlab com rwkgyg CFwarp raw main
  • 浏览器渲染原理

    浏览器渲染原理 渲染时间点 渲染流水线 解析 HTML Parse HTML 解析 HTML Parse HTML Document Object Model 1 解析 HTML Parse HTML CSS Object Model 解析
  • Eigen 使用碎碎记_norm、normalize、normalized的区别

    本文转载自Eigen中norm normalize normalized的区别 norm normalize normalized的区别 include
  • 小程序实时监听搜索数据并将关键字高亮显示

  • Win10下VS2019双机调试之调试驱动

    转载于 https blog csdn net m0 48995611 article details 112211268 有现成的写的非常详细就不重复造轮子了 ps 1 注意文章字体加深部分 非常重要 2 原文bcdefit dbgset
  • Springboot当中通过引入依赖的形式使用前端框架

    在现在很多大型公司很多都前后端分离开发 而前端也是独立启动的 但是也有很多公司直接是独立的一个项目 前端页面直接在java程序当中 应对与这种独立项目我们可以采用springboot给我们提供的依赖形式来引入前端包 也挺方便的 需要的朋友们
  • Android Studio中重写onClick()方法时,出现Method does not override method from its supperclass问题

    用实现接口的方式来重写监听器中的onClick 方法 改正方法 应在让该类继承implements View OnClickListener
  • UNIX网络编程卷一 学习笔记 第十二章 IPv4与IPv6的互操作性

    未来数年内 因特网也许会逐渐从IPv4过渡到IPv6 在过渡阶段 基于IPv4的现有应用能与基于IPv6的全新应用协同工作非常重要 例如 厂商不应只提供仅能与IPv6 telnet服务器程序协同工作的telnet客户程序 而既应该提供能与I
  • 北京大学肖臻老师《区块链技术与应用》公开课笔记3——BTC数据结构篇

    北京大学肖臻老师 区块链技术与应用 公开课笔记 比特币数据结构篇 对应肖老师视频 click here 全系列笔记请见 click here About Me 点击进入我的Personal Page Hash pointer 哈希指针 指针
  • 入门PCB设计AD9学习笔记8-PCB布板规则

    写作前面 最近在学PCB设计 发现杜洋工作室的入门PCB设计讲的非常详细 适合初学者 由于是视频讲解形式 不利于后期再索引搜索各个知识点细节 所以这里做上笔记方便自己消化和之后内容的索引 惊喜发现已经有前辈写过前几集的内容整理 写的很详细
  • Rigidbody2D ( Simulated )

    bool类型 设为false后则不会模拟刚体
  • 一个TCP长连接设备管理后台工程(一)---概述

    一个TCP长连接设备管理后台工程 一 概述 这个项目最初只是用来进行一个简单的协议测试用的 而且是一个纯粹的后端命令行工程 只是后面想着只有命令行 操作也不太方便 于是便有了添加一个ui的想法 golang项目要配ui 最佳的还是配一个前端
  • 微信小程序之生成图片分享 二维码分享 canvas绘制

    如果本文对你有用 请爱心点个赞 提高排名 帮助更多的人 谢谢大家 如果解决不了 可以在文末进群交流 添加画布 首先 在小程序里进行绘图操作需要用到
  • css3动画 提交成功圆圈画对勾

    这里写目录标题 提交成功圆圈画对勾 遇到的问题 问题一 对号的动画要在圆圈执行完动画后执行 解决 问题二 css不能在display none和display block之间进行动画 解决 代码 提交成功圆圈画对勾 这是一个动画效果 可以直
  • Java多线程进阶(JUC)

    1 什么是JUC JUC实际上是Java包的缩写 java util concurrent包 2 回顾线程和进程 1 进程 一个程序 例如QQ exe 进程是程序的集合 进程是CPU调度的基本单位 一个进程可以有多个线程 至少包含一个 Ja
  • python3.7的版本号安装tensorflow

    步骤 1 下载tensorflow的whl包 由于tensorflow还没有官方支持python3 7 所以pip直接是搜索不到合适的tensorflow的 所以需要下载whl文件包手动安装 有人说google的网址上不去没法下载 解决办法
  • STM32驱动MPU6050基于IIC协议

    一 简介 MPU6050是一款六轴陀螺仪 可以通过IIC协议输出三个方向上的加速度和角速度 在平衡车和飞控中较为常见 一般情况下 模块有用的引脚只有四个 其它的不常用 即VCC GND SDA和SCL 操作它的第一步 即编写IIC协议 二