野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 28291|回复: 5

STM32的硬件I2C有什么问题?

[复制链接]
发表于 2014-3-10 13:15:59 | 显示全部楼层 |阅读模式
STM32的硬件I2C很多人都对它望而却步。因为很多电工都说,STM32 硬件 I2C有BUG、不稳定、死机等等……最后都使用GPIO模拟I2C。
STM32的硬件I2C有什么问题? 如何避免?
回复

使用道具 举报

发表于 2014-3-10 13:17:14 | 显示全部楼层
据说是必须把iic的中断优先级设置到最高级,不然时序会被其它中断打乱导致通讯出错
回复 支持 反对

使用道具 举报

发表于 2014-3-10 15:55:32 | 显示全部楼层
郑倚云 发表于 2014-3-10 13:17
据说是必须把iic的中断优先级设置到最高级,不然时序会被其它中断打乱导致通讯出错

中断影响I2C的时序么?

I2C的时序由硬件实现的吧,不由CPU产生的,中不中断对它有什么影响?

中断是为了快点接收数据吧,就算不用中断接收得慢,也会由硬件把SCL持续拉低(或者是拉高 忘了),来延迟后续操作,等你读完了才释放SCL的~

个人感觉不是因为中断的问题。

每个芯片都有自己的BUG,多数是由于硬件造成的吧。

这一问题得查证ST的勘误表那些资料。期待火哥或者山外大哥给个答复呢~
回复 支持 反对

使用道具 举报

发表于 2014-3-10 16:02:23 | 显示全部楼层
yinhao 发表于 2014-3-10 15:55
中断影响I2C的时序么?

I2C的时序由硬件实现的吧,不由CPU产生的,中不中断对它有什么影响?

ST说了要用硬件IIC就要把IIC的中断优先调到最高
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-10 17:02:04 | 显示全部楼层
本帖最后由 Flyheart 于 2014-3-10 17:09 编辑
yinhao 发表于 2014-3-10 15:55
中断影响I2C的时序么?

I2C的时序由硬件实现的吧,不由CPU产生的,中不中断对它有什么影响?



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 切片:

1.png
该函数一定要用在主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 的基本用法:

2.png

(注: 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时要先和他握一下手是很好的防守编程模型:

3.png


回复 支持 反对

使用道具 举报

发表于 2014-3-13 22:05:40 | 显示全部楼层
Flyheart 发表于 2014-3-10 17:02
  • 网上搜到一篇文章是这么讲的,感觉好复杂。。。
  • 下文来自:http://bbs.ednchina.com/BLOG_ARTICL ...

  • 学习了~

    据说是st为了规避专利,所以它的硬件iic有点特别,然后官方为了解决用户使用硬件iic的问题,专门做了一个iic的范例库,那时有下载来看过,不过没有深入研究。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

    GMT+8, 2024-6-2 01:36 , Processed in 0.040829 second(s), 26 queries , Gzip On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表