打印
[应用相关]

分享一个关于使用“开漏输出”的惨痛经验教训

[复制链接]
7076|35
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 feilusia 于 2014-11-4 10:38 编辑

****************后记**************************************************
后来经16楼提醒,我的下述结论有错误,是我理解错了,希望不要误导到大家。

***************原帖******************************************
在做的项目需要IO口自己写一个通信协议,由于是双向的,所以使用了开漏输出加上拉。
调试中发现线长一点时通信不过,一直以为是我的焊接不行、线不行、协议不行,找了很多天,最终发现是开漏输出的使用出现了问题。于是我被主管骂惨了。

我是这么传输数据的:机子1将数据写到IO口,由于软件到硬件上有些许延时,所以机子1不停的查询IO口状态,等查询到IO口的数值正确时,拉低握手线。

问题就在于:同一时间下IO口只能有一种状态,要么输入要么输出。也就是类似半双工,而我却以为是全双工。在写IO的瞬间它被设置为输出,我又去读引脚导致IO变为输入,而距离短时机子2能接受到数据完全是因为IO口的硬件延迟。

那又如何确定写到IO口的数据已经准备好了呢?
为此我可以做两件事情:
第一件事情是减小上拉电阻,也就是增大电流,这样能使数据在线中传输的快一些,减小长短线造成的不同步影响。
第二件事情是可以在置位IO口后写几句空指令,然后再拉低握手线。当机子2检测到握手线被拉低时,IO口理论上也就置位好了。
当然具体加几句空指令还是需要实际测试。

程序还未改动,先写个笔记总结,自己MARK一下。

/*****************实测**************************/
比较慢的机子在置位数据总线后需要适当延时,否则会出现偶尔电平不稳定的现象。
50M的IO翻转一次需要0.02ns。
所以我把较慢的STM8加上了一条NOP语句,也就是一条指令周期。大概延时在1/16M=62.5ns左右,测试一晚上未出现错误。









沙发
Rain_King| | 2013-12-3 16:32 | 只看该作者
貌似不错啊........先标记一下.........

使用特权

评论回复
板凳
fengdingkusong| | 2013-12-3 20:03 | 只看该作者
经验分享

使用特权

评论回复
地板
有缘于你| | 2013-12-3 22:36 | 只看该作者
不错的提醒

使用特权

评论回复
5
cs0617| | 2013-12-4 08:12 | 只看该作者
mark

使用特权

评论回复
6
gpjun2008| | 2013-12-4 08:36 | 只看该作者
mark                     

使用特权

评论回复
7
aa274131487| | 2013-12-4 08:39 | 只看该作者
maRK

使用特权

评论回复
8
zoudejile| | 2013-12-4 09:24 | 只看该作者
恩,谢谢分享

使用特权

评论回复
9
ppenppen| | 2013-12-4 10:56 | 只看该作者
本帖最后由 ppenppen 于 2013-12-4 11:27 编辑

看来楼主的方法,还是能适合板内的通信。还可节省一个IO口。

使用特权

评论回复
10
feilusia|  楼主 | 2013-12-4 11:02 | 只看该作者
ppenppen 发表于 2013-12-4 10:56
看来楼主的方法,还是能适合板内的通信。

也不是板内通信,是板间通信,现在是手工压线,每台机子间也就4CM左右。到时候会底板代替我的手工线。

使用特权

评论回复
11
zyj9490| | 2013-12-4 13:03 | 只看该作者
如果是ARM之类,有输入寄成器,输出寄成器,输入寄成器的相应位永远反应的是端口的状态。除非复用了。当作GPIO的话,

使用特权

评论回复
12
lapeno| | 2013-12-4 13:28 | 只看该作者
速率高的时候,上拉电阻要小一些

使用特权

评论回复
13
hithms| | 2013-12-4 23:10 | 只看该作者
:lol
很好的经验

使用特权

评论回复
14
yf2008bj| | 2013-12-5 17:48 | 只看该作者
mark

使用特权

评论回复
15
副BAN主就是我| | 2013-12-5 18:22 | 只看该作者
这种实际开发项目的经验才是最可贵的,支持!!

使用特权

评论回复
16
戈卫东| | 2013-12-6 09:38 | 只看该作者
STM32F103,GPIO配置成OD输出,从IDR读取的值,是正确反应管脚的电平的.
OD的管脚,采用适当的上拉电阻,可以从ODR输出0给出低电平,也可以从ODR输出1然后从IDR读取管脚实际电平,当成双向应用是没有问题的.

使用特权

评论回复
17
戈卫东| | 2013-12-6 09:38 | 只看该作者
你的产品中出现的状况,应该是其它原因造成的.

使用特权

评论回复
18
feilusia|  楼主 | 2013-12-6 10:14 | 只看该作者
戈卫东 发表于 2013-12-6 09:38
STM32F103,GPIO配置成OD输出,从IDR读取的值,是正确反应管脚的电平的.
OD的管脚,采用适当的上拉电阻,可以从O ...

输入数据寄存器和输出数据寄存器是分开的,并没有输入/输出寄存器。在读IDR时是对输入数据寄存器进行操作,自然就没有办法对输出数据寄存器进行操作。此时端口就没有输出了。

QQ截图20131206101102.jpg (38.06 KB )

QQ截图20131206101102.jpg

使用特权

评论回复
19
戈卫东| | 2013-12-6 10:31 | 只看该作者
你的理解有误.
读IDR不会影响端口配置,不会影响ODR,不会影响ODR在管脚上的输出.

使用特权

评论回复
20
戈卫东| | 2013-12-6 10:38 | 只看该作者
你的中文DATASHEET也有可能误导你.
他说"在推挽模式时,对输出寄存器的读访问得到最后一次写的值". 其实任何时候访问ODR都是得到最后一次写的值.
而读IDR其实总是得到管脚实际状态, 即使是配置成推挽模式, ODR输出1, 但外部强制拉成0, 从IDR读到也会是0.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:1、博客:http://blog.csdn.net/feilusia 2、QQ群:STM8/STM32群(164311667);职场交流群(450154342);CC2640R2F群(557278427) 3、淘宝店:https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i

135

主题

1960

帖子

94

粉丝