STM32-I2C通信外设
目录
一:I2C外设简介
二:I2C外设数据收发
三:I2C的复用端口
四:主机发送和接收
五:硬件I2C读写MPU6050
相关函数:
1.I2C_ GenerateSTART
2.I2C_ GenerateSTOP
3.I2C_ AcknowledgeConfig
4.I2C_ SendData
5.I2C_ ReceiveData
第一步:配置I2C外设,对I2C外设进行初始化
第二步:控制外设电路,实现指定地址写的时序
第三步:控制外设电路,实现指定地址读的时序
六:防止死循环卡机
一:I2C外设简介
STM32内部集成了硬件I2C收发电路,可以由硬件自动执行时钟生成、起始终止条件生成、应答位收发、数据收发等功能,减轻CPU的负担。也就是由硬件电路来自动翻转引脚电平,软件只需要写入控制寄存器CR和数据寄存器DR,还需要用SR读取状态。(高位先行)

二:I2C外设数据收发
1.当我们需要发送数据时,可以把一个数据写到数据寄存器DR,当移位寄存器没有数据移位时,这个数据寄存器(DATA REGISTER)的值就会进一步转到移位寄存器里,在移位的过程中,就可以把下一个数据放到数据寄存器(DATA REGISTER)里等着,一旦前一个数据完成,下一个数据就可以无缝衔接,继续发送。当数据由数据寄存器(DATA REGISTER)转到移位寄存器时,就会置状态寄存器的TXE位为1,表述发送寄存器为空。
2.接收数据时,输入的数据,一位一位地从引脚移动到移位寄存器里,当一个字节收齐之后,数据就整体从移位寄存器转到数据寄存器,同时置标志位RXNE,表示接受寄存器非空,这时就可以从数据由数据寄存器(DATA REGISTER)里把数据读出来。

三:I2C的复用端口


四:主机发送和接收
1.主机发送:
首先,初始化之后,总线默认空闲状态STM32默认是从模式,为了产生一个起始条件,STM32需要写入控制寄存器,只要在控制寄存器START位,写1就可以产生起始条件——STM32由从模式变为主模式。



五:硬件I2C读写MPU6050
相关函数:
1.I2C_ GenerateSTART

2.I2C_ GenerateSTOP
功能描述:产生 I2Cx 传输 STOP 条件
参数1:I2Cx:x 可以是 1 或者 2,来选择 I2C 外设
参数2:NewState: I2Cx STOP 条件的新状态 ,这个参数可以取:ENABLE 或者 DISABLE

3.I2C_ AcknowledgeConfig
功能描述:使能或者失能指定 I2C 的应答功能
参数1:I2Cx:x 可以是 1 或者 2,来选择 I2C 外设
参数2:NewState: I2Cx 应答的新状态 ,这个参数可以取:ENABLE 或者 DISABLE

4.I2C_ SendData
功能描述:通过外设 I2Cx 发送一个数据
参数1:I2Cx:x 可以是 1 或者 2,来选择 I2C 外设
参数2:Data: 待发送的数据
5.I2C_ ReceiveData
功能描述:返回通过 I2Cx 最近接收的数据
输入参数:I2Cx:x 可以是 1 或者 2,来选择 I2C 外设

第一步:配置I2C外设,对I2C外设进行初始化
- 开启I2C和GPIO时钟
- 需要把PB10和PB11都初始化为复用开漏模式(原因:开漏是I2C协议设计要求,复用是GPIO的控制权要交给硬件外设,如果是软件I2C的话就是通用开漏模式)
- 初始I2C2外设
- 使能I2C255
/*** 函 数:MPU6050初始化* 参 数:无* 返 回 值:无*/
void MPU6050_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); //开启I2C2的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启GPIOB的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure); //将PB10和PB11引脚初始化为复用开漏输出/*I2C初始化*/I2C_InitTypeDef I2C_InitStructure; //定义结构体变量I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //模式,选择为I2C模式I2C_InitStructure.I2C_ClockSpeed = 50000; //时钟速度,选择为50KHzI2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; //时钟占空比,选择Tlow/Thigh = 2I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //应答,选择使能I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //应答地址,选择7位,从机模式下才有效I2C_InitStructure.I2C_OwnAddress1 = 0x00; //自身地址,从机模式下才有效I2C_Init(I2C2, &I2C_InitStructure); //将结构体变量交给I2C_Init,配置I2C2/*I2C使能*/I2C_Cmd(I2C2, ENABLE); //使能I2C2,开始运行/*MPU6050寄存器初始化,需要对照MPU6050手册的寄存器描述配置,此处仅配置了部分重要的寄存器*/MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x01); //电源管理寄存器1,取消睡眠模式,选择时钟源为X轴陀螺仪MPU6050_WriteReg(MPU6050_PWR_MGMT_2, 0x00); //电源管理寄存器2,保持默认值0,所有轴均不待机MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x09); //采样率分频寄存器,配置采样率MPU6050_WriteReg(MPU6050_CONFIG, 0x06); //配置寄存器,配置DLPFMPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18); //陀螺仪配置寄存器,选择满量程为±2000°/sMPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18); //加速度计配置寄存器,选择满量程为±16g
}
第二步:控制外设电路,实现指定地址写的时序
- 生成起始条件(对于非阻塞式的程序,在函数结束之后,我们都要等待相应的标志位来确保这个函数的操作执行到位了,所以在程序中我们要等待EV5事件的到来),检测EV5事件:I2C_ CheckEvent——检查最近一次 I2C 事件是否是输入的事件
- 起始条件发送之后,就要发送从机地址、接收应答
- 按这个流程写代码:

/*** 函 数:MPU6050写寄存器* 参 数:RegAddress 寄存器地址,范围:参考MPU6050手册的寄存器描述* 参 数:Data 要写入寄存器的数据,范围:0x00~0xFF* 返 回 值:无*/
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{I2C_GenerateSTART(I2C2, ENABLE); //硬件I2C生成起始条件MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT); //等待EV5I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter); //硬件I2C发送从机地址,方向为发送MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED); //等待EV6I2C_SendData(I2C2, RegAddress); //硬件I2C发送寄存器地址MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING); //等待EV8I2C_SendData(I2C2, Data); //硬件I2C发送数据MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED); //等待EV8_2I2C_GenerateSTOP(I2C2, ENABLE); //硬件I2C生成终止条件
}
第三步:控制外设电路,实现指定地址读的时序
/*** 函 数:MPU6050读寄存器* 参 数:RegAddress 寄存器地址,范围:参考MPU6050手册的寄存器描述* 返 回 值:读取寄存器的数据,范围:0x00~0xFF*/
uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{uint8_t Data;I2C_GenerateSTART(I2C2, ENABLE); //硬件I2C生成起始条件MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT); //等待EV5I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter); //硬件I2C发送从机地址,方向为发送MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED); //等待EV6I2C_SendData(I2C2, RegAddress); //硬件I2C发送寄存器地址MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED); //等待EV8_2I2C_GenerateSTART(I2C2, ENABLE); //硬件I2C生成重复起始条件MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT); //等待EV5I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Receiver); //硬件I2C发送从机地址,方向为接收MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED); //等待EV6I2C_AcknowledgeConfig(I2C2, DISABLE); //在接收最后一个字节之前提前将应答失能I2C_GenerateSTOP(I2C2, ENABLE); //在接收最后一个字节之前提前申请停止条件MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED); //等待EV7Data = I2C_ReceiveData(I2C2); //接收数据寄存器I2C_AcknowledgeConfig(I2C2, ENABLE); //将应答恢复为使能,为了不影响后续可能产生的读取多字节操作return Data;
}
六:防止死循环卡机
/*** 函 数:MPU6050等待事件* 参 数:同I2C_CheckEvent* 返 回 值:无*/
void MPU6050_WaitEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{uint32_t Timeout;Timeout = 10000; //给定超时计数时间while (I2C_CheckEvent(I2Cx, I2C_EVENT) != SUCCESS) //循环等待指定事件{Timeout --; //等待时,计数值自减if (Timeout == 0) //自减到0后,等待超时{/*超时的错误处理代码,可以添加到此处*/break; //跳出等待,不等了}}
}
相关文章:
STM32-I2C通信外设
目录 一:I2C外设简介 二:I2C外设数据收发 三:I2C的复用端口 四:主机发送和接收 五:硬件I2C读写MPU6050 相关函数: 1.I2C_ GenerateSTART 2.I2C_ GenerateSTOP 3.I2C_ AcknowledgeConfig 4.I2C…...
【脚本】Linux一键扩大虚拟内存的大小
Linux增加虚拟内存其实很简单 就那几个命令,free、mkswap、swapon 但是方便起见我写成了脚本 使用方法 进入你的目录, nano ./install_swap.sh 下面的脚本全文复制,粘贴进去之后,按ctrlx后按y保存 然后运行以下命令 sudo bash …...
信号隔离器 0-20mA/0-10V模拟信号隔离模块变送器 一进二出高精度
信号隔离器 0-20mA/0-10V模拟信号隔离模块变送器 一进二出高精度https://item.taobao.com/item.htm?ftt&id766022047828 型号 一进二出 0-20mA 转0-20mA/0-10V MS-C12 一进二出 0-10V 转 0-20mA/0-10V MS-V12 信号隔离器 单组输出 MS-C1/V1 双组输出 MS-C12/V12 用于…...
Nat. Methods | scPerturb——单细胞扰动数据的标准化资源与统计分析方法
《Nature Methods》提出scPerturb资源平台,整合44个单细胞扰动数据集(涵盖转录组、表观组、蛋白组读值),并通过能量统计量(E-statistics)量化扰动效应,旨在解决单细胞扰动数据的互操作性差、缺乏…...
【易康eCognition实验教程】005:影像波段组合显示与单波段显示
文章目录 一、加载多波段影像二、单波段显示三、彩色显示一、加载多波段影像 二、单波段显示 如果导入的影像数据具有三个或者更多的波段,影像场景将自动以RGB(红绿蓝)模式默认显示,如上图所示。在视图设置(View Settings)窗口中使用单波段灰度显示(Single LayuerGrays…...
使用Process Explorer、Dependency Walker和PE信息查看工具快速排查dll动态库因库与库版本不一致导致的加载失败问题
目录 1、问题说明 2、使用Process Explorer查看目标dll动态库有没有动态加载起来 3、使用Dependency Walker查看xxpadll.dll库的库依赖关系,找到xxpadll.dll加载失败的原因 4、使用PE信息查看工具查看目标dll库的时间戳 5、关于xxsipstack2.dll中调用xxdatanet…...
Git的命令学习——适用小白版
浅要了解一下Git是什么: Git是目前世界上最先进的的分布式控制系统。Git 和其他版本控制系统的主要差别在于,Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。Git 并不保存这些前后变化的差异数据。实际上…...
如何安全处置旧设备?
每年,数百万台旧设备因老化、故障或被新产品取代而被丢弃,这些设备上存储的数据可能带来安全风险。 如果设备没有被正确删除数据,这些数据往往仍可被恢复。因此,安全处置旧设备至关重要。 旧设备可能包含的敏感数据 旧设备中可能…...
Java 学习记录:基础到进阶之路(一)
今天,让我们深入到 Java 项目构建、基础语法及核心编程概念的领域,一探究竟。 软件安装及环境配置请查看之前更新的博客有着详细的介绍: IDEA软件安装&环境配置&中文插件-CSDN博客 目录 1.Java 项目构建基础 1.项目中的 SRC 目录…...
3.3-3.9 蓝桥杯备赛周记
斜率关系 14届省赛 ![[Pasted image 20250205145241.png]] NE555频率解算温度 频率范围外 无效 unsigned int Freq; if(Freq<200) {humnity0;} else if(Freq>2000) {humnity0;} else{ humnity80.0/1800.0 *(float)(Freq-200)10.0;} 斜率计算题 需要类型转换 和数据需要…...
系统架构设计师—系统架构设计篇—软件架构风格
文章目录 概述经典体系结构风格数据流风格批处理管道过滤器对比 调用/返回风格主程序/子程序面向对象架构风格层次架构风格 独立构件风格进程通信事件驱动的系统 虚拟机风格解释器基于规则的系统 仓库风格(数据共享风格)数据库系统黑板系统超文本系统 闭…...
工厂模式加策略模式 -- 具体实现
这里写目录标题 定义接口定义抽象类定义主处理器分支处理器定义工厂demo 定义接口 public interface EntityHandler extends InitializingBean {MatchContentDTO match(MatchEntityDTO matchEntityDTO);String supportEntityType(); }定义抽象类 public abstract class Abstr…...
STM32---FreeRTOS消息队列
一、简介 1、队列简介: 队列:是任务到任务,任务到中断、中断到任务数据交流的一种机制(消息传递)。 FreeRTOS基于队列,实现了多种功能,其中包括队列集、互斥信号量、计数型信号量、二值信号量…...
python-leetcode-删掉一个元素以后全为 1 的最长子数组
1493. 删掉一个元素以后全为 1 的最长子数组 - 力扣(LeetCode) 可以使用滑动窗口的方式来解决这个问题。我们要找到最长的全 1 子数组,但必须删除一个元素,因此可以将问题转化为寻找最多包含一个 0 的最长子数组。 解题思路 使用双指针(滑动窗口),维护窗口内最多包含一…...
【赵渝强老师】PostgreSQL的模板数据库
在PostgreSQL中,创建数据库时实际上通过拷贝一个已有数据库进行工作的。在默认情况下,将拷贝名为template1的标准系统数据库。所以该数据库是创建新数据库的“模板”。如果为template1数据库增加对象,这些对象将被拷贝到后续创建的用户数据库…...
vue2中,在table单元格上右键,对行、列的增删操作(模拟wps里的表格交互)
HTML <template><div><divclass"editable-area"v-html"htmlContent"contenteditableblur"handleBlur"contextmenu.prevent"showContextMenu"></div><button click"transformToMd">点击转成M…...
使用DeepSeek+蓝耘快速设计网页简易版《我的世界》小游戏
前言:如今,借助先进的人工智能模型与便捷的云平台,即便是新手开发者,也能开启创意游戏的设计之旅。DeepSeek 作为前沿的人工智能模型,具备强大的功能与潜力,而蓝耘智算云平台则为其提供了稳定高效的运行环境…...
解决微信小程序中调用流式接口,处理二进制数据时 TextDecoder 不兼容的问题
问题复现 最近在开发一个 AI 问答小程序时,由于接口返回的是流式二进制数据,因此我使用了 TextDecoder 的 decode 方法将二进制数据转换为文本。在开发环境中,数据处理一直没有问题,但在真机测试及上线后,发现调用接口…...
DeepSeek与QWQ大模型对比
题目为《deepseek和qwq大模型对比》1000字 DeepSeek与QWQ大模型对比 引言 在人工智能领域,大模型的发展日新月异。DeepSeek和QWQ作为两种具有代表性的大模型,各自在技术架构、应用场景和性能表现上展现出独特优势。本文将从多个维度对这两种模型进行详细…...
Java 大视界 -- Java 大数据在智慧农业农产品质量追溯与品牌建设中的应用(124)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
c++介绍信号六
信号量是c中实现对有限资源访问控制,现成通过信号量获得对资源访问的许可。可用资源大于0,线程可以对资源进行访问,此时计数器减1。当计数器为0时,不可访问资源,线程进入等待。当资源释放时,线程结束等待&a…...
DeepSeek 本地部署全流程指南:畅享专属AI体验
DeepSeek本地部署全流程指南:畅享专属AI体验 一、部署优势剖析 在本地部署DeepSeek大模型,能带来诸多好处。一方面,数据隐私更有保障,所有运算都在本地独立完成,无需联网,有效避免了数据泄露的风险。另一…...
GStreamer —— 2.18、Windows下Qt加载GStreamer库后运行 - “播放教程 6:音频可视化“(附:完整源码)
运行效果 介绍 GStreamer 带有一组将音频转换为视频的元素。他们 可用于科学可视化或为您的音乐增添趣味 player 的本教程展示了: • 如何启用音频可视化 • 如何选择可视化元素 启用音频可视化实际上非常简单。设置相应的标志,当纯音频流为 found&#…...
IP 地址与端口号:网络通信的双重坐标解析
IP 地址与端口号:网络通信的双重坐标解析 在互联网广袤无垠的世界里,数据恰似无数灵动的信息精灵,在复杂的网络脉络中穿梭往来。而确保这些数据能够精准无误地抵达目的地的关键,便是两个至关重要的核心标识符:IP 地址…...
用Deepseek写一个 HTML 和 JavaScript 实现一个简单的飞机游戏
大家好!今天我将分享如何使用 HTML 和 JavaScript 编写一个简单的飞机游戏。这个游戏的核心功能包括:控制飞机移动、发射子弹、敌机生成、碰撞检测和得分统计。代码简洁易懂,适合初学者学习和实践。 游戏功能概述 玩家控制:使用键…...
【从零开始学习计算机科学】操作系统(三)进程的互斥、同步与通信
【从零开始学习计算机科学】操作系统(三)进程的互斥、同步与通信 进程的互斥、同步与通信进程的互斥进程的同步进程的通信进程的互斥、同步与通信 进程的互斥 两个或两个以上的进程,不能同时进入关于同一组共享变量的临界区域,否则可能发生与时间有关的错误,这种现象被称…...
Android Compose MutableInteractionSource介绍
在 Android 开发中,Compose 是 Google 推出的现代化 UI 工具包,它让开发者能够更简洁高效地构建应用界面。而 MutableInteractionSource 是 Compose 中一个重要的组件,它可以帮助你处理用户与界面交互时的状态变化,尤其在处理交互…...
[杂学笔记] TCP和UDP的区别,对http接口解释 , Cookie和Session的区别 ,http和https的区别 , 智能指针 ,断点续传
文章目录 1. TCP和UDP的区别2. 对http接口解释3. Cookie和Session的区别4. http和https的区别5. 智能指针6.断点续传 1. TCP和UDP的区别 tcp的特点: 面向连接,可靠性高,全双工,面向字节流udp特点:无连接,不…...
Ubuntu 源码安装 Qt5
1.开发背景 Ubuntu 下安装指定版本的 Qt,最新的Qt官方已经不支持 Qt5.15.2 版本以下版本,所以有必要用旧的源码编译 Qt 库。 2.开发需求 源码安装 Qt5.12.2 3.开发环境 开发环境:Ubuntu18.04 目标版本:Qt5.12.2 4.实现步骤 4…...
【NLP 29、项目 Ⅰ:电商评论分类(好评 / 差评) 】
目录 项目介绍 一、训练及测试数据 二、代码实现 1.配置文件 config.py 2.分割训练集和验证集 split_train_valid.py 3.数据加载文件 loader.py Ⅰ、 加载和处理数据 DataGenerator ① 初始化 ② 数据加载 ③ 文本编码 ④ 补齐 / 截断 ⑤ 获取数据集长度和指定索引的数据 Ⅱ、加…...
