时钟拉伸(Clock stretching)

clock stretching通过将SCL线拉低来暂停一个传输.直到释放SCL线为高电平,传输才继续进行.clock stretching是可选的,实际上大多数从设备不包括SCL驱动,所以它们不能stretch时钟.

链接是IIC标准官网说明http://www.i2c-bus.org/clock-stretching/,贴到这里

Clock Stretching

In an I2C communication, the master device determines the clock speed. Unlike RS232 the I2C bus provides an explicit clock signal which relieves master and slave from synchronizing exactly to a predefined baud rate.

However, there are situations where an I2C slave is not able to co-operate with the clock speed given by the master and needs to slow down a little. This is done by a mechanism referred to as clock stretching.

An I2C slave is allowed to hold down the clock if it needs to reduce the bus speed. The master, on the other hand, is required to read back the clock signal after releasing it to the high state and wait until the line has actually gone high.

Bandwith

Clock stretching sounds a bit odd but is common practice. However, the total bandwidth of the shared bus might be significantly decreased. So, especially for I2C buses shared by multiple devices, it is important to estimate the impacts of clock stretching. So do not make the slowest I2C device dominate your bus performance.

Clock Stretching in High Speed Mode

Clock stretching in High-Speed-Mode is only allowed after the ACK bit (and before the 1st bit of the next byte). Stretching between bits 2-9 is illegal because the edges of these bits are boosted with an additional current source. See I2C specification Rev. 03 chapter 5.3.1 for further details.

本人具体遇到的情况是从设备有Clock stretching功能,在调试DS90ub913与DS90ub914通过模拟IIC与DZ60通信事,914可是正常读写,而913不可以正常读写,换作DZ60硬件IIC却可以正常通信,最后在查找913规格书是才发现Clock Stretching问题,而之前本人没遇到过,还以为是硬件出了问题,实际就是从设备在高速模式下在应答位将clk时钟拉低,通知主设备等待,等从设备释放时钟后,主设备可继续发送命令。

现象(如下图):

由于在发送读命令之后,即ACk之后,下面从设备需要准备数据时间,(大约10us,一个时钟的时间),此时还在I2C中断中,因此SCLK上是被拉低。由于主设备,并未检查该SCLK信号,导致下一个数据的第一个时钟信号被拉低,而不知道,而当做有效信号采样,结果导致数据采用出错;我们自己的主设备,采用硬件I2C,有判断总线是否占用和超时机制,故没有这个问题。

I2C的时钟可能被从设备拉低,从示波器看好像主少发了时钟(只有8个时钟,实际应该9个,最前面一个被从设备拉低了),实际是从设备拉低,这时候主设备最好检查时钟信号变高后,再发时钟信号脉冲!

(还在调试爱立信电源PMBUS问题:主发第九个时钟未检查总线,此时从设备把SCL拉低《此时从设备正在做相应数据处理,所以拉低总线》,导致ACK应答失败,从示波器看好像少发了第九时钟;方法发第九个时钟的时候检查SCL电平,发现它变高后,才发第九个时钟)

原因:通信中,从设备由于某种原因(数据处理或准备)拉低SCL时钟线(此时总线属于被占用状态),而主设备并未判断SCL的是否为高空闲,而继续通信,导致失败

解决方法:在通信中,要随时检查SCL电平,当它为低的时候,需要超时等待,等它为高时候,再发新的SCL信号

(即在代码中,主设置SCL为高后,要超时判断SCL是否为高,再发后面的时序)

具体可以在主机应答位检查子程序中进行程序的完善实现Clock Stretching功能;操作如下面红色标注:

//--------------------------------------------------------------------------------------------------  
// 函数名称: check_ACK  
// 函数功能: 主机应答位检查子程序,迫使数据传输过程结束  
//--------------------------------------------------------------------------------------------------

int8u iic1_check_ACK(void)  
{   
    int8u check;
    int16u ucErrTime=0;
    SDA1 = 1;
    DelayUS(2);
    SCL1 = 1;
 /*****************************************添加部分*********************************************/ 
    DelayUS(10);
    while(0 == SCL1) //用于检测SCL stretch 需要将检测引脚与SCL短接
    {
      ucErrTime++;
      DelayUS(1);
      if(ucErrTime>1000)
      {
        ucErrTime = 0;
        break;
      }
    }
    DelayUS(10);
 /****************************************添加部分**********************************************/
    SDA1_Dir = 0;   //SDA设置为输入端口
    DelayUS(3);     //延时3us
    check = 0;
    if(SDA1 == 1)   // 若SDA1==1 表明非应答
      check = 1;
    SCL1 = 0;
    DelayUS(2);
    SDA1_Dir = 1;
    return check;   
}

另:个人认为硬件i2c有总线占用和超时判断,相对于模拟i2c更好; 但硬件i2c容易出现死锁的问题

模拟IIC的时钟延展问题(Clock Stretching)相关推荐

  1. IIC 关于时钟拉伸问题 clock stretch

    转载请标明出处 时钟拉伸(Clock stretching) clock stretching通过将SCL线拉低来暂停一个传输.直到释放SCL线为高电平,传输才继续进行.clock stretchin ...

  2. 0.96寸OLED显示屏标准库移植HAL库(模拟IIC) - 基于STM32

    ** 0.96寸OLED显示屏标准库移植HAL库,使用模拟IIC ** 由于项目的需要使用OLED屏显示,并且现有的项目程序是基于HAL库编写的,而手头能找到的程序是标准库的驱动程序,大概看了一下代码 ...

  3. STM32实现0.96寸OLED显示模拟IIC和IIC四种实现(标准库和HAL库)

    目录 本文通过四种方法实现OLED显示 设备选择 OLED介绍 接线表设计 OLED应用 1.标准库模拟IIC实现OLED显示 2.标准库IIC实现OLED显示 3.HAL库模拟IIC实现OLED显示 ...

  4. STM32 软件模拟 IIC 代码,标准库、HAL库可用

    1 #ifndef _IIC_H 2 #define _IIC_H 3 4 #include "stdio.h" 5 #include "stm32f1xx_hal.h& ...

  5. 【STM32】IIC的基本原理(实例:普通IO口模拟IIC时序读取24C02)(转载)

    版权声明:本文为博主原创文章,允许转载,但希望标注转载来源. https://blog.csdn.net/qq_38410730/article/details/80312357 IIC的基本介绍 I ...

  6. MSP430杂谈--AD7745硬件IIC驱动与模拟IIC驱动

    和上一篇AD7793类似,项目中也涉及到利用AD7745读取电容值,来测环境湿度.编写了基于MSP430的AD7745的硬件IIC驱动和模拟IIC驱动,分享给大家. AD7745硬件IIC驱动完整版下 ...

  7. 模拟IIC——关于模拟IIC的IO口的配置选取推挽输出还是开漏输出,以及是否需要更改IO口输入输出模式和是否需要对IO配置上拉

    在使用模拟IIC的时候,观看别人的程序的时候发现了程序之间的一些不一样的地方 ----------------------------------代码1------------------------ ...

  8. STM32模拟IIC读取PCF8563

    作者第一次开写博客,本着学习的态度,附上自己总结的代码,希望大家多多指点! 一.首先是对于PCF8563芯片的介绍与使用说明: PCF8563 是PHILIPS 公司推出的一款工业级内含I2C 总线接 ...

  9. STM32 Cube MX 之hal库软件模拟IIC 可直接移植使用

    此为软件模拟IIC,可以直接移植到HAL库使用..h文件需要自己做函数声明这里就不再放出,如有问题大家可以讨论. 使用的时候只需要更改SDA 和SCL引脚的宏定义就可以移植使用,当然IIC协议其实就是 ...

最新文章

  1. 一篇文章搞定大规模容器平台生产落地十大实践
  2. 一个运维老将的自我修养
  3. python树莓派串口通信实例_树莓派通过串口发送数据
  4. 39个工具,120种组合深度评估 (转录组分析工具哪家强)
  5. 从零开始学习springBoot(Contextpath+修改默认idk)
  6. 配置Hibernate二级缓存步骤
  7. uni-app H5跨域问题解决方案(CORS、Cross-Origin) VUE axios 跨域问题 No ‘Access-Control-Allow-Origin‘ header is pres
  8. ubuntu下编译安卓7.0源码
  9. 访问自己的网站有病毒提示,为什么?
  10. 关于vue-axios的使用及跨域问题的解决
  11. 图:用PPT为湖北黄石某电视台及其有线电视定制的知识竞赛题库
  12. php个人资料表单显示,php-如何显示用户从表单构建器中选择的带...
  13. CnCerT.Net.SKiller工作原理
  14. win7怎么设置开机密码_主编教您电脑开机密码怎么设置
  15. java 中如何检测异常_如何检测Java中何时全局抛出了异常?
  16. 天池大数据《快来一起挖掘幸福感!》项目第169名
  17. 2023年PHP常见中高面试题汇总(持续更新)
  18. 大数相乘(数组表示)
  19. 带你玩转IntelliJ IDEA操作手册
  20. k8s ingress yml 浅薄理解

热门文章

  1. 了解常用音频接口,看这篇全了!
  2. bwapp靶场笔记 -SQL注入篇
  3. 上岸后分享:SELECT查询解题思路(尤其是不同多表查询对比) 力荐力荐力荐
  4. jupyter安装后Nbextensions不显示内容
  5. eclipse的搜索快捷键
  6. 超级计算机多少钱100万,超级计算机的100万亿倍!中国量子计算机“九章”为何这么快?...
  7. Java代码小片段(二)
  8. SHA1算法的编程实现
  9. 多线程编程——prctl()函数介绍
  10. CSS实现可以旋转的两面图像