RS-485半双工延时问题
学习485总线时,遇到延时问题,困扰很久。通过学习知道了485半双工收发时必须延时,以保证系统的稳定性、可靠性。好多资料都介绍了485 防静电、抗干扰电路。惟独没提 每一帧收发停止位(或第9位)的延时和 半双工总线收发切换延时 问题。我觉得在半双工状态下 485 帧的收发和 总线的收发状态切换延时问题 对485总线长期稳定的工作有很大影响。彻底搞懂这个问题 对了解误码产生、数据丢失、总线的稳定性、可靠性都有重要意义。
以下来源laoguo 21ic的文章 整理后:
1、每一帧收发停止位(或第9位)的延时问题
在RS-485半双工通讯中,一般以单片机的TI,RI信号作收发切换控制信号,发送时,检测TI是否建立起来,当TI为高电平后关闭发送功能转为接收功能,接收时,检测RI是否建立起来,当RI为高电平后,接收完毕,又可以转为发送。因此,必须控制端RE*,DE的信号的有效脉宽应该大于发送或接收一帧信号的宽度。
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_231915.gif
从上面的时序图可知:单片机在串行口发送数据时,只要将8位数据位传送完毕,TI标志即建立,但此时应发送的第九位数据位(若发送地址帧时)和停止位尚未发出。如果在这时关闭发送控制,势必造成发送帧数据不完整。
接收数据时也同样如此,单片机在接收完8个数据位后就建立起RI信号,但此时还未接收到第九位数据位(若接收地址帧时)和停止位。所以,接收端必须延时大于2位数据位的时间(1位数据位时间=1/波特率),再作应答,否则会发生总线冲突。
总之,发送和接收控制信号应该足够宽,以保证完整地接收一帧数据,任意两个单机的发送控制信号在时间上完全分开,避免总线争端。
注:延时T秒的取值
(1) 传送地址帧时,T>2X(1/波特率),可以选取T=2.5X(1/波特率)。
(2) 传送数据帧时,T>1X(1/波特率),可以选取T=1.5X(1/波特率)。
实际的软件流程:
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_231936.gif
问题:(【5楼】以解决)
可看到软件流程并没有在 每一帧收发停止位(或第9位)后实现延时,而是在(数据包的)最后一个字节(帧)上延时。这样能保障数据帧的正确(完整性)和稳定性吗?
2、半双工总线收发切换延时问题
为了可靠的工作,在485总线状态切换时需要做适当延时,再进行数据的收发。具体的做法是在数据发送状态下,先将控制端置“1”,延时1ms左右的时间,再发送有效的数据,一包数据发送结束后再延时1ms后,将控制端置“0”。这样的处理会使总线在状态切换时,有一个稳定的工作过程。
问题:
这里的 1ms是如何计算的? 485总线收、发状态切换时需要做适当延时,是指 485芯片的收发切换需要延时还是 485总线电缆固有的特性? 转一篇:智能控制收发器(整理)
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_231955.GIF
用内置微处理器实现收发使能的智能控制。
具体方法:微处理器在检测到UART的通信起始位后(低电平),打开发送使能,允许串行数据发送至RS-485/RS-422 通讯网络。微处理器根据所设定的波特率延时至UART停止位发送一半时,例如11位格式时,延时10.5T(T=1/fBAUD),然后开始检测是否有下一个起始位到来,在时间T内若有下一个起始位到来则保持发送状态。否则,将关闭发送使能结束数据发送,重新开始检测UART的起始位。
U3采用Microchip公司的 PIC12C508A,其中 GP0 GP1 GP4和GP5四个引脚设定对应于16 种常用波特率300 600 1200至38.4Kbps等8 种,以及900 1800 至 115.4Kbps等8种的延时时间。GP3对应于10位或11位串行数据格式,GP2为TXD输入用来检测UART何时发送和停止数据,GP1为复用输出引脚用来控制MAX3491的发送使能控制端,GP0也为复用输出引脚用来控制MAX3491的接收使能。 关注 两个自动转换(零延时)电路:
http://www.ouravr.com/bbs/bbs_upload19801/files_9/ourdev_230635.jpg
输出1时,485芯片不工作,总线仍然处于接收状态,靠上拉电阻保证差分电路输出1。
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_230635.jpg
零延时电路图:
http://www.ouravr.com/bbs/bbs_upload19801/files_9/ourdev_230999.jpg
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_230999.jpg
零延时电路波形图:
和上面电路比,输出1时,485芯片也有短时(RC延时)输出。
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_232140.GIF
他们如何保证 “控制端RE*,DE的信号的有效脉宽应该大于发送或接收一帧信号的宽度” 的?
------------------------
这个已经理解了,这两个电路没有使用 单片机来切换,所以不存在发送最后一个帧需要延时的问题。
但是这个问题依然存在:
为了可靠的工作,在485总线状态切换时需要做适当延时,再进行数据的收发。
------------------------------------
这两个电路在状态切换时都没有按这个要求来延时。 mark 可看到软件流程并没有在 每一帧收发停止位(或第9位)后实现延时,而是在(数据包的)最后一个字节(帧)上延时。这样能保障数据帧的正确(完整性)和稳定性吗?
-------------------------------
又查了些资料,第一个问题有了新的思路:(具体理解的是否正确,还需要看波形来验证)
对于一个数据包来说,单片机发第一帧(字节)到最后帧之间的数据帧时,单片机都能正确的发出停止位(或第9位),因为这期间没有使用中断里的TI,RI信号作切换。直到最后一个帧才会用TI,RI信号来切换 485。也就是 最后一个帧(字节)才需要延迟 停止位(或第9位)的时间。
从本质上说,在发送/接收 数据包的 最后一个帧(字节)时,需要延时 等待 停止位(或第9位)的完整发送/接收。 也就是应当在 最后一个帧发送/接收后,在软件里写入延时代码 控制485芯片。 掉的好快。 Maxim带有自动方向控制的半双工RS-485收发器
MAX13487E/MAX13488E半双工RS-485收发器。该系列器件带有AutoDirection功能,发送数据时可自动使能驱动器。这一特性省去了驱动使能控制信号。
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_232078.jpg
比普通的485收发器多了个线与的东西。 21ic的文章,可惜看不到图三
高手的艰难颠簸----Q118.RS-485总线的方向控制如何实现?要注意什么?
http://blog.21ic.com/more.asp?id=10746
3 换向控制
总的来看,真正传输数据前先打开驱动器的条件不应改变,只有这样才能保证数据可靠地传输(按常规就是这样做的)。现在的问题是:打开驱动器的时间总是要占用时间的,要求还必须是低电平,高电平不起任何作用。同时,直接用数据打开驱动器是不可取的,这样做有损坏数据的危险。因此,可以这样说,设计思路上与使用I/O口先打开DE再发送数据的思路是一样的。为了达到不需要I/O干预,那么就需要使用专门的开启代码机制解决吧。
通过线与让I/O控制先送出开启电平来开启驱动器比之由数据线先送一个字节开启代码相对简单,虽然电路稍为复杂一些,但不对接收方识别提出要求。线与的方法优点是之一占用时间少又类似常规机制;第二个优点是节省光耦,即在线路采用光隔离措施时能与数据线共用一个光耦。但必须在发送真正的数据前及时退出。为了及时准确控制,感觉用单稳态触发器为好。图3的电路,影响时间常数的主要因素是数据速率。速率高,时间常数要小些,速率低,时间常数要大些。调试相对难是这个电路的不一定的不足。不过,要注意这个电路的两个时间常数并不相同,原因是C2要经过Q4的发射结放电,而C1不存在这样的问题。该电路的不足还有收发控制电平不是数字信号而是模拟信号。
图一:
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_232115.gif
可惜看不到图三。 另一段关于延时的问题的讨论:
只是我们讨论这些问题可能要将传输速率限制在一个合适的水平以下。如果是在115.2K,数据的单bit位宽约8uS,而TXD通过74HC05的延迟约为25ns,MAX485的控制延迟约为70ns,这样合计造成单个bit的信号损失为(25+70)/8000=1.18%, 一般UART是对一个比特进行16次采样的,这1%的损失应该不会对其中任何一次造成影响。另外以上的计算可能是实际情况的2倍,因为对于一个0比特,虽然在下降沿部分造成了损失,但是因为前述两个延迟同时也作用于上升沿,这就会延长0电平时间,减少了0电平的宽度损失。
这是我的计算方法,还请大家指正。 顶下,希望高手看看。 郁闷的AVR与485的通信问题
http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=857628&bbs_page_no=1&search_mode=3&search_text=amwox&bbs_id=9999
(关于 延时 的整理)
1、使用 AVR的发送中断标志,解决办法:在每一包数据的最尾加一个0xFF
AVR的发送中断标志是数据移出发送缓冲就产生了中断,数据还没有真的发送出去.
如果此时后面的数据没了,把485置为接收状态就会出现最后一个数据发不出去的现象,在此条件下, 用超时来判断最后一个数据是否发出去,对于不同的波特率,时间也不一样,而且,对于"0"响应的设备时,用超时就有可能收不到部分数据.没办法只好在每一包数据的最尾加一个0xFF确保所有数据都发出去.
2、使用 AVR的发送完成中断。(可能是AVR特有功能)
当整个数据帧移出发送移位寄存器,同时发送缓冲器中又没有新的数据时,发送结束标志TXC 置位。TXC 在传送结束中断执行时自动清零,也可在该位写"1” 来清零。TXC 标志位对于采用如RS-485 标准的半双工通信接口十分有用。在这些应用里,一旦传送完毕,应
用程序必须释放通信总线并进入接收状态。
当UCSRB 上的发送结束中断使能位TXCIE 与全局中断使能位均被置为"1” 时,随着TXC 标志位的置位, USART 发送结束中断将被执行。一旦进入中断服务程序, TXC 标志位 即被自动清零,中断处理程序不必执行TXC 清零操作。
donkey 知秋的回答:不知道是我的232-485的转换器的问题还是别的什么问题,即使用了发送完成中断,也还是要延时5us才行,否则偶尔会出错.
这里的 "偶尔会出错" 也是 延时 问题,为何 延时 能排除 "偶尔会出错",原因(理论根据)是什么? 用过延时,不用够呛,只是切换的时候加就可以,不知道为什么,就是因为不稳定,上网查到有这么回事的。几us就ok了 今天调了232/485电路,都未延时,开了3小时,每秒发/收一个包(9600bps,8/30字节,不定长),无错误。
用下面两个图 直接把原来的程序(232下的上、下位机)未做任何修改搞成 485了。
上位机用的站上的图:
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_237015.jpg
下位机用的 3楼的图:
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_230635.jpg 有搞 485的给看看。 485半双工收发时必须延时,以保证系统的稳定性、可靠性。
????????
必须延时?为什么?485半双工收发不需要延时,只需要在发送数据是发送使能,接收数据时接收使能。
1.每一帧收发停止位(或第9位)的延时问题
这里其实是由于单片机的特殊性,如何使用RS485的问题。就是标志位不是真正的接收完毕,发送完毕标志时,需要软件帮助其使能延时。
2.半双工总线收发切换延时问题
误人之语,延时时间居然还能达到1ms!这里绝对是错误。
实际使用时,有出现总线上不同波特率的误差产生丢数据的。总线不间断的发数据时,可能偶尔会有1次数据丢失。这里适用延时,只要延时时间能消除晶振频率的误差,使其不累计,即可。 485半双工收发时必须延时,以保证系统的稳定性、可靠性。
----------------------------
在本论坛里,在21IC里都有这样的说法。并且一些做过485工程的前辈们也这样说。但我的确不懂这样做的理论依据,所以才提问。第一个延时的问题以搞懂了。
这个,一直没有搞懂原因:
2.半双工总线收发切换延时问题 1ms。有好多帖上说用1ms延时,通讯就稳定了,不用则出现误码。不知究竟为何? 总结下15楼的:
总线上不间断(长时间连续)的发送数据会产生累积误差(不同晶振频率的误差)。所以用延时(暂停通信一段时间)来消除波特率的误差,避免数据错误。 掺和两句……
先声明一哈,俺没玩过AVR,正准备试试,所以不管对错申请免责,并请各位高手老鬼们不必太认真听俺掰。
①.先搞清异步通信的帧结束于何处
一帧数据包括起始位、数据位(n位)、校验位(option)和停止位(1/1.5/2位)。对接收方而言,不管事先停止位设成几位的,收到半个停止位就算帧结束。剩下的对方爱发不发,反正这边不看了。(这点顺便解消了17楼的疑虑....)
这样,剩下的0.5~1.5个停止位成就了双方调整时钟的余地,以保证不积累误差。所谓异步通信允许双方时钟误差2.5%左右,就是从这来的。
②.该在哪儿做收发切换?
从Tx→Rx,当然是越早越好,要不头上就可能丢掉;从Rx→Tx,迟一点较安全,给对方留出准备时间。这个显而易见的原则编程时注意到了吗?
③.中断能不能用?怎么用?
从Tx→Rx,用Tx buffer空中断?肯定错了,那时最后一个数据才刚被搬出FIFO,还在移位寄存器里慢慢发着呢,哪能急着切断Tx?楼上有人说应采用“发送完”中断,这就对了,很重要,狠狠重要。
从Rx→Tx,没辙,要加延迟,至少必须加到停止位完整才行,剩下就指望接收方别懒洋洋的不肯切换就是了。
④.再唠叨两句……
半双工切换是要通信双方努力的,两边都得遵循Tx→Rx快切,Rx→Tx慢切的原则。慢切咋都好办,但要快切,就必须考虑中断优先级什么的,关系到系统设计。如果整体设计时对实时性考虑不周,该切换时程序还被吊在别处一时回不来,那丢数据也真是活该了。
俺说过俺没实际玩过AVR,查资料也没找到TXC中断的详细描述,有谁知道请不吝赐教下吧,在别的CPU手册里俺看到一个在1/2停止位发生的例子。顺便提一哈,TXC中断只适宜用于最后的一个数据,发送全程都用TXC的话,可能会降低发送速率(为啥?想想便知)。
要不想用TXC的话其实还有个挺绝办法,就是在电路上永远打开接收使能,自己发的数据自己也能收到。这样做的好处是,不仅能保证发送帧完整,而且也校验了自己发出的数据,能检测出通信线路上的冲突。 AVR与485的通信问题 : 使用TXC中断,功能如同老51单片机,简单!可靠! 掺和两句……
先声明一哈,俺没玩过AVR,正准备试试,所以不管对错申请免责,并请各位高手老鬼们不必太认真听俺掰。
--------------------------------------
我并不是说,用AVR才存在 延时 问题。 现在不是讨论 使用中断(非发送完中断)造成最后位丢失问题。
现在这个问题:
2.半双工总线收发切换延时问题 1ms。有好多帖上说用1ms延时,通讯就稳定了,不用则出现误码。不知究竟为何?
没有理论依据,大家都凭经验这样做了,想搞懂原因。
另:我用13楼的电路,没有 延时 ,使用了近3个小时,没出问题。 按【13楼】 yzz163 的做了一个LPC2131与PC通信,
仿时发现两个片子的收发控制端都是红的(高
电平),这都处于发送态嘛,还是这个电路不能
这样用? PC给ARM发‘1’出不来,是哪出问题了?
http://cache.amobbs.com/bbs_upload782111/files_11/ourdev_493912.PNG
(原文件名:12.PNG)
http://cache.amobbs.com/bbs_upload782111/files_11/ourdev_493913.PNG
(原文件名:13.PNG)
本贴被 shishi 编辑过,最后修改时间:2008-11-11,17:15:27. 收藏 刚做的项目,不加延时几乎总是出错,必须加!!!!!!!!!!!!!!! 我也刚做过mega8控制485,发送一桢数据后差不多要延时1ms后才能切换到接受状态,否则出错 好贴!mark! mark ji mark mark MARK 好看 mark mark 最近在玩485,总线切换是需要时间的,适当延时没有坏处,更不能当成双工那样使用 mark ok十三楼电路今天没事调试了一下连接下位机的确实可以只是要把第4引脚接到TXd Mark 485加延时是为了区分一帧数据是否接收完成,如果接收的2个字符之间的间隔时间大于3.5个字符的发送时间认为接收完毕,进行CRC及以后的处理,根据波特率的不同延时不同,如果是自己开发的系统可以固定,主机判断发送完最后一个字节后立即切换到接收状态 回复【8楼】yzz163
-----------------------------------------------------------------------
图中画“X”的电路是可用的,485芯片有一个收发转换延时,
但是UART的基础是基于时间分包,有这个转换延时,
只是将所有发送波形向后做了一个延时,对接受是没有太大影响的
不过如果反相器如果使用三极管电路搭建,通讯波特率肯定上不去,
因为你TXD的0电平可能已经发送结束,
而本应同步产生的RTS信号还处在中间电平,
另外,查看了下,SP485EEN充关闭带开启输出0或1,耗时均在40-100ns之间,
没有看到由输入转换为输出的耗时,考虑大概10被乘余量
使用集成反相器由TXD产生RTS,大概能工作在1MHz
如果使用三极管反相器,那就得看反相器电路的响应速度了
呵呵,纯主观臆测,没有实际测试的,不知道有参考价值没 这个延时时间,如何实现
要用定时器吗? mark TI在开始发送停止位时建立,停止位并未发出,只有等待停止位发送完成才能关闭DE,所谓的1ms延时其实就是等待停止位发出的时间,为什么是1ms,主要是考虑到一般的通讯波特率从1200开始,1s/1200≈0.83ms,这样看来,最合适的值当然是1ms了,而且这个1ms能够保证1200bps及以上的波特率都能够正常的发出停止位,其实0.5ms就可以了,因为接收时在停止位的中间检测到停止位(18楼已经说到了这一点),也就是半个停止位就可以了,考虑到同步误差,取1ms还是很有理由的。
其实,根据不同的波特率,延时时间需求是不一样的,1200bps需要0.83ms,9600bps就只需要0.104ms了,如果采用定时器很容易实现,在最后一个字节发送后产生TI中断时,打开定时器,时间根据不同波特率写入不同值,延时时间到关闭DE即可 我用的38400,msp430芯片。16MHz,两分频。延时0.2ms不行,延时0.4ms就可以
我的延时程序还没有测试。 MARK 好东西 mark
又见一个485的讨论帖~
mark之~ 延时后会稳定很多的 这种问题,理论分析不如用程序实测,当发送完时,RE/DE不要急着变换电平,需要延时多长时间变换电平,波特率不同,不好确定。程序实测为好。我个人得出的经验,3ms,我是这么做的。 我咋就没遇到过呢?
搞MODBUS从来没延时过,波特率用到过115200也没出过问题。 好帖子,mark 早点来看就好了,板子出来了,才发现问题,后悔啊
默默收藏 mark mark好贴 好帖,MARK 学习了,谢谢。 这真是485好贴啊{:victory:} 485延时原因 好贴,收藏 ntkz 发表于 2012-4-15 12:47
我咋就没遇到过呢?
搞MODBUS从来没延时过,波特率用到过115200也没出过问题。 ...
波特率越低才越容易出问题。
举个例子吧,有的攻城狮是在【寄存器空】状态出现后立即切换为接收状态,而实际上寄存器移位还没有完成,你这时候切换收发难道最后一个字节能发送出去???
你没有出问题那有可能是因为:
1、你可能是使用到了【发送完毕】状态而不是【寄存器空】状态;
2、你的MCU时钟频率不快,执行收发切换时数据最后一个字节已经发送出去了;
3、其他可能的情况自行脑补;
本帖最后由 60飘过 于 2016-3-2 17:32 编辑
测试软件串口助手,电路设计无延时,此条件下790us可以,780us连续通信下(手按在回车键)几百次会有一次乱码。程序:接收中断,发送扫描发送完毕标志。波特率:9600。芯片:MAX485。仅供参考{:smile:} 看晕了。。感觉好复杂 MARK............. yzz163 发表于 2008-3-16 19:31
两个自动转换(零延时)电路:
http://www.ouravr.com/bbs/bbs_upload19801/files_9/ourdev_230635.jpg
这个短延时设置多大呢?能适应任意波特率吗?
技术贴 好贴
页:
[1]