来自:http://bbs.ednchina.com/BLOG_ARTICLE_2154168.HTM

I2C 总线在所有嵌入式系统中用得极广, 是一个工业级别的总线, 但由于STM32 是一个32位的MCU, 注定了他的I2C硬件接口将会功能强大, 但同时也会较难于控制,不象8位机,如AVR8位机的TWI(实际完全符合 I2C标准) 那么易用. 以下是我的STM32 I2C硬件接口编程的一些心得体会.

如果你选择了STM32, 说明了你的项目的需求是比较复杂的,使用EMBEDDED OS 和大量地运用中断+DMA的编程模型是必然的选择, 如果你的项目中用STM32,而你用模拟的I2C的话, 说明了两点: 一是浪费了STM32; 二, 如果你的项目很复杂的话,你会发现在项目的开发后期,好象STM32也比8位机快不了多少, WHY!! ,但这不是STM32的问题,而是你没有最有效地利用上STM32.

很多朋友在搞STM32的I2C接口编程时总是时不时“当在某处”(GOOGLE时你会发现这个问题很普遍), 一些朋友这时就会用软件来模拟I2C,然后,很快发现和I2C设备能很好地通信了(但当机还是可能随机出现), 这些朋友于是大骂STM32的I2C硬件接口是个”杯具”(呵呵,我有时也会突然想骂骂,但我知道,99.999%的原因还是自已对于STM32硬件接口的熟悉程度不够,或者说,是我没有扬STM32 I2C的长,而总是捉住他的短不发。)。

固然,STM32 I2C硬件接口有设计不完善的地方,例如下面就是我从STM32最新的Errata sheet中总结出的,关于STM32 I2C接口设计上的一些缺陷和如何避开这些缺陷的推荐程序模型:

(1)把I2C的中断优先级提升到最高

(2)把发送多于2个字节的发送与接收封装成利用DMA收发的函数,而把对某I2C设备接收和发送一个字节的函数单独封装为一个POLLING (轮询)函数。

(3)在寻址某一I2C DEVICE时要先CHECK I2C BUS 是否BUSY,如果忙,则等待指定时间,如果还是忙就说明I2C BUS 挂了(原因99.9%是由于我们的I2C通信时序并不十分尊守I2C规约,或者我们所封装的I2C通信模块没有加上防守代码(出错恢复代码)),这时要调用一个专门的用于通知 I2C BUS上的所有device,让他们结束当前内部的工作,重新准备好(下雨了,收衣服啦)。如下面的我的I2C模块的FUN 切片:

该函数一定要用在主MCU的启动模块上,因为I2C总线在充当Master的MCU启动时,SDA和SCL有可能组合出刚好符合I2C规约的时序组合,比如一个开始位(START CONDITION),使得I2C BUS 立即当在那里(因为当主MCU真正需要发出一个START CONDITION时,发现I2C BUS 正处于BUS状态,而根据STM32 手册的START CONDITION说明可知,一个起始条件将会使得I2C BUS处于BUSY 状态, 下面的I2C2_Free_Buf fun 的基本用法:

(注: I2C2_Free_Bus Fun 应放在线程中,而不是放在上图中的位置,这样会触发并进入一个硬件错误处理向量中断中)

提示:摘自STM32 手册:
    I2C.SR1.Bit 0 位(SB)- Start bit(Master mode)
    - Set when a Start condition generated.
    - Cleared by software by reading the SR1 register followed by writing the DR register, or by hardware when PE=0.

(4) 不要让I2C工作在88KHz的频率上,低于或者使用Fast-mode(400KHz)频率,这是STM32 I2C真正的一个硬件BUG(99.999%机率),但是也是可以编程避免的。

(5)Programming the bit NOSTRETCH=0  in the I2C_CR1 register. 这样也可避免一个STM32 I2C硬件设计的一个小BUG(2。9。5节)

(6)大部分的MCU的硬件I2C接口的工作模式是中断(高端的会用DMA)+状态机;因此状态机的编程概念要熟悉

(7)STM32 I2C的硬件接口负责实现满足I2C总线的的规约,而我们(嵌入式编程开发者)则是通过I2C 控制寄存器和I2C的事件标志组合来启动状态机,然后让状态机按照由I2C SR1 和SR2所组合志来的事件自动工作,并在发送或接收完成后通过FLAG的方式或信号量的方式通知我们所写的读写函数,操作已经完成,或者在操作中出现了错误,如最常见的AF错误(device 在第9位上没有拉低SDA应答Master。)

(8)I2C SR1 和SR2的功能分配(这是一个极易忽视的思考死角)

从STM32 手册的I2C register map 中可以看到, I2C的SR1,主要是反映I2C通信的最基本的标志,要清除SR1的某个标志可以直接清除,而I2C的SR2即是辅助SR1的,他一般反映了I2C总一当前的工作状态,如BUSY,是主机模式还是从机模式,等等。关于SR2的很重要的一个编程模型是:要清除SR1的某些指定的标志位时,比如ADDR,先读SR1然后再读SR2将会清除掉已置位的ADDR。

(9)Master在操作slave device时要先和他握一下手是很好的防守编程模型:

 
 

STM32 I2C 难点---这个不错,留着慢慢研究的更多相关文章

  1. art中的部分内容,留着慢慢研究

    root@hbg:/tmp# cat /proc/mtddev:    size   erasesize  namemtd0: 00040000 00010000 "u-boot" ...

  2. STM32 I2C

    STM32 I2C 搞了几天了,比较郁闷,写点东西给那些正在郁闷的同志 // 好使的,也是范例的代码 cnt = TIME_OUT; while (cnt-- && !I2C_Chec ...

  3. STM32 i2c通讯失败复位方法

    最近在调研STM32 F10X,准备把公司AVR的MCU项目迁移到STM32上.在调研STM32 i2c这一部分时,在与i2c slave硬件连接断开后,这时再去读/写 i2c slave需要STM3 ...

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

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

  5. STM32应用实例十:简析STM32 I2C通讯死锁问题

    I2C接口是一种使用非常普遍的MCU与外部设备的接口方式,在STM32中也集成了I2C接口,我们也常常使用它来与外围的传感器等设备通讯. 最近在我们使用STM32F1VET6读取压力和温湿度传感器数据 ...

  6. loading 动画效果(收藏起来以后留着慢慢用)

    动画效果一: html代码: <div class="spinner">   <div class="rect1"></div&g ...

  7. python的subprocess模块(写的不错留作查询)

    python的subprocess模块 subprocess模块是python从2.4版本开始引入的模块.主要用来取代 一些旧的模块方法,如os.system.os.spawn*.os.popen*. ...

  8. stm32 i2c eeprom 24C02

    电路图 相关文章:http://blog.csdn.net/zhangxuechao_/article/details/74936798 举例 #define i2c_scl PBout(10) #d ...

  9. STM32 的系统滴答定时器( Systick) 彻底研究解读

    作者:王健 前言 SysTick 比起那些 TIM 定时器可以说简单多啦~~~~~哥的心情也好了不少, 嘎嘎!! ARM Cortex-M3 内核的处理器内部包含了一个 SysTick 定时器,它是一 ...

随机推荐

  1. Windows 10更新后无法启动Dolby音频驱动程序

    在电脑更新Windows 10 1903版本后,重启出现如下问题: 经查,这与驱动强制签名有关.解决方法如下: 打开"设置"->"更新与安全"->& ...

  2. Pycharm 修改项目名称后 中括号中出现先前名称怎么解决?

    这时候,你打开工程的路径,会找到一个隐藏文件, .idea  目录删掉他,重新导入Pycharm 就行了. idea记录了一些工程项目信息. 步骤: 1.退出当前工程 2.打开工程路径删除.ideal ...

  3. 本地SVN服务器的搭建(WINDOWS环境)

    1.下载安装 VISUALSVN SERVER 1.1下载地址:https://www.visualsvn.com/server/download/ 1.2下载完成后,双击安装. 2.下载安装 Tor ...

  4. 从零开始学编程_第A001期_C语言HelloWorld详解

    emmm,这是我的第一篇博客. 作为一个软件工程专业的学生,我希望自己能在编程方面有不错的成就,我们老师告诉我们学编程就要写博客,在写博客的过程中不断成长,结交朋友,所以我就开始尝试写专业相关的博客. ...

  5. vue自定义指令获取焦点及过滤器修改时间

    <template id="comp3"> <div id="app"> <model :list="selectedl ...

  6. Java虚拟机——类加载机制

    转自:http://blog.csdn.net/ns_code/article/details/17881581 类加载过程 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载 ...

  7. 22pygame 安装

    实战步骤 pygame 快速体验 飞机大战 实战 确认模块 --pygame pygame 就是一个 Python 模块, 专为电子游戏设计 提示 : 学习第三方模块, 通常最好的参考资料就在官方网站 ...

  8. rabbit-c编译 vs2013

    需要openssl的库

  9. F1函数csdn 是否支持版本

    https://docs.microsoft.com/zh-cn/windows/desktop/api/winsock2/nf-winsock2-wsaioctl

  10. W3C 事件切换 颜色变化

    颜色变化代码: HTML: <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...