I2C总线时序以及ACK和NACK(NAK),SCL被从机拉低?

2023-10-27

1、I2C协议详解及裸机程序分析 - 简书(通俗易懂)

 

根据上图,我们首先设置IICCON(来设置时钟),时钟源是PCLK(是50MHZ)太快了我们需要设置这个分频系数,把时钟降低,降低到我们想要的SCL,然后我们要发出start信号,我们需要设置寄存器发出start信号,之后我们需要发出数据啊,我们的程序可以把数据写入到IICDS寄存器,一写入就会自动的发出时钟,并且把这8位数据从SDA发送给从设备,数据发送之后,在第九个时钟会收到回应信号,可以查询IICSTAT是否有ACK(有ACK表示数据发送成功了),可以继续发送数据,等发完数据之后,再来设置IICSTAT让它发出P信号。

 

关于i2c的响应问题:对于每一个接收设备(从设备,slaver),当它被寻址后,都要求在接收到每一个字节后产生一个响应。因此,the master device 必须产生一个额外的时钟脉冲(第九个脉冲)用以和这个响应位相关联。

在这个脉冲期间,发出响应的从设备必须将SDA拉低并在时钟脉冲的高电平期间保持住。这表示该设备给出了一个ACK。如果它不拉低SDA线,就表示不响应(NACK)。

另外,在从机(发送方)发送完最后一个字节后主设备(接收方)必须产生一个不响应位,用以通知从机(发送方)不要再发送信息了,这样从机就知道该将SDA释放了,而后,主机发出一个停止位给slaver。

总结下,标准的IIC协议中,SDA 和 SCL 都是有主机控制的,从设备只是能够将SDA线拉低而已。对于SCL线,从机是没有任何能力去控制的。从机只能被动跟随SCL

再说的清楚些:

主机发送数据到从机的状态下:主机控制SCL信号线和SDA信号线,从机只是在SCL线为高的时候去被动读取SDA线。

主机读取从机的数据:主机来发出时钟信号,从机只是保证在时钟信号为高电平的时候的SDA的状态而已。

冲突争论点:从机到底能不能拉低SCL?

标准的IIC协议中说明,IIC通讯中,SDA 和 SCL 都是有主机控制的,从设备只是能够将SDA线拉低而已。对于SCL线,从机是没有任何能力去控制的。从机只能被动跟随SCL。从这段话得出,从机无权控制SCL线。
但是!!!在实际应用中,我遇到了从机将SCL拉低的情况。一笔数据(8bit+ACK)完成之后,从机开始处理数据(从机忙碌),无法接受下一笔数据,此时从机将SCL拉低,主机需等待SCL变为高电平时才可以继续进行数据传输。
比如我主机没有给足够的处理数据时间(此时间要看软件也即程序需跑多久才处理完成),主机想强行拉高SCL发送下一帧数据,这时候抓取波形来看,就像是SCL想拉高但是拉不起来,被拽住了一样。而后果就是下一帧的数据错乱,严重的甚至导致IIC通信死掉。

从机拉低SCL的情况是存在的:当从机正忙、无法保质保量完成接下来的通讯时,可以主动将SCL拉低,是以谓之 Clock Stretching。这是整个I²C总线中从机唯一有权限拉低SCL的特例。

I2c slave将SCL主动拉低 - 开发者知识库

5.1 SCL信号的同步
如果被控器希望主控器降低传送速度可以通过将SCL主动拉低延长其低电平时间的方法来通知主控器,当主控器在准备下一次传送发现SCL的电平被拉低时就进行等待,直至被控器完成操作并释放SCL线的控制控制权。这样以来,主控器实际上受到被控器的时钟同步控制。可见SCL线上的低电平是由时钟低电平最长的器件决定;高电平的时间由高电平时间最短的器件决定。这就是时钟同步,它解决了I2C总线的速度同步

 根据上面的描述,“时钟同步”与“总线仲裁”可以总结如下规律:
①主控器通过检测SCL上的电平来调节与从器件的速度同步问题——时钟同步;

②主控器通过检测SDA上自身发送的电平来判断是否发生总线“冲突”——总线仲裁。

因此,I2C总线的“时钟同步”与“总线仲裁”是靠器件自身接口的特殊结构得以实现的。

IIC通讯_编程世界093的博客-CSDN博客

当Master速度过快Slave端来不及处理时,Slave设备可以拉低SCL不放(SCL=0将发生“线与”)以阻止Master发送更多的数据。此时Master将视情况减慢或结束数据传送。

不同观点1:在第九个时钟之后

主机发送数据时,被发送方即主机拉低;主机接收数据时,被接收方即从机拉低

 不同观点2:

在第9个时钟之后,如果有某一方处于繁忙状态,它可以一直把SCL拉低当SCL为低电平时候,大家都不应该使用IIC总线,只有当SCL从低电平变为高电平的时候,IIC总线才能被使用。

不同观点3:

在第九个CLK,就会产生一个中断,在中断处理过程中SCL被拉为低电平,谁都不能再使用IIC总线,等待中断处理完成.

重点: 发生中断时,我们的IIC控制器=IICCON寄存器会把SCL拉低,阻止任何设备再使用IIC总线,清中断之后才能继续使用,这种机制就给我们中断服务程序的执行提供了时间。

IICCON寄存器(Multi-masterIIC-buscontrol)
IICCON寄存器用于控制是否发出ACK信号、设置发送器的时钟、开启,i2c中断,并标识中断是否发生。它的各位含义如表:

//----------------------------------------

补充@201108311142

SDA和SCL已经通过上拉电阻被上拉,master可以控制(拉低或者释放)这两条线,而slaver只能控制SDA线。当master发送数据时,master会适时地将SDA和SCL拉低或释放(拉高)。确切的时序应该是这样的:

当mater要发送一个start时,mater会将SDA拉低,这就可以了,因为此时的SCL一定是High。好了,一个start就这样发出去了。而slaver也会发现这个start信号的发生,slaver便会准备好接收接下来的数据了。紧接着,master要发送一个Byte的数据了,一位一位的发出这8个bits。这时master会先将SCL拉低,然后在SCL为低的状态下将一个bit准备好放到SDA上(比如要发送一个 0,master就会通过拉低SDA来放好这个0),然后master会把SCL拉高(释放),此时slaver会立刻检测到SCL的变化,由此聪明的slaver便知道master已经将要发送的那个bit准备好了,slaver便会在这个SCL的高电平期间尽快(maser不会等你很久的哦)去读取一下SDA,嗯读到了一个0,slaver就把这个0放到自己的移位寄存器中待后续处理。master会在一个设定好的时间后把SCL再次拉低,然后在SCL为低电平期间把下一个bit放到SDA上,然后再把SCL拉高,然后slaver在SCL的高电平期间再去读SDA。。。。。如此反复8次,一个Byte的传输便告结束。当这8个bit发完后,SCL是处于低电平的(被master拉低的),SDA是出于高电平的(master已经释放了SDA)。

当一个字节发送完毕后,master会释放SDA(拉高)并拉低SCL,此时slaver如果打算发出一个ACK的话,它必须在这个SCL被master拉低的短暂时间内去主动将SDA拉低并保持住 (此前我们说过,SDA此时已经被master释放,所以slaver才有机会去拉低这个SDA)。master会在一个确定的时间后再次将SCL拉高,并在拉高的期间去读取SDA线的状态,如果读到低电平,则认为收到了来自slaver的响应(ACK),否则认为slaver没有响应(NACK)刚才发送的那一个Byte。这个过程就是我们说的i2c通讯中的第9个时钟周期。当master读完这个ACK / NACK 后,会再次将SCL拉低,用以通知slaver:第9个时钟周期已经结束,你现在可以释放SDA了。而此时master也可以向SDA上准备下一个Byte的第一个bit。继而重复上述过程。。。。。或者,master也许想在接下来发送一个stop过去,那么master会在这个SCL为低的时间内将SDA拉低,而后再将SCL拉高,在SCL为高的期间再将SDA释放 (拉高) 。这样,一个STOP位就产生了。你会发现此后的SDA和SCL都是高,这就是是所谓的总线空闲了!

一句话:SCL是单向的,由master控制。而SDA是双向的,master可以控制,slaver也可以控制。

Yasin Lee@201109091400

昨天在调试mma8452q的过程中发现一个新的问题:

我一直以为用i2c读取slaver的某个寄存器的过程是:1.向slaver写一个寄存器地址过去。2.读取slaver。就是这样两步,可是这样的想法在读取mma8452q时却出现了问题,总是无法读到正确的数据。上述两步我是通过这样的方法实现的:1.调用i2c_master_send发送一个字节的数据(寄存器地址)过去。2.调用i2c_master_recv读取一个字节。完毕。之所以这么做是基于这样的想法:当向slaver写入(发送)一个寄存器地址过去后,slaver就会把当前的读写指针(假想的)指向这个寄存器,此后,读取的时候自然是读到这个寄存器的值了。

可是这样的想法不行,考虑到,这个假设可能不对,我便直接使用i2c_transfer来进行操作,因为这个函数可以实现在由写入状态切换到读取状体的过程中不发送stop,也就是直接再次发送一个start,即Restart。

问题解决,看来对mma8452q的读取操作必须经由restart来做中间的切换。而不能在切换过程中发送stop命令。而先前采用的分部操作在每一步完成后都有一个i2c stop命令发生,所以出了问题。

I2C总线时序以及ACK和NACK(NAK)_Leo丶Fun的博客-CSDN博客_i2c nak

2、IIC 总线接口-详细介绍 

在第9个时钟之后,如果有某一方处于繁忙状态,它可以一直把SCL拉低当SCL为低电平时候,大家都不应该使用IIC总线,只有当SCL从低电平变为高电平的时候,IIC总线才能被使用。

 

3、详述I2C总线协议、时序,入门不再是难事 - 云+社区 - 腾讯云

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

I2C总线时序以及ACK和NACK(NAK),SCL被从机拉低? 的相关文章

  • scl sda 是什么接口_SOC设计控制接口IIC

    IIC全称为Inter Integrated Circuit 集成电路总线 IIC接口只有两根线 SCL SDA SCL为同步时钟线 SDA为数据线 通SPI不同的是 数据线为双向接口 也就是说 发送接收都走这根线 IIC是一种多向控制总线
  • STM32 HAL库IIC驱动

    1 STM32上IIC的一些争议 关于STM32的IIC驱动 xff0c 网上有很多争论 xff0c 究竟是使用STM32自带的硬件IIC还是用IO口和软件模拟IIC呢 xff1f 下面这个图形象展示了这些争论 总结一些 xff1a ST为
  • 试想面试官让你讲讲UART IIC SPI你能讲多少。

    试想面试官让你讲讲UART IIC SPI你能讲多少
  • PX4-5-SPI-IIC设备驱动

    在之前的分享中 xff0c 我们聊了PX4的通信框架和任务调度框架 xff0c 现在我们讲一下PX4的设备驱动 PX4支持很多种设备 xff0c 根据通信方式的不同大致分为 xff1a SPI IIC设备 串口设备 IO设备 CAN设备 这
  • 基于STM32平台的BMP180测试(模拟IIC)

    1 测试描述 xff1a 使用模拟IIC xff0c 从BMP180中获取ID号 温度值 气压值以及计算海拔高度 2 测试准备 xff1a 硬件平台 xff1a 原子战舰V3开发板 测试工具 xff1a 逻辑分析仪 串口调试工具 3 数据手
  • IIC总线最多可以挂多少个设备

    由IIC地址决定 xff0c 8位地址 xff0c 减去1位广播地址 xff0c 是7位地址 xff0c 2 7 61 128 xff0c 但是地址0x00不用 xff0c 那就是127个地址 xff0c 所以理论上可以挂127个从器件 但
  • DHT12温湿度传感器IIC,I2C接口调试心得和代码说明

    来源 xff1a http www fuhome net bbs forum php mod 61 viewthread amp tid 61 2141 DHT11那个单总线的温湿度传感器用的很多了 xff0c aosong推出了DHT12
  • STM32——硬件IIC从机通信

    前言 xff1a 根据网上的资料 xff0c 大部分网友表示STM32自带的硬件IIC存在bug xff0c 读写时很容易卡死 自己在调试的时候也出现卡死的情况 xff0c 最后一点一点调试 xff0c 也还是调通了 本文将记录自己调试ST
  • SYD8821 IIC模块使用说明

    SYD8821是具有全球领先低功耗 RX 2 4mA 64 94 5dBm灵敏度 xff0c TX 4 3mA 64 0dBm输出功率 的蓝牙低功耗SOC芯片 xff0c 在极低电流下实现了优异的射频性能 xff0c 搭配176kB SRA
  • IIC 驱动OLED

    IIC总线可以驱动很多器件 xff0c 比较常见的有OLED EEPROM存储器 xff08 AT24C02 xff09 温度传感器 xff08 LM75A xff09 温湿度传感器 xff08 DHT11 xff09 等 有关IIC总线协
  • STM32软件模拟iic驱动oled(显示汉字,图片)(一)

    一 iic驱动模式 1 硬件驱动 xff1a 所谓硬件驱动就是使用STM32板子上固定的iic接口 xff0c 但是由于板载iic数量有限 xff0c 且大多和别的外设有引脚复用 xff0c 在别的外设使用的情况下还得通过重映射引到别的引脚
  • UART、IIC、SPI、CAN通信的区别与应用

    文章目录 1 通信的基本知识1 1 数据通信的种类1 1 1 串行通信1 1 2 并行通信1 1 3 总结 1 2 数据通信的传输方向1 2 1 单工1 2 2 半双工1 2 3 全双工1 2 4 总结 1 3 数据通信的方式1 3 1 同
  • 通信协议详解(二):IIC总线协议(传输时序+数据格式+设计实现)

    文章目录 一 IIC xff08 Inter Integrated Circuit xff09 介绍二 传输协议1 时序传输时序写操作时序数据有效性开始 amp 结束信号从机应答信号 2 数据格式 三 设计实现1 时钟2 传输过程3 三态门
  • UART, IIC, SCI, SPI, 232, 485, 422, CAN, SDIO, GPIO, MODBUS, TCP/IP汇总简介

    UART IIC SCI SPI 232 485 422 CAN SDIO GPIO MODBUS TCP IP汇总简介 UART xff1a Universal Asynchronous Receiver Transmitter xff1
  • STM32标准库通用软件模拟IIC

    STM32标准库通用软件模拟IIC 继上次通用可移植的矩阵键盘之后 xff0c 便继续寻找着下一个能够拿来只需改改引脚就可以使用的通用方案 恰好最近在研究PCA9685 xff0c 这是一片能够产生最多十六路PWM信号的芯片 xff0c 通
  • AT24C02的使用说明和完整代码-51单片机

    AT24C02的使用说明和完整代码 51单片机 简述 at24c02为存储器芯片 可以使用单片机将数据存入其中 同时也可以任意读取 at24c02的原理及使用方法在其说明资料中已有充分的讲述 本篇仅对其使用的关键步骤进行罗列 以及说明一下具
  • I2C之知(四)--I2C总线的7bit从机地址 数据传输时序的详细过程

    时钟拉伸 Clock stretching clock stretching通过将SCL线拉低来暂停一个传输 直到释放SCL线为高电平 传输才继续进行 clock stretching是可选的 实际上大多数从设备不包括SCL驱动 所以它们不
  • 基于STM32 的IIC 模拟主机编写

    最近在学习STM32 的IIC IO 模拟主机方式 好像失败了 include myiic h include delay h MCU VERSION DATA 作者 other Function IIC
  • STM32 IIC通信干货!理论+实例

    I2C总线简介 I2C总线介绍 I2C Inter Integrated Circuit 总线 也称IIC或I2C 是由PHILIPS公司开发的两线式串行总线 用于连接微控制器及其外围设备 是微电子通信控制领域广泛采用的一种总线标准 它是同
  • I2C之知(三)--I2C总线的字节格式、时钟同步和仲裁

    字节格式 发送到SDA线上的每个字节必须是8位 每次传输的字节数量是不受限制的 每个字节后必须跟着一个ACK应答位 数据从最高有效位 MSB 开始传输 如果从机要执行一些功能后才能接收或者发送新的完整数据 比如说服务一个内部中断 那么它可以

随机推荐

  • React小技巧-React.memo useMemo useCallback

    React小技巧 React memo useMemo useCallback 原文 https piyushsinha tech series optimizing react ck subscriber id 1555690090 本文
  • TV服务器的安装维护和调试,广电机顶盒安装调试教程及系统设置密码

    QQ截图20160813140648 png 931 06 KB 下载次数 3 2016 8 13 14 43 上传 电视机与机顶盒正确连接后 打开电视机和机顶盒的电源开关 并按电视机遥控器的视频切换键 TV 切换到IPTV界面 第一步 进
  • Python可视化界面编程入门

    Python可视化界面编程入门具体实现代码如所示 1 普通可视化界面编程代码入门 import sys from PyQt5 QtWidgets import QWidget QApplication 导入两个类来进行程序界面编程 if n
  • leetcode 5 最长回文子串

    题目 给你一个字符串 s 找到 s 中最长的回文子串 如果字符串的反序与原始字符串相同 则该字符串称为回文字符串 示例 输入 s babad 输出 bab 解释 aba 同样是符合题意的答案 解析 这道题和之前的那道回文的很像 647回文子
  • Vue2.0教程

    一 Vue入门 1 概述 在众多的语言排名中 JavaScript 已经非常靠前 它是前端的核心编程语言 我们可以利用 js 开发 动态 效果的网页 也可以开发 app 为了简化 JavaScript 的使用 在其基础上 发展出两个门派 真
  • C++ 用两个栈实现一个队列

    首先我们要看看栈和队列的特点 栈的特点 先进后出 队列的特点 先进先出 队列的出队顺序与栈的出栈是相反的 我们把数据压入第一个栈 如果再把这个栈里面的元素依次压入第二个栈 此时栈2里面的元素的顺序 相当于对一组数据进行了两次倒序 此时对第二
  • python 的继承重写和 super函数

    1 super函数实现父类方法的继承和重写 class Car1 def init self color weight self color color self wheel 4 self weight weight self speed
  • 防止连接Mysql超时,JDBC探活配置

    我们知道Mysql有两个关于连接超时的参数 默认为8小时 MySQL gt show global variables like timeout wait timeout 28800 非交互连接等待时间 interactive timeou
  • php 检测用户名已存在错误,验证用户名时出现PHP错误

    我正在使用PHP构建一个网站 我需要验证用户输入的名称是否正确 由于JavaScript是客户端的 我不能完全依赖它 所以这是我的服务器端函数来验证用户名 function validate name name name trim name
  • Intellij IDEA安装YAML插件

    1 下载插件 http pan baidu com s 1nvgECTN 2 安装插件 Intellij IDEA File gt Settings gt Plugins gt Install plugin from disk gt 选择插
  • Mac下安装Metaspoit

    Mac下安装Metaspoit 在mac下安装的方式 1 先去官网上下载对应的dmg文件 想要不花钱的话就可以对应的去 下载社区版本的 连接 https osx metasploit com metasploitframework late
  • PhpStorm 上面的git集成用法

    phpStrom这个php的 IDE完美的集合了git 对于有些对命令行不是很熟悉的同学来说 这可以带来很大的帮助 下面我给大家说一下具体的用法 1 我们提交自己的代码 a 在我们的项目上 右击 如图所示 相当于 git add 这个大家都
  • 使用DS18B20模块的Arduino模拟温度计

    有时 我们需要在项目中添加一个温度指示器 因此 在本篇文章中 您将学习如何使用Arduino和DS18B20温度传感器制作一款模拟温度计 DS18B20模块 首先 Maxim DS18B20数字温度计提供9位至12位摄氏温度测量 并具有报警
  • linux机试题,智一面之荣耀机试题 2021.04 ~05

    记录下最近面试的算法题 题目记得不是特别清楚了 大致描述 一 2021 04 17荣耀机试 1 数组排序 题目描述 输入多个数字 按数字从小到大排序 输入描述 多个整数 保证都在int范围内 用空格隔开 输出描述 从小到大的值 用空格隔开
  • qt 带复选框的下拉列表

    参考 Qt之QComboBox定制 核心思想 void QComboBox setView QAbstractItemView itemView void QComboBox setModel QAbstractItemModel mode
  • pandas dataframe类型数据的反转(reverse)

    data iloc 1
  • 瀑布流实现的三种方法js jq css3

    一 样式 div div class box div class pic img src images 1 jpg div div div class box div class pic img src images 2 jpg div d
  • LeetCode 题解——岛屿数量

    大家好 我是前端西瓜哥 今天我们做一道经典算法题 岛屿数量 LeetCode 上对应题目为 200 题 https leetcode cn com problems number of islands 这道题归属于岛屿问题 是有固定套路的
  • selenium处理各类滑块验证码

    selenium处理各类滑块验证码 滑动验证码 案例展示 实现 滑块拼图验证码 案例展示 实现 滑块拼图验证码 Canvas 案例展示 实现 滑动验证码 案例展示 这种只要用鼠标点击并移动指定距离就可以完成验证 x轴 实现 coding u
  • I2C总线时序以及ACK和NACK(NAK),SCL被从机拉低?

    1 I2C协议详解及裸机程序分析 简书 通俗易懂 根据上图 我们首先设置IICCON 来设置时钟 时钟源是PCLK 是50MHZ 太快了我们需要设置这个分频系数 把时钟降低 降低到我们想要的SCL 然后我们要发出start信号 我们需要设置