I2C接口是一种使用非常普遍的MCU与外部设备的接口方式,在STM32中也集成了I2C接口,我们也常常使用它来与外围的传感器等设备通讯。

最近在我们使用STM32F1VET6读取压力和温湿度传感器数据时,就是使用I2C接口来实现通讯的。但在使用I2C和STM32F1的标准库读取数据时出现了死机的现象。其现象是这样的,程序可以顺利的运行,但I2C没有数据返回。用示波器查看波形时,发现SCL的电平时钟为高,而SDA的电平时钟为低。如果拔掉对应的设备,SCL的波形则恢复正常。接上设备恢复正常,但运行一会现象依旧。

一开始以为是连接的设备有问题,于是换了一台设备,发现依旧如此。难道真的是I2C出现了死锁现象。那我们看看究竟怎么样的情况下I2C才会发生死锁现象呢?

在I2C主设备进行读写操作的过程中,主设备在开始信号后控制SCL产生8个时钟脉冲,然后拉低SCL信号为低电平,在这个时候,从设备输出应答信号,将SDA信号拉为低电平。如果这个时候主设备异常复位,SCL就会被释放为高电平。此时,如果从设备没有复位,就会继续I2C的应答,将SDA一直拉为低电平,直到SCL变为低电平,才会结束应答信号。而对于I2C主设备来说.复位后检测SCL和SDA信号,如果发现SDA信号为低电平,则会认为I2C总线被占用,会一直等待SCL和SDA信号变为高电平。这样,I2C主设备等待从设备释放SDA信号,而同时I2C从设备又在等待主设备将SCL信号拉低以释放应答信号,两者相互等待,I2C总线进人一种死锁状态。同样,当I2C进行读操作,I2C从设备应答后输出数据,如果在这个时刻I2C主设备异常复位而此时I2C从设备输出的数据位正好为0,也会导致I2C总线进入死锁状态。

既然判断了是I2C出现了死锁,那我们有什么办法解决了?网上有不少高手提供了多种的解决方案。当然有些方法实现起来不那么容易,因为我们的硬件已经确定,软件业已经编好,做很大的改变是不现实的。

所以我选择在出现死锁时将I2C接口重新配置,并且将对应的GPIO端口配置为输出,并将电位拉高,然后再冲新配置I2C端口,但现象并未消除。于是我们将I2C的时钟也重新使能现象消除。这种不断重置I2C接口的方法虽然能够使得在死锁时能够恢复使用,但不停地解除和配置接口总是感觉并那么理想。

在我们的试验中我们发现,可以从软件和硬件的角度来解决这一问题。首先我们来说下软件方法:在I2C主设备中增加I2C总线恢复程序。每次I2C主设备复位后,如果检测到SDA数据线被拉低,则控制I2C中的SCL时钟线产生9个时钟脉冲(针对8位数据的情况),这样I2C从设备就可以完成被挂起的读操作,从死锁状态中恢复过来。这种方法有很大的局限性,因为大部分主设备的I2C模块由内置的硬件电路来实现,软件并不能够直接控制SCL信号模拟产生需要时钟脉冲。其次我们说一下硬件方式:如硬件尚可修改,可以增加一个额外的总线恢复设备或者串入一个具有死锁恢复的I2C缓冲器都可以从硬件上解决这个问题。其实我们发现用GPIO模拟I2C通讯时,死锁现象是不会出现的。所以如果硬件不能改变,但软件容易改变时,我们可以考虑使用GPIO来模拟I2C通讯。

STM32应用实例十:简析STM32 I2C通讯死锁问题的更多相关文章

  1. STM32应用实例十五:STM32的ADC通道间干扰的问题

    最近我们在开发一个项目时,用到了MCU自带的ADC,在调试过程中发现通道之间村在相互干扰的问题.以前其实也用过好几次,但要求都不高所以没有太关注,此次因为物理量的量程较大,所以看到了变化. 首先来说明 ...

  2. STM32应用实例十四:利用光敏二极管实现光度测量

    最近我们在开发臭氧发生器时,需要监测生成的臭氧的浓度,于是想到使用光度计来测量.因为不同浓度的臭氧对管的吸收作用是不相同的,于是检测光照强度的变化就可以得到相应的浓度数据. 1.硬件设计 此次光照度检 ...

  3. WinForm 自动完成控件实例代码简析

    在Web的应用方面有js的插件实现自动完成(或叫智能提示)功能,但在WinForm窗体应用方面就没那么好了. TextBox控件本身是提供了一个自动提示功能,只要用上这三个属性: AutoComple ...

  4. STM32应用实例六:与MS5837压力传感器的I2C通讯

    MS5837压力传感器是一种可用于电路板上,适用于检测10-1200mbar压力范围的传感器,灵敏度非常高,理论上能够检测到0.01mbar的压力变化,实际使用过程中测试并无明显的变化. MS5837 ...

  5. 解决STM32 I2C接口死锁在BUSY状态的方法讨论

    关于STM32的I2C接口死锁在BUSY状态无法恢复的现象,网上已有很多讨论,看早几年比较老的贴子,有人提到复位MCU也无法恢复.只有断电才行的状况,那可是相当严重的问题.类似复位也无法恢复的情况是存 ...

  6. 功能强大的图片截取修剪神器:Android SimpleCropView及其实例代码重用简析(转)

    功能强大的图片截取修剪神器:Android SimpleCropView及其实例代码重用简析 SimpleCropView是github上第一个第三方开源的图片修剪截取利器,功能强大,设计良好.我个人 ...

  7. Linux VFS机制简析(一)

    Linux VFS机制简析(一) 本文主要基于Linux内核文档,简单分析Linux VFS机制,以期对编写新的内核文件系统(通常是给分布式文件系统编写内核客户端)的场景有所帮助. 个人渊源 切入正文 ...

  8. Android 启动过程简析

    首先我们先来看android构架图: android系统是构建在linux系统上面的. 所以android设备启动经历3个过程. Boot Loader,Linux Kernel & Andr ...

  9. [转载] Thrift原理简析(JAVA)

    转载自http://shift-alt-ctrl.iteye.com/blog/1987416 Apache Thrift是一个跨语言的服务框架,本质上为RPC,同时具有序列化.发序列化机制:当我们开 ...

随机推荐

  1. SQL Server 关于CROSS APPLY 和 OUTER APPLY应用

    先看看语法: <left_table_expression>  {cross|outer} apply<right_table_expression> 再让我们了解一下appl ...

  2. 修改Linux Operating System的时间与时区

    修改Linux Operating System的时间与时区 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 有的小伙伴可能会遇到安装了linux系统后,尽管时区选择正确,也会发现系 ...

  3. Scala进阶之路-Spark底层通信小案例

    Scala进阶之路-Spark底层通信小案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Spark Master和worker通信过程简介 1>.Worker会向ma ...

  4. JavaEE学习总结(十六)— Servlet

    一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向 ...

  5. 设计模式---组件协作模式之观察者模式(Observer)

    一:概念 Observer模式的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态 Observer模式提供给关联对象一种同步通信的手段,使得某个对象与依赖他的其他对象之间保 ...

  6. windows 查看链接数

    windows 端口链接数  查看有效 链接数: netstat -an|find " |find "ESTABLISHED" /c /c 统计: 查看链接信息: 查看当 ...

  7. JavaScript之DOM等级概述

    这两日对DOM等级的理解不是太通透,就进Mozilla官网去看了一下,然后进行了首次的对技术文档的翻译工作,虽然官网也有中文解释,但我想,自己翻译出来时,已经有了原汁原味的理解了吧,这边是做此次翻译的 ...

  8. Java 的NIO 3个主要概念 Channel、Buffer、Selector

    Java 的NIO 3个主要概念 Channel.Buffer.Selector,为何提高了性能

  9. proxysql 系列 ~ 总揽概括

    一 简介: proxysql相关知识汇总 二 proxysql 相关报错    1 proxysql 报错 too many connections     分析 proxysql关于连接池的参数  ...

  10. JXL导出Excel(只支持xls版本)——(一)

    注意: 导出的后缀是xls可以直接打开,如果导出的后缀是xlsx打开报错,需要手动将名字改为xls才可以打开.也就是JXL不可以导出xlsx的excel. Jar包