【STM32】I2C通信

基本的任务是:通过通信线,实现单片机读写外挂模块寄存器的功能。其中至少要实现在指定位置写寄存器和在指定的位置读寄存器这两个功能。

异步时序的优点:省一根时钟线,节约资源;缺点:对事件要求严格,对硬件电路依赖严重

同步时序反过来。

1 I2C通信

I2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线

两根通信线:SCLSerial Clock)、SDASerial Data

同步,半双工

带数据应答

支持总线挂载多设备(一主多从、多主多从)

一主多从:一个单片机作为主机,挂载一个或者多个模块作为从机。

多主多从:多个主机,多个从机(但是同一时刻只能有一个主机控制)

1.1 硬件电路

所有I2C设备的SCL连在一起,SDA连在一起

设备的SCL和SDA均要配置成开漏输出模式

SCL和SDA各添加一个上拉电阻,阻值一般为4.7KΩ左右

左边的CPU就是单片机,作为总线的主机,主机的权利很大,包括对SCL线的完全控制,任何时候都是主机完全掌控SCL线。空闲状态下,主机可以主动发起对SDA的控制,只有在从机发送数据和从机应答时候,主机才会转交SDA的控制权给从机。下面都是被控制IC,也就是挂载在I2C上总线上的从机,这些从机可以是姿态传感器、OELD、存储器、时钟模块等。从机的权利比较小,对于SCL时钟线,在任何时刻都只能被动的读取,从机不允许控制SCL线。对于SDA数据线,从机不允许主动发起对SDA的控制,只有在主机发送读取从机的命令后或者从机应答的时候,从机才能短暂的取得SDA的控制权,这就是一主多从模型。

主机的SCL是输出,没问题,主机和从机的SDA在输入和输出之间变化,

左边是SCL的结构,右边是SDA的结构。

首先引脚的信号进来,都可以通过一个数据缓冲器或者施密特触发器,进行输入,因为输入对电路没有任何影响。在输出这部分使用的是开漏输出的配置(输出低电平,开关管导通,引脚直接接地,是强下拉;输出高电平,这个开关管断开,引脚什么都不接,处于浮空状态,所有的设备只能输出低电平而不能输出高电平,为了避免高电平造成的引脚浮空,这时需要在总线外面SCL和SDA各外置一个上拉电阻,弱上拉)

好处:

(1)完全杜绝了电源短路现象,保证了电路的安全;

(2)避免了引脚模式的频繁切换,开漏加弱上拉的模式,同时兼具了输入和输出的功能。开漏模式下,输出高电平就相当断开引脚,所以在输入之前,可以直接输出高电平,不用切换输入模式了;

(3)这个模式会有一个“线与”的现象,就是只要有任意一个或多个设备输出了低电平,总线就处于低电平。利用这个特性执行多主机模式下的时钟同步和总线仲裁。

1.2 I2C时序基本单元

(1)起始条件:SCL高电平期间,SDA从高电平切换到低电平

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

在I2C处于空闲时,SCL和SDA都处于高电平;SCL高电平期间,SDA从高电平切换到低电平,之后主机要再把SCL拽下来,一方面是占用这个总线,另一方面也是为了这些基本单元的拼接。(低电平开始,低电平结束)

终止条件:SCL先回弹到高电平,之后,SDA再回弹至高电平,这个上升沿触发终止条件。

起始和终止都是由主机产生的。所以在总线空闲状态时,从机必须双手放开,不允许主动跳出来碰总线(允许的话是多主机模型了)

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

起始开始后,第一个字节也必须是主机发送的,最开始SCL是低电平,如果主机想发送0,就拉低SDA到低电平;如果想发送1,就放手,SDA回弹至高电平。在SCL低电平期间,允许改变SDA的电平。当这一位放好后,主机松手时钟线,SCL回弹到高电平,在高电平期间是从机读取SDA的时候,所以高电平期间,SDA不允许变化;SCL处于高电平之后,从机需要尽快的读取SDA,一般是在上升沿这个时刻,从机就已经读取完成了。主机在放手SCL一段时间后,就可以继续拉低SCL了,传输下一位,主机也需要在SCL下降沿之后尽快把数据放到SDA上;数据放完之后,主机再松手SCL,SCL到达高电平,从机读,以此类推。主机拉低SCL,把数据放在SDA上,主机松开SCL,从机读取SDA上的数据,在SCL的同步下依次进行主机的发送和从机的接收。高位先行,所以第一位是第一个字节的最高位B7。SCL和SDA全程由主机掌控,从机只能被动读取。

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

释放SDA就相当于切换成输入模式,所有设备包括主机都处于输入模式,当主机需要发送的时候,就可以主动拉低SDA,而主机在被动接收的时候,就必须先释放SDA(总线是线与的特征)。

接收一个字节和发送一个字节非常相似。

区别是:发送一个字节是低电平主机放数据,高电平从机读数据;

           而接收一个字节是低电平从机放数据,高电平主机读数据,

主机在接收数据之前要先释放SDA线,然后这是从机取得SDA的控制权,从机需要发送0,就把SDA拉低;从机需要发送1,就放手SDA线,SDA回弹至高电平。然后同样的,低电平变换数据,高电平读取数据。实线表示主机控制的电平,虚线表示从机控制的电平。SCL全程由主机控制,SDA主机在接收前要释放,交由从机控制,从机的数据变化都是贴着SCL下降沿进行的,而主机可以在SCL任意高电平时刻读取数据,这就是接收一个字节的时序。

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

在接收一个字节后,需要给从机一个应答位,发送应答位的目的是告诉从机,是不会还要继续发,如果从机发送一个数据后,得到了主机的应答,那从机就会继续发送;如果从机没有得到主机的应答,那从机就会认为,自己发送了一个数据,主机不理,可能主机不想要了,这时从机就会释放SDA,交出SDA的控制权,防止干扰主机的操作。

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

在调用发送一个字节之后,就要紧跟着调用接收应答的时序,用来判断从机有没有收到刚才给它的数据。如果从机收到了,那在应答位这里,主机释放SDA的时候,从机就应该立刻把SDA拉下来,然后在SCL高电平期间,主动读取应答;如果应答位为0,就说明从机确实收到了。这个场景就是主机刚发送一个字节,问有没有人收到,现在把SDA放手了,如果有人收到的话,就把SDA拽下来,然后主机高电平读取数据,发现确实有人拽下来了,说明有人收到了数据;如果主机发送松手后,SDA跟着回弹到高电平,说明没人回应,没人收到或者收到没回应。

1.3 I2C时序

从机有唯一的设备地址。(7位地址)MPU6050: 1101 000

(1)指定地址写

对于指定设备(Slave Address),在指定地址(Reg Address)下(设备内部地址,寄存器),写入指定数据(Data

SAD和SDL都处于高电平,开始的时候,拉低SDA,产生起始条件,在起始条件之后,紧跟着的时序必须是发送一个字节的时序,字节的内容必须是从机地址+读写位,从机地址7位,读写位1位, 加起来是一个字节8位,发送从机地址就是确定通信对象,发送读写位就是确定接下来是读出还是写入。具体:低电平期间,SDA变换数据,高电平期间,从机读取SDA。绿色的竖线表示从机读的数据。主机寻找的地址是1101 000(MPU6050的地址),后面的0表示之后的时序主机要进行写入操作,1表示之后的时序要进行读出操作。目前主机是发送一个字节,字节的内容转换成16进制,高位先行,就是0xD0,然后根据协议规定,紧跟着的就是接收从机的应答位(Receive ACK,RA),在这个时刻,主机要释放SDA。

如果单看主机的波形,释放SDA之后,引脚电平回弹到高电平(黄线),但是根据协议规定,从机要在这个时候拉低SDA(绿线),综合两者的波形,在主机释放SDA之后,由于SDA也被从机拽住了,所以主机松手后,SDA并没有回弹高电平,这个过程就表示从机产生了应答,最终高电平期间,主机读SDA,发现是0,就说明进行寻址时,有人给我应答了,传输没问题;如果主机读取SDA发现是1,就说明寻址在应答期间,我松手了,但是没人拽住它,没人给我应答,就直接产生停止条件。后面的上升沿就是应答结束后,从机释放SDA产生的,从机交出SDA的控制权,因为从机要在低电平期间尽快变换数据,所以这个上升沿和SCL的下降沿几乎是同时发生的。继续往后,读写位给了0,所以应答结束后,要继续发送一个字节,同样的时序,再来一遍,第二个字节就可以送到指定设备的内部了,从机设备可以自己定义第二个字节和后续字节的用途,一般第二个字节可以是寄存器地址或者指令控制字等。这里是0x19就表示要操作0x19地址下的寄存器了。

接着同样是从机应答,主机释放SDA,从机拽住SDA,SDA表现为低电平,主机接收到应答位0,表示收到了从机的应答。同样的流程再来一遍,主机再发送一个字节,这里表示要在0x19地址下写入0xAA,最后是接收应答位。如果主机不需要再继续传输了,就可以产生停止条件,在停止条件之前,先拉低SDA,为后续的SDA上升沿做准备,然后释放SCL,再释放SDA,这样就产生了SCL高电平期间,SDA的上升沿。

总结:这个数据帧的目的就是对于指定从机地址为1101 0000的设备,在其内部0x19的寄存器中写入0xAA这个数据。

(2)当前地址读

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

如果主机想要读取从机的数据,就可以执行这个时序。最开始还是SCL高电平期间,拉低SDA,产生起始条件,起始条件开始后,主机必须首先调用发送一个字节,来进行从机的寻址和指定读写标志位,图中表示本次寻址的目标是1101 000的设备,最后一位读写标志位为1,表示主机读取数据,紧跟着,发送一个字节之后,接收一下从机的应答,从机应答0,表示从机接收到了第一个字节,在从机应答之后,在这里开始,数据的传输方向就要反过来了。

主机刚才发出了读的指令,所以在这之后,主机就不能继续发送了,要把SDA的控制权给从机,主机调用接收一个字节的时序,进行接收操作,之后,从机得到主机的允许,可以在SCL低电平期间写入SDA,然后主机在SCL高电平期间读取SDA,最终,主机在SCL高电平期间依次读取8位,就接收到从机发送的一个字节的数据,0000 1111,也就是0x0F,这里没有指定地址环节,这里需要用到当前地址指针了,在从机中,所有寄存器被分配到一个线性区域中,并且会有一个单独的指针变量,指示着其中一个寄存器,一般默认为0地址,每写入和读出一个字节后,这个指针就会自动自增一次,主机没有指定地址的话,从机就会返回当前指针指向的寄存器的值。

(3)指定地址读

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

前面一部分是指定地址的时序,把后面写数据的部分去掉,然后把前面这一部分设置地址,还没有指定写什么数据的时序,追加到当前地址读的时序前,就得到了指定地址读的时序(复合格式)

前面部分是指定地址写,只指定了地址,还没来得及写;后面的部分是当前地址读,加起来就是指定地址读了。

前面依然是启动条件,然后发送一个字节进行寻址,指定从机地址是1101 000,读写标标志位是0,表示进行写操作,经过从机应答后,再发送一个字节,第二个字节用来指定地址,这个数据就写入到从机的地址指针里了,也就是说从机接收到这个数据之后,它的寄存器指针就指向0x19这个位置了,之后要写入的数据,不给它发,直接再来个起始条件(start repeat),然后重新寻址并且指定读的标志位,此时读写标志位是1,表示要开始读了,接着主机接收一个字节,这个字节就是0x19地址下的数据,

进阶版本就是读写多个字节。

1.4 MPU6050简介

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/242057.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python实现元旦多种炫酷高级倒计时_附源码【第19篇—python过元旦】

文章目录 🌍python实现元旦倒计时 — 初级(控制台)⛅实现效果🌋实现源码🌜源码讲解 🌍python实现元旦倒计时 — 中级(精美动态图)⛅实现效果🌋实现源码🌜源码讲解 🌍python实现元旦倒计时 — 高…

Fireblock:为Dapp实现可编程隐私

1. 引言 Fireblock network为Cosmos生态应用链。并于2023年10月宣布完成pre-seed轮250万美金融资。 其定位为实现: 有条件解密可编程隐私 Fireblock使用的密码学方案有: distributed key generation(DKG)Identity-based encry…

Linux网络编程——Socket编程步骤及常用API

Sockt服务器和客户端的开发步骤 TCP connect()最好建立在listen()后&#xff0c;一旦监听到就建立连接。 UDP 常用API 包含头文件 #include<sys/types.h> #include<sys/socket.h>创建套接字&#xff08;连接协议&#xff09; 作用 用于根据指定的地址族、数据…

四、ensp配置ftp服务器实验

文章目录 实验内容实验拓扑操作步骤配置路由器为ftp server 实验内容 本实验模拟企业网络。PC-1为FTP 用户端设备&#xff0c;需要访问FTP Server&#xff0c;从服务器上下载或上传文件。出于安全角度考虑&#xff0c;为防止服务器被病毒文件感染&#xff0c;不允许用户端直接…

SpringBoot集成opencc4j实现繁体中文转为简体中文

背景 繁体中文转为简体中文的需求非常常见&#xff0c;特别是在中文语境下的文本处理和翻译应用中。有很多现成的工具和库可以实现这个功能&#xff0c;比如 OpenCC 、 HanLP 等。从网上下载的 MySQL 版诗词数据库中的诗词数据都是繁体字&#xff0c;这里使用 SpringBoot 集成…

互联网上门洗衣洗鞋小程序优势有哪些?

互联网洗鞋店小程序相较于传统洗鞋方式&#xff0c;具有以下优势&#xff1b; 1. 便捷性&#xff1a;用户只需通过手机即可随时随地下单并查询&#xff0c;省去了许多不必要的时间和精力。学生们无需走出宿舍或校园&#xff0c;就能轻松预约洗鞋并取件。 2. 精准定位&#xff1…

代码随想录刷题题Day21

刷题的第二十一天&#xff0c;希望自己能够不断坚持下去&#xff0c;迎来蜕变。&#x1f600;&#x1f600;&#x1f600; 刷题语言&#xff1a;C Day21 任务 ● 216.组合总和III ● 17.电话号码的字母组合 1 组合总和III 216.组合总和III 思路&#xff1a; 在[1,2,3,4,5,6,…

vcomp120.dll缺失怎么解决,vcomp120.dll丢失的详细修复方法分享(总共5种方法)

计算机提示找不到vcomp120.dll&#xff0c;无法继续执行代码的5个解决方法和vcomp120.dll是什么以及vcomp120.dll丢失原因与作用解析 在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“找不到vcomp120.dll&#xff0c;无法继续执行代码”。…

基于Springboot的宠物领养系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的宠物领养系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

嵌入式开发必须学习qt吗?

嵌入式开发必须学习qt吗&#xff1f; 在开始前我有一些资料&#xff0c;是我根据自己从业十年经验&#xff0c;熬夜搞了几个通宵&#xff0c;精心整理了一份「 嵌入式的资料从专业入门到高级教程工具包」&#xff0c;点个关注&#xff0c;全部无偿共享给大家&#xff01;&#…

【Linux】定时任务

定时任务常用crontab来定期执行程序。 crontab 基本语法 crontab [-u user] -l # 列出用户cron任务 crontab [-u user] -e # 编辑用户cron任务 crontab [-u user] -r # 移除用户cron任务cron 表达式 # 分 时 日 月 周 执行命令 minute hour day month week command # 示例…

代码随想录算法训练营 | day60 单调栈 84.柱状图中最大的矩形

刷题 84.柱状图中最大的矩形 题目链接 | 文章讲解 | 视频讲解 题目&#xff1a;给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 1 < heights.len…

第六部分 集合论

目录 主要内容 集合的基本概念 集合的基本运算 集合恒等式 初级运算 文氏图 集合的广义并与广义交 广义运算的性质 例1 A{{a},{a,b}} 集合算律 例2 判断下列命题是否为真 例3 设 例4 判断以下命题的真假&#xff0c;并说明理由. 解题思路 主要内容 集合的基本概念 属于、包含…

JavaOOP篇----第十五篇

系列文章目录 文章目录 系列文章目录前言一、有没有可能两个不相等的对象有相同的hashcode二、拷贝和浅拷贝的区别是什么?三、static都有哪些用法?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通…

HarmonyOS4.0系统性深入开发03UIAbility组件详解(中)

UIAbility组件基本用法 UIAbility组件的基本用法包括&#xff1a;指定UIAbility的启动页面以及获取UIAbility的上下文UIAbilityContext。 指定UIAbility的启动页面 应用中的UIAbility在启动过程中&#xff0c;需要指定启动页面&#xff0c;否则应用启动后会因为没有默认加载…

抖音网红罗盘时钟改良版

文章目录 💕效果展示💕代码展示HTML💕效果展示 💕代码展示 HTML <!DOCTYPE html> <html lang=

【BBuf的CUDA笔记】十,Linear Attention的cuda kernel实现解析

欢迎来 https://github.com/BBuf/how-to-optim-algorithm-in-cuda 踩一踩。 0x0. 问题引入 Linear Attention的论文如下&#xff1a; Transformers are RNNs: Fast Autoregressive Transformers with Linear Attention&#xff1a;https://arxiv.org/pdf/2006.16236.pdf 。官方…

微信小程序-textarea组件字数实时更新

一、前言 本文实现的是在小程序中&#xff0c;textarea文本框输入文字后&#xff0c;实时显示文字的字数&#xff0c;获取更好的用户输入体验以及提示。 下图是实现的效果 二、代码实现 2-1、wxml代码 <view style"padding: 30rpx;"><view style"…

MySQL 数据库系列课程 04:MySQL Workbench的安装

Workbench 是 MySQL 官方推出的免费的强大的可视化工具&#xff0c;不熟悉命令行工具的人&#xff0c;可以安装这一款软件&#xff0c;通过编写 SQL 进行数据库中数据的增删改查操作&#xff0c;接下来我们详细说明一下 Workbench 的安装。 一、Windows安装Workbench &#x…

java八股 redis

Redis篇-01-redis开篇_哔哩哔哩_bilibili 1.缓存穿透 2.缓存击穿 逻辑过期里的互斥锁是为了保证只有一个线程去缓存重建 3.缓存雪崩 4.双写一致性 4.1要求一致性&#xff08;延迟双删/互斥锁&#xff09; 延迟双删无法保证强一致性 那么前两步删缓和更新数据库哪个先呢&#xf…