当前位置: 首页 > news >正文

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

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

2.I2C_ GenerateSTOP 

功能描述:产生 I2Cx 传输 STOP 条件

参数1:I2Cxx 可以是 1 或者 2,来选择 I2C 外设

参数2:NewState: I2Cx STOP 条件的新状态 ,这个参数可以取:ENABLE 或者 DISABLE

3.I2C_ AcknowledgeConfig 

功能描述:使能或者失能指定 I2C 的应答功能

参数1:I2Cxx 可以是 1 或者 2,来选择 I2C 外设

参数2:NewState: I2Cx 应答的新状态 ,这个参数可以取:ENABLE 或者 DISABLE

4.I2C_ SendData 

功能描述:通过外设 I2Cx 发送一个数据

参数1:I2Cxx 可以是 1 或者 2,来选择 I2C 外设

参数2:Data: 待发送的数据

5.I2C_ ReceiveData 

功能描述:返回通过 I2Cx 最近接收的数据

输入参数:I2Cxx 可以是 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…...

CTA策略【量化理论】

CTA策略演变史 全称:Commodity Trading Advisor (商品交易顾问) CTA最开始是指通过为客户提供期权、期货方面的交易建议,或者直接通过受管理的期货账户参与实际交易,来获得收益的机构或个人。 随着市场的发展&#…...

基于AMD AU15P FPGA的SLVS-EC桥PCIe设计方案分享

作者:Hello,Panda 各位FPGAer周末愉快,今天熊猫君分享一个基于AMD AU15P FPGA的SLVS-EC桥PCIe设计方案。 一、方案背景 先说方案的应用背景:众所周知,较为上层的如基于AI的机器视觉应用,大多基于高端的专用SoC、AI专…...

②Modbus TCP转Modbus RTU/ASCII网关同步采集无需编程高速轻松组网

Modbus TCP转Modbus RTU/ASCII网关同步采集无需编程高速轻松组网https://item.taobao.com/item.htm?ftt&id784749793551 网关 MS-A1-5081 MS-A1-5081 网关通过 MODBUS TCP 协议与 Modbus RTU/ASCII 协议的相互转换,可以将 Modbus 串口设备接入 MODBUS TCP 网络…...

游戏引擎学习第145天

仓库:https://gitee.com/mrxiao_com/2d_game_3 今天的计划 目前,我们正在完成遗留的工作。当时我们已经将声音混合器(sound mixer)集成到了 SIMD 中,但由于一个小插曲,没有及时完成循环内部的部分。这个小插曲主要是…...

【Kotlin】Kotlin基础笔记

一、数据类型 1.1 变量声明与类型推导 变量声明 使用 val 声明不可变变量(相当于常量);使用 var 声明可变变量。 val a 10 // 类型自动推断为 Int,不可变 var b: Double 5.0 // 显示声明为 Double,可变变量…...

Jump( 2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15). )

Jump( 2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15). ) 题目大意: 在这个交互式问题中,你需要通过查询系统,逐步找出隐藏的位字符串 S。给定一个偶数 n,表示目标位字符串 S 的长度,你需要通…...

uniapp uniCloud引发的血案(switchTab: Missing required args: “url“)!!!!!!!!!!

此文章懒得排版了,为了找出这个bug, 星期六的晚上我从9点查到0点多,此时我心中一万个草泥马在崩腾,超级想骂人!!!!!!!!! uniCloud 不想…...

【Linux】冯诺依曼体系与操作系统理解

🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:Linux 目录 前言 一、冯诺依曼体系结构 二、操作系统 1. 操作系统的概念 2. 操作系统存在的意义 3. 操作系统的管理方式 4. 补充:理解系统调用…...

STM32之软件SPI

SPI传输更快,最大可达80MHz,而I2C最大只有3.4MHz。输入输出是分开的,可以同时输出输入。是同步全双工。仅支持一主多从。SS是从机选择线。每个从机一根。SPI无应答机制的设计。 注意:所有设备需要共地,时钟线主机输出&…...

Python零基础学习第三天:函数与数据结构

一、函数基础 函数是什么? 想象你每天都要重复做同一件事,比如泡咖啡。函数就像你写好的泡咖啡步骤说明书,每次需要时直接按步骤执行,不用重新想流程。 # 定义泡咖啡的函数 def make_coffee(sugar1): # 默认加1勺糖 print("…...

启动wsl里的Ubuntu24报错:当前计算机配置不支持 WSL2,HCS_E_HYPERV_NOT_INSTALLED

问题:启动wsl里的Ubuntu24报错 报错信息: 当前计算机配置不支持 WSL2。 请启用“虚拟机平台”可选组件,并确保在 BIOS 中启用虚拟化。 通过运行以下命令启用“虚拟机平台”: wsl.exe --install --no-distribution 有关信息,请访…...

顶点着色器和片段着色器

在Unity渲染中,**顶点着色器(Vertex Shader)和片段着色器(Fragment Shader)**是图形渲染管线中的两个核心阶段。我们可以通过一个比喻来理解它们的分工:想象你要画一幅由三角形组成的3D模型,顶点…...

std::optional详解

基础介绍 c17版本引入了std::optional特性&#xff0c;这一个类模板&#xff0c;基本的使用方法如下&#xff1a; std::optional<T> 这个新特性的含义是利用std::optional<T>创建的某个类型的对象&#xff0c;这个对象存储某个类型的值&#xff0c;这个值可能存在…...

Web三件套学习笔记

<!-- HTML --> HTML是超文本标记语言 1、html常用标签 块级标签 独占一行 可以设置宽度&#xff0c;高度&#xff0c;margin,padding 宽度默认所在容器的宽度 标签作用table定义表格h1 ~ h6定义标题hr定义一条水平线p定义段落li标签定义列表项目ul定义无序列表ol定…...

Scala 中trait的线性化规则(Linearization Rule)和 super 的调用行为

在 Scala 中&#xff0c;特质&#xff08;Trait&#xff09;是一种强大的工具&#xff0c;用于实现代码的复用和组合。当一个类混入&#xff08;with&#xff09;多个特质时&#xff0c;可能会出现方法冲突的情况。为了解决这种冲突&#xff0c;Scala 引入了最右优先原则&#…...

C++入门——引用

C入门——引用 一、引用的概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用同一块内存空间。这就好比《水浒传》中&#xff0c;一百零八位好汉都有自己的绰号。通过&…...

深度学习模型组件之优化器—Lookahead:通过“快慢”两组优化器协同工作,提升训练稳定性

深度学习模型组件之优化器—Lookahead&#xff1a;通过“快/慢”两组优化器协同工作&#xff0c;提升训练稳定性 文章目录 深度学习模型组件之优化器—Lookahead&#xff1a;通过“快/慢”两组优化器协同工作&#xff0c;提升训练稳定性1. Lookahead优化器的背景2. Lookahead优…...

K8s 1.27.1 实战系列(五)Namespace

Kubernetes 1.27.1 中的 ​Namespace​(命名空间)是集群中实现多租户资源隔离的核心机制。以下从功能、操作、配置及实践角度进行详细解析: 一、核心功能与特性 ​1、资源隔离 Namespace 将集群资源划分为逻辑组,实现 Pod、Service、Deployment 等资源的虚拟隔离。例如,…...

Spring Boot整合ArangoDB教程

精心整理了最新的面试资料和简历模板&#xff0c;有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 一、环境准备 JDK 17Maven 3.8Spring Boot 3.2ArangoDB 3.11&#xff08;本地安装或Docker运行&#xff09; Docker启动ArangoDB docker run -d --name ar…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...