stm32 i2c例程 io如何设置 接不接上拉电阻

当前位置: >>
STM32 I2C 接口进入 Busy 状态不能退出
I2C 接口进入 Busy 状态不能退出问题:该问题由某客户提出,发生在 STM32F103VDT6 器件上。据其工程师讲述:在其产品设计中,使用了 STM32 的一个 I2C 接口与一个 EEPROM 通信。在系统靠性测试中发现,经过长时间运行后, STM32 会 出现不能读写 EEPROM 的现象。通过 NRST 管脚对 STM32 进行复位,复位后该现象依旧存在。关掉电 源,然后重新上电,现象消失。通过进一步测试发现,如果对 STM32 反复做复位操作,会很容易复现 这一现象。调研:修改软件,通过打印监控 I C 通信程序的流程,及 I2C 接口的各个寄存器的状态。当出 现上述现象时,I C 接口的状态寄存器 SR2 中的 Busy 位置‘1’,状态寄存器 SR1 中的 ARLO 位置‘1’。用示波器观察 I2C 总线,发现其 SCL 为高电平,SDA 为低电平。将 STM32 的复位脚拉到地,SCL 及 SDA 的状态不变。检查原理图,确认 I C 总线上只有 STM32 和 EEPROM 两颗器件。2 2 2结论:EEPROM 驱动 I2C 总线进入了非空闲状态,使得 STM32 在接管总线时发生总线仲裁失败,进而失去对总 线的控制,无法启动数据的传输。EEPROM 的这种状态可能是通信被意外中断造成的。通过对 STM32 进行复位而重现这一现象,在一定程度上吻合了这种猜测。但没有实验和理论依据证实一定是该原因 导致了这一问题,是否还有其它原因在起作用,不得而知。处理:修改软件,加入对 I2C 总线修复的功能。在每次发送起始条件之前首先检测 SR2 中 Busy 位,如果为 ‘1’,则说明总线上有异常。此时,可由 GPIO 的 OD 模式代替 I2C 通信口接管 SCL 及 SDA 两个管 脚。通过翻转 GPIO,向 SCL 信号线上发高电平脉冲,脉冲宽度及间隔匀为 10uS。每发出一个脉冲之 后,检测 SDA 信号是否为高电平。若 SDA 信号为已高电平,则将 SCL 拉高,然后向 SDA 信号线发 出一个 10uS 宽的低电平脉冲。然后将 SCL 及 SDA 两个管脚交还给 I2C 接口,并通过将 CR1 中的 SWRST 位置‘1’后再清‘0’来复位 I2C 接口,使其退出 Busy 状态。如图(一)所示: A:将 SCL 和 SDA 切换成 GPIO 的 OD 模式; B:发送时钟脉冲并等待 SDA 跳变到高电平; C:在 SDA 上发出一个低电平脉冲; D:在 SDA 拉高后,将 SCL 的 SDA 切换回 I2C 接口; 2 E:通过 CR1 中的 SWRST 位复位 I C 接口;建议:STM32 中的 I2C 接口被设计成为主从自适应接口,并充许多个主机共享一条 I2C 总线。I2C 接口在被使 能之后,会不断的检测 SCL 及 SDA 的电平与跳变。当发现有低脉冲出现在 SCL 或 SDA 上时,则认 为总线进入了 Busy 状态,其 Busy 标志会置‘1’,直到在总线上检测到一个符合要的停止条件之 后,才认为总线回到了空闲状态,这时由硬件清除 Busy 标志。当 I2C 接口认为总处于 Busy 状态且不 是由自己占用时,会拒绝向总线上发送信号,因为它认为此刻 I2C 总线正在被其它的主机所使用。这时 向 I C 接口发命令,要求产生起始条件,会导致总线仲裁失败。要从这种状态退出,首先要保证总线是 处于空闲状态,即 SCL 和 SDA 都为高电平。然后,通过将 CR1 的 SWRST 置‘1’然后清‘0’来复 位 I2C 接口,以达到清除 Busy 标志回到空闲状态目的。2
FSMC 只是打开了 FSMC 的时钟也会影响 I2C1 的...STM32 I2C 硬件接口有设计不完善的地方, 例如下面就...他一般反映 了 I2C 总一当前的工作状态,如 BUSY,...从主设备发出 START 位开始,总线进入通信状态(BUSY@...这样的话,再想进 行 I2C 通信,则不能成功。 [...STM32 I2C 封装库(添加中... 11页 免费
STM32...一个稳定可靠的STM32 I2C程序_电子/电路_工程科技_...(RegisterLen - 1); /* Wait for the busy ...关闭 ...BUSY 的状态,也就是网上问得最多的关于 I2C 的问题-I2C 总线 TMD 的怎么会...而把 stm32f10x_i2c.c 加入到项目中,使得 DEBUG 时能进入到 I2C_CheckEvent...STM32F0系列软件模拟i2c接口_计算机软件及应用_IT/计算机_专业资料。基于STM32...关闭 ...STM32F4 IIC的一些使用经验_计算机硬件及网络_IT/计算机...(I2C1, I2C_FLAG_BUSY)); I2C_AcknowledgeConfig(...读写接口函数 USB/HID 设备报告描述符详解 Delphi...ENABLE); } 至此,STM32 已配置完毕,其实不是那么...-& 发送 MPU6050 地址、状态(写)-& 写地址成功?...busy */ while(I2C_GetFlagStatus(I2C1, I2C_...STM32 I2C_电子/电路_工程科技_专业资料。I2C 基于...高电平时保持稳定,数据线电平状态只能在时钟线为低...4MHz 1) 发送起始条件 当总线空闲(BUSY=0)时; ...基于I2C总线设计_教学案例/设计_教学研究_教育专区。...main.c/i2c_ee.c/stm32f10x_it.c Main.c ...(I2C1, I2C_FLAG_BUSY)); I2C_GenerateSTART(I2C...嵌入式课程设计报告stm32_信息与通信_工程科技_专业...1.4 功能描述默认情况下,I2C 接口总是工作在从模式...4MHz 起始条件当 BUSY 位处于清除状态时对 START ...
All rights reserved Powered by
copyright &copyright 。文档资料库内容来自网络,如有侵犯请联系客服。2014年7月 硬件/嵌入开发大版内专家分月排行榜第二
2013年10月 硬件/嵌入开发大版内专家分月排行榜第三2013年6月 硬件/嵌入开发大版内专家分月排行榜第三2013年3月 硬件/嵌入开发大版内专家分月排行榜第三
2015年3月 Linux/Unix社区大版内专家分月排行榜第二2014年12月 Linux/Unix社区大版内专家分月排行榜第二2014年11月 Linux/Unix社区大版内专家分月排行榜第二2014年9月 Linux/Unix社区大版内专家分月排行榜第二2014年8月 Linux/Unix社区大版内专家分月排行榜第二2014年7月 Linux/Unix社区大版内专家分月排行榜第二2014年5月 Linux/Unix社区大版内专家分月排行榜第二2014年4月 Linux/Unix社区大版内专家分月排行榜第二
2014年3月 Linux/Unix社区大版内专家分月排行榜第三
2013年1月 硬件/嵌入开发大版内专家分月排行榜第一2012年10月 硬件/嵌入开发大版内专家分月排行榜第一2012年9月 硬件/嵌入开发大版内专家分月排行榜第一2012年8月 硬件/嵌入开发大版内专家分月排行榜第一2012年7月 硬件/嵌入开发大版内专家分月排行榜第一2012年6月 硬件/嵌入开发大版内专家分月排行榜第一2012年5月 硬件/嵌入开发大版内专家分月排行榜第一2012年4月 硬件/嵌入开发大版内专家分月排行榜第一2012年3月 硬件/嵌入开发大版内专家分月排行榜第一2012年2月 硬件/嵌入开发大版内专家分月排行榜第一2012年1月 硬件/嵌入开发大版内专家分月排行榜第一2011年11月 硬件/嵌入开发大版内专家分月排行榜第一2011年10月 硬件/嵌入开发大版内专家分月排行榜第一2011年9月 硬件/嵌入开发大版内专家分月排行榜第一
2014年10月 硬件/嵌入开发大版内专家分月排行榜第二2014年2月 硬件/嵌入开发大版内专家分月排行榜第二2013年10月 硬件/嵌入开发大版内专家分月排行榜第二2013年8月 硬件/嵌入开发大版内专家分月排行榜第二2013年3月 硬件/嵌入开发大版内专家分月排行榜第二2012年12月 硬件/嵌入开发大版内专家分月排行榜第二2012年11月 硬件/嵌入开发大版内专家分月排行榜第二2011年12月 硬件/嵌入开发大版内专家分月排行榜第二
2006年7月 硬件/嵌入开发大版内专家分月排行榜第二
2006年9月 硬件/嵌入开发大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。I2C接口上拉电阻的选择
I2C接口上拉电阻的选择1、I2C接口的输出端是漏极开路或集电极开路,所以必须在接口外接上拉。
2、上拉电阻的范围很宽,但也需要跟据功耗、信号上升时间等具体确定。和速度应该没关系。主要是I2C是oc,所以需要和驱动的从机个数(虽然从机个数不是由电阻决定的)有一定关系。不能说和速度没关系,
从机数量多的话, 由于经常在CMOS 集成电路里面源和基底是相连的, 而漏和基底存在寄生电容, 所以源和漏之间是有寄生电容的,
过大的上拉电阻会引起延时,导致边缘的上升下降速度变慢上拉电阻的取值何I2C总线的频率有关,工作在standard
-mode时,其典型值为10K&。在FAST
mode时,为减少时钟上升时间,满足上升时间的要求,一般为1K philips的IIC协议中pullup-res的典型值是5.1K@
VIO=5V(其实用5K一样,5.1K比较好买便宜),但手机系统一般VIO=2.8V,所以在参考设计中,通常此阻值用4.7K,虽然于驱动力上比协议标准不如,但考虑到leakage
current,用3.3K的漏电流比较大,综合考虑用4.7K,况且此阻值也是常规值I2C的上拉电阻可以是1.5K,2.2K,4.7K,电阻的大小对时序有一定影响,对信号的上升时间和下降时间也有影响,一般接1.5K或2.2K。总之,不同平台的官方试验和我的取值相似,倾向与用4.7K
@ 2.8V VIO Rp最大值由总线最大容限(Cbmax)决定,Rp最小值由Vio与上拉驱动电流(最大取3mA)决定;于是
Rpmin=5V/3mA≈1.7K(@Vio=5V)或者2.8V/3mA≈1K(@Vio=2.8V)
Rpmax的取值:参考周公的I2C总线规范中文版P33图39与P35图44标准模式,100Kbps总线的负载最大容限&=400pF;快速模式,400Kbps总线的负载最大容限&=200pF,根据具体使用情况、目前的器件制造工艺、PCB的走线距离等因素以及标准的向下兼容性,设计中以快速模式为基础,即总线负载电容&200pF,也就是传输速度可以上到400Kbps是不成问题的。于是Rpmax可以取的范围是1.8K~7K
@ Vio=5V对应50pF~200pF根据Rpmin与Rpmax的限制范围,一般取5.1K @ Vio=5V ,
负载容限的环境要求也容易达到。在2.8V系统中,console设计选3.3K,portable/handset等低供耗的设计选4.7K牺牲速度换取电池使用时间。有些IDH竟然用到10K或以上,将大大影响其抗噪性能,对于PCB的制造以及板层堆叠的结构的干扰将加大数据的误判。
I2C上拉电阻确定有一个计算公式:
Rmin={Vdd(min)-o.4V}/3mA
Rmax=(T/0.874) *c, T=1us 100KHz, T=0.3us 400KHz C是Bus
capacitance&
关于I2c的上拉电阻,个人最好的方式就是看参考设计,如果走线长了或好总线上有好几个芯片,就把电阻改小一些。如果参考设计没有就在1.5K~5k左右里面选一个就是了。但实际的时候我们没有去测量总线的电容问题,只能在选件/走线时候给与些许的关注。
注:之前做的一个STM32F407项目的I2C上拉电阻是100KΩ,然后我将I2C时钟速率由100KHz慢慢降至1Hz,I2C通讯都是失败的。之后将上拉电阻更换为5.1KΩ,I2C通讯正常。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。查看: 10254|回复: 26
STM32从机硬件I2C作为发送时如何捕获处理NACK。困扰一个月...
本帖最后由 princeward 于
07:58 编辑
是这样,主机I2C读取,从机I2C发送一个byte。
由于只有一个byte,所以主机在收到这个byte之后会给出一个NACK。但是我不知道如何处理这个NACK信息,库函数里貌似没有对应的I2C_EVENT?
我试过,在发送完一个byte并收到NACK后,以下几个中断事件都进不去:
I2C_EVENT_SLAVE_BYTE_TRANSMITTED (这个如果是主机发ACK能进去)
I2C_EVENT_SLAVE_ACK_FAILURE&&(按我的理解收到NACK之后应该是进入这个中断里,但是没有)
I2C_EVENT_SLAVE_STOP_DETECTED
这样遍导致从机在发送完一个byte后一直在等待主机的应答,从而导致后面的发送无法进行。也就是主机只能收到一个byte的数据,之后再读取就不行了。
我试过在从机里,发送byte前先I2C_AcknowledgeConfig(I2C1,Disable)禁止应答,但是仍然不成功。
到底怎样才能正确的处理NACK信息呢?中断处理函数如下:
void I2C1_EV_IRQHandler(void)
& & switch (I2C_GetLastEvent(I2C1))
& & & & //探测到停止信号
& & & & case I2C_EVENT_SLAVE_STOP_DETECTED: //有这个状态!!
& & & & & & & & I2C1_Configuration();
& & & & & & & &
& & & & & & & & /* Slave Transmitter Events */
& & & & & & & & //从机发送地址匹配到。
& && & case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:&&/* EV1 */& & & & & & & &
& & & & & & & & I2C_SendData(I2C1,0xaa);
& & & & & & & &
& & & & & & & & //字节已发送
& && & case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:& && && & /* EV3 */& & & &&&//发送完一个字节后进入不到这里& & & &
& & & & & & & && & & & & & & &
& & & & & & & & /* Slave Receiver Events */
& & & & & & & & //从机接收,地址匹配到
& & & & case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:& && && & /* EV3 */
& & & & & & & &
& & & & case I2C_EVENT_SLAVE_BYTE_RECEIVED:& && && & /* EV3 */& & & &
& && && && && & temp_read=I2C_ReceiveData(I2C1); //收到寄存器地址
& && &&&& & & &
& & default:
另外还有一个小问题,在从机发送完或者接受完一个字节后,应该对从机I2C做怎样的reset或者清除标志位工作?我这里是简单粗暴的重新用I2C1_Configuration()把I2C重新初始化了一下,但是总感觉不太好。
求高手支招,本来知道stm32的硬件I2C蛋疼,但是没办法,项目一定需要,就硬着头皮上了。唉。事成之后上I2C双机通讯的代码。
另外我觉得stm32的I2C设计真心没有mega16好用。那么复杂,datasheet上也没有示范例程。
在mega16中,通过读取TWSR可以知道I2C总线的状态,对于从机发送问题,专门有两个状态码,分别是:0xB8(完成发送一字节,收到ACK,那么我下面的中断处理程序就继续发送一字节),和0xC0(完成发送一字节,收到NACK,那么我下面就停止发送字节,并清除I2C的中断标志位)。非常的简洁明了,对比stm32实在是太蛋疼了。在mega16上随便写了个i2c的slave程序,就能和STM32的主机通讯了,收发都没问题。叹息!!!继续求高手支招!~
stm32硬件iic不好用
应该说STM32F10的硬件IIC不好用。其他系列的还不错。
yurii 发表于
stm32硬件iic不好用
但是确实是能用的,只不过调起来很费时很麻烦。
两个stm32之间iic我已经调通了,上面那个问题的解决办法就是,主机虽然接受一个byte,但是也发ACK,好让从机stm32能够进入到I2C_EVENT_SLAVE_BYTE_TRANSMITTED里面,就可以正常操作了。
但是现在要调的是stm32和linux通信,Linux那端的函数不好改,必须严格按照iic时序,主机接受一个byte后只能发NACK,所以stm32这端就萎了。。。
唉,实在是蛋疼。
tiancaigao7 发表于
应该说STM32F10的硬件IIC不好用。其他系列的还不错。
见楼上,希望能得到大大的帮助~~到底如何在中断里捕获并处理NACK啊~~
顶一下,难道因为STM32的I2C难用大家都不用它的硬件I2C吗?
作为从机,在等待ACK或NACK应设置超时,超时情况下收到NACK应释放总线,未超时情况下收到ACK,转到发送下一个BYTE
zhshliu 发表于
作为从机,在等待ACK或NACK应设置超时,超时情况下收到NACK应释放总线,未超时情况下收到ACK,转到发送下一个BY ...
十分感谢您的回复!
不过超时是在哪里设置呢?能否说一下具体步骤?
STM32的I2C状态寄存器SR1里有一位标志Time Out的错误,25ms之后就会被set,这个是要在错误处理的中断中捕获并且处理吗?
顶一下,真心求助~~~~~还是解决不了啊。。。
其实你的问题应该在主机,主机收到从机一个字节并回了NACK后,主机要发起STOP,或继续下一个REPET START
zhshliu 发表于
其实你的问题应该在主机,主机收到从机一个字节并回了NACK后,主机要发起STOP,或继续下一个REPET START ...
主机应该不会有问题吧。。。因为是用的linux系统中的函数,不太可能出问题的呃
在I2C ERROR中断中,有ACK Fail中断啊,I2C EVENT中断都是正常通信的中断
每路I2C在中断向量表中有两个中断
Acknowledge failure (AF)
This error occurs when the interface detects a nonacknowledge bit. In this case:
● the AF bit is set and an interrupt is generated if the ITERREN bit is set
● a transmitter which receives a NACK must reset the communication:
– If Slave: lines are released by hardware
– If Master: a Stop or repeated Start condition must be generated by software
另外:你的I2C做主时可以只读一个字节吗?怎么我一发送开始和地址读,后面就自动连续读两个字节?
本帖最后由 princeward 于
13:25 编辑
yuson 发表于
在I2C ERROR中断中,有ACK Fail中断啊,I2C EVENT中断都是正常通信的中断
谢谢这位兄弟!!!按照你的方法解决了问题!!!
之前一直都在void I2C1_EV_IRQHandler(void)这个中断里做事,忽略了void I2C1_ER_IRQHandler(void)这个中断。
确实如你所言,当收到NACK信号时,只需要在void I2C1_ER_IRQHandler(void)里响应一下I2C_EVENT_SLAVE_ACK_FAILURE这个消息就OK了!
另外:可以只读一个字节啊,注意你的主机在读了一个字节后就要发NACK。如果发成了ACK那么从机会再传一个字节的。。
顶顶,看看
princeward 发表于
谢谢这位兄弟!!!按照你的方法解决了问题!!!
之前一直都在void I2C1_EV_IRQHandler(void)这个中断里 ...
很好很强大,想问问楼主最后这样处理能稳定运行吗?
princeward 发表于
谢谢这位兄弟!!!按照你的方法解决了问题!!!
之前一直都在void I2C1_EV_IRQHandler(void)这个中断里 ...
还有你响应这个I2C_EVENT_SLAVE_ACK_FAILURE消息的时候是不是就是把总线复位一下就可以了?还请楼主支招一下,谢谢!
tangcdong 发表于
还有你响应这个I2C_EVENT_SLAVE_ACK_FAILURE消息的时候是不是就是把总线复位一下就可以了?还请楼主支招 ...
一直运行很稳定。
是的,我在程序里偷了个懒,把I2C初始化的函数调用了一下,相当于重置复位了,可以用的。
请问楼主的硬件iic调好了吗?是用了中断优先级最高呢?还是用了DMA?
还有就是32做主机iic能被高优先级的中断打断吗?
求楼主发一份源程序,硬件IIC一直没搞好。
求源码啊,楼主,有个项目需要呢,大谢。
这个MARK一下
楼主&&求发一份双机IIC成功的代码& &
楼主&&能将你的主机和从机代码各发送一份么?谢谢了。最近也在弄双机通信,弄了好久都没有成功。
感谢楼主,求双机通信的程序。
感谢楼主,求双机通信的程序。
阿莫电子论坛, 原"中国电子开发网"}

我要回帖

更多关于 stm32 i2c 上拉电阻 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信