作者 | 主题 |
---|---|
合 奇侠 ![]() 经验值:6090 发帖数:3970 精华帖:20 |
楼主
![]() 主题:应用探讨—S7-200 自由口通信
强大而灵活的自由口通信能力,是S7-200系统的一个重要特点。S7-200 CPU的RS485通信口提供了建立在串行通信基础上的“自由”通信能力,数据传输协议完全由用户程序决定。通过自由口方式,S7-200可以与串行打印机、条码阅读器等通信。而S7-200的编程软件也提供了一些通信协议库,如USS协议库和modbus RTU从站协议库,它们实际上也使用了自由口通信功能。
开设本话题的目的,在于澄清自由口通信的基本概念,强调使用中的要点,讨论应用的常见问题。欢迎大家畅所欲言,分享应用中的心得体会,经验教训,共同提高与进步。 参考文档:下载中心“1109582”——S7-200可编程控制器系统手册。 此次集中探讨将持续至1月25日,其中有突出表现的网友将获得加倍精华奖励积分;最终所有有效留帖的网友将获得加倍发帖积分;根据交流情况,会酌情赠送小礼品。 交流结束后也将专门整理重要内容,供广大网友分享参考。 预祝大家交流愉快,收获丰富! |
Laohuai 至圣 ![]() 经验值:17410 发帖数:6225 精华帖:18 |
7楼
![]() ![]()
我觉得做自由口通讯时容易出现的几个问题:
1 0009 端口0中同时执行XMT/RCV 000B 端口1中同时执行XMT/RCV 经常有人问,程序里只发送(XMT),怎么会出现同时执行XMT/RCV呢? 其实这个有4种可能: 发送没结束,又执行发送 接收没结束,又执行接收 发送没结束,又执行接收 接收没结束,又执行发送 有3种解决方法: a 用沿来执行。 b 在中断程序里来执行。 c XMT用 SM4.5/ SM4.6来执行,RCV根据SMB86的条件来执行。 2 发送结束可以(应该)立即执行接收,但接收结束不能立即发送,应该延时发送。 3 用字符中断方式接收数据时,中断程序应该足够短,否则会丢数据,中断程序执行的时间应该小于传送一个字节数据所需的的时间。 管理员注:本帖已被纳入此次探讨发帖整理,请点此详阅。 |
Laohuai 至圣 ![]() 经验值:17410 发帖数:6225 精华帖:18 |
41楼
![]() ![]()
我来发几个SMB2的例子(特别适合初学者):
SMB2为自由口接收字符的暂放区,从端口0或端口1接收的每个字符都放在这里。 SMB2只能存放一个字节字符,而对方发送的一帧可能是很多字符,所以在接收到下个字符之前,应该在中断里将接收到的字符移走。 每接收一个字符会产生一次中断,端口0产生中断事件8,端口1产生中断事件25。 例1:通讯方法(用串口调试软件)控制PLC的输出: PLC写入如下程序:比如向PLC发1时,Q0.0亮,发2,那么Q0.1亮,发255,那么从Q0.0到Q0.7都亮,发送0,则都不亮。 LD SM0.1 MOVB 9, SMB30 ATCH INT_0, 8。 ENI INT_0: LD SM0.0 MOVB SMB2, QB0 用串口调试软件向PLC发1时,Q0.0亮,发2,那么Q0.1亮,发255,那么从Q0.0到Q0.7都亮,发送0,则都不亮,你可以试试。 串口调试软件设置:9600波特率,数据位8,停止位1,无奇偶校验。 例2:如果有2个PLC,那么将两个通讯口(PORT0)3 3接,8 8接。如果只有一个PLC,那么用串口调试软件当主站也可以。 主站程序:向从站发送4个字节的数据。 网络1: LD SM0.1 MOVB 9, SMB30 MOVB 4, VB0 MOVB 1, VB1 MOVB 2, VB2 MOVB 3, VB3 MOVB 4, VB4 网络2: LD SM0.5 EU XMT VB0, 0 // 每秒发送一次 从站程序1: MAIN:OB1 LD SM0.1 MOVB 9, SMB30 ATCH INT0, 8 ENI INT_0:INT0 LD SM0.0 MOVB SMB2, VB10 ATCH INT1, 8 INT_1:INT1 LD SM0.0 MOVB SMB2, VB11 ATCH INT2, 8 INT_2:INT2 LD SM0.0 MOVB SMB2, VB12 ATCH INT3, 8 INT_3:INT3 LD SM0.0 MOVB SMB2, VB13 ATCH INT0, 8 如果主从站同时启动,或者从站启动比主站启动早,那么VB11=1,VB12=2,VB13=3,VB14=4. 如果主站先发送,那么VB11就不一定是1了,可能是2或3或4。 从站程序2: MAIN:OB1 LD SM0.1 MOVB 0, VB10 MOVB 9, SMB30 MOVD &VB10, VD80 ATCH INT_0:INT0, 8 ENI INT_0:INT0 Network 1 LD SM0.0 INCB MB10 MOVB SMB2, *VD80 INCD VD80 Network 2 LDB= MB10, 4 MOVB 0, MB10 -D +4, VD80 这个例子只是比上个例子少了3个中断而已。 从站程序3: MAIN:OB1 LD SM0.1 MOVB 9, SMB30 ATCH INT0, 8 ENI INT_0:INT0 Network 1 LDB<> SMB2, 1 CRETI Network 2 LD SM0.0 MOVB SMB2, VB10 ATCH INT1, 8 INT_1:INT1 LD SM0.0 MOVB SMB2, VB11 ATCH INT2, 8 INT_2:INT2 LD SM0.0 MOVB SMB2, VB12 ATCH INT3, 8 INT_3:INT3 LD SM0.0 MOVB SMB2, VB13 ATCH INT0, 8 如果1是起始字符,那么在中断0里加个判断,就不会发生接收数据错位的问题。 管理员注:本帖已被纳入此次探讨发帖整理,请点此详阅。 |
yanxiao 版主 ![]() 经验值:26885 发帖数:11964 精华帖:45 |
48楼
![]() ![]()
我看过不少问S7200通讯问题的贴子,觉得很多问题并不是S7200的,而是串行通讯的共性问题,也就是对串行通讯本身概念的认识问题。下面我来谈谈在我的记忆中关于串行通讯的一些认识。
1、串行通讯只有一个传输通道,每个时刻只能表达一种状态。不管什么介质,不管是什么信号,我们用1表示一种状态,用0表示另一种状态。 2、只用1和0两种状态,是不能表达更多信息的。好在有一个物理量,对每个系统来讲是统一的,那就是时间。我们现在很容易做到不同系统之间的定时误差控制在PPM数量级。1和0在时间上进行有序的组合,就可表达近乎无限的信息。 3、任何一个信号,如果不赋给它一些特点的意义,实际上没什么用。两个系统要通过信号交换信息,必须对信号有一个共同的约定,这就是我们通常所说的协议。 4、最基本的协议是物理层面的(那个OSI的七层协议模型,第一层就是物理层协议)。RS232、RS485、RS422,这些是物理层面的一些协议。 5、我们现在要谈的是异步串行通讯。异步,发达方和接收方之间,没有额外的通道来传送信息何时传送与接收。每个信息单元的起止时间,发送方编在信息中,由接收方自已解码并同步。 6、好。现在来讲一下传送一个字节的过程。在没有传送信息时,传输线处于空闲状态。规定:空闲状态为1。发送方(TX)准备发送,驱动传输线让它由1变为0,并持一位的时间长度,我们把这一位叫做起始位。接收方(RX),检测到传输线由1变0,意味着可能有信息要传了,RX就持续检测,以验证这个0是不是持续了规定的一位时间长度,若是个合法的起始位,就按约定的定时方式,把后续的传输线状态,接收为1个字节。TX在发完起始位后,就发字节中的第一个位(bit),并依次把字节中的所有位发完,每bit均持续相同的一位时长。然后再发校验位(如果约定发/收方都采用的话)、停止位。 7、停止位,这个要说一下。我们知道起始位是0,而这个停止位,规定是1,和传输线的空闲状态1是相同的。停止位规定的时长比较乱,有1位停止位(也就持续时间占1个位长)、1.5位、和2位停止位,其它时长的停止位好象没见过。停止位的作用,其一是作为一字节单元的成员,给接收方定时用的,也就是下一个字节,在停止位之后才开始。另一个作用,可供检查字节传送的完整性。因为停止位是规定为1状态的,若在停止位的时间里测到了非1状态,表示这个字节传送有问题,有可能被接收方丢弃,传送失败。 8、若收发双方的停止位不相同,怎么办?这个在论坛上经常有人问。好,我们来分析一下。若TX是2个停止位,RX要求是1个停止位,很好,TX多发的一个停止位,会被RX看作是空闲状态(也可认为是字符间隔),没有任何问题。若反过来,TX是1个停止位,RX要求是2个停止位,有问题吗?一般问题是很大的,但也有可能可以正常通讯。这要看TX是怎么发字节的。有些系统,硬件上,发送电路比较简单,没有缓冲机构,一个字节必须完整发送后,才准备下一个字节的数据,而这个准备需要花一些时间的,这就给传送的时序上,停止位之后,有了空闲时间,相当于停止位得到了延长。所以我曾经发过一个贴子说,S7200的发送改为单字节发送,每个字节之间有意插入一些延时,人为造成空闲时间,以充当停止位,但这个方法说归说,我并没有试过。可惜的是,现在的系统,硬件都做得很完美了,包括S7200,TX是有缓冲的,在一个字节还未发完前就可以接受下一个要发送的字节,硬件上保证一个字节发完后可以立即启动下一个字节发送,前后两字节间除了停止位,没有额外的间隙,这种情况下,接收方就要命了,RX认为还在收停止位时,下一个字节的起始位就来了,没办法完整接收,通讯就失败了。 9、波特率。两边设为一致就可以了。波特率不一致,铁定不能通讯。但允许有少量的误差。停止位实际上还用来调节这个误差的。比如1个停止位,RX并不死板要求停止位是完整的1个位时长,实际只要停止位超过0.5个位长就算是合格了。波特率,就是每秒最快能传送的位数,包括了起始位、停止位这些辅助位。实际每秒能传送的最快字节数,要看这些辅助位的多少。比如一个11位结构的字节单元:1起始位+8字节位+1校验位+1停止位,字节最快传送速率为band/11。好象还有一个概念,叫比特率,也就是有效的位传送速率,比特率=8*(band/11),也就是比特率比波特率要小的。 10、RS232的TX和RX是两根独立的线,收/发可以同时进行,所以叫作全双工异步串行通讯。按我们日常两人交谈的经验,总是A说B听,当B要说时,A就停下来听B说。如果A、B同时说,这是吵架,要达到相互交流就难了。同样,通讯若同时收发,一般人会白白死掉很多脑细胞而写出的程序通讯效果还是很差。所以,即使RS232能双向同时, 一般使用时也是收、发不同时的。 11、RS485。RS232不错了,但局限性大大的。RS485收发同线,允许多少RS485并联使用,电气采用差分传送信号,可以抗干扰。S7200就属于RS485。RS485设备同一时间只能发或再改,收发是分时的,所以叫做准双向。尽管S7200中可以同时缓冲8个NETR和NETW,实际在RS485层面,还是一个一个分时完成的(由系统程序根据PPI协议协调)。RCV和XMT完全由用户程序控制,你就不能同时让两个都执行,否则就是哄抢资源而被S7200当成错误处理。 12、RS422,介于RS232和RS485。RS422和RS232一样收、发线独立,但电气上采用和RS485一样的差分信号。所以RS422能多机通讯,比RS232传得远,但比RS485浪费硬件资源。RS422只要软件上采用准双向的规则,通过发收线合并,可以简化为RS485,和RS485设备通讯。但RS485却不能复杂化成RS422使用。 管理员注:本帖已被纳入此次探讨发帖整理,请点此详阅。 |
veich 奇侠 ![]() 经验值:6012 发帖数:1037 精华帖:18 |
56楼
![]() ![]()
自由口通讯确实挺强大的,
我做通讯主站的使用经验是, 首先要做好自由口的定义,用SMB30/SMB130;此时除了定义波特率、奇偶校验外, 还要注意,如果要接受从站的反馈信息,最好定义接受为中断接受。否则 有可能造成接受不到从站的返回信息。 注意通讯时序,要一帧一帧的发送,每一帧间隔时间要大于最小间隔时间, 还要注意从机回复的时间也要计算在内。 不能同时多条指令一起发送,整个体系就乱了。 另外如果通讯出错,是所有人最头疼的问题, 我的解决方法是,如果编程上已经不知道自己哪里错了, 就用串口调试软件,将电脑的232转换为485,监控自由通讯口发送和接收、 的信息,很快就可以知道问题点了。
知足常乐!!!
|
苦斗 侠士 ![]() 经验值:1108 发帖数:318 精华帖:3 |
64楼
![]() ![]()
200的自由通讯功能确实强大!
目前我用其端口做过和ABB变频器(modbus)、富士变频器(富士通讯协议)、海里普变频器(海里普协议)、西门子M440的USS通讯、托利多称重仪表等通讯。 以上通讯没有用西门子的库程序,直接根据自由通讯规约而编制的,其实不管什么modbus还是别的关键在于校验不同,因为其通讯原理都是一样的,即一问一答,多站轮询等! 基于485半双工通讯介质,也即发送和接收要分开, 200自由通讯我认为最为稳定的是用接收字符终中断(如端口0,中断事件8)和SMB2,每接收一个字符就触发中断事件一次。然后在程序中处理接收过来的数据,最好结束中断、转移数据等。 哪位需要类似程序可联系我,以便交流! 附中断事件程序 LD Always_On:SM0.0 XORB VB1567, VB1567 MOVD &VB201, VD1562 MOVB 0, VB200 ATCH INT_1:INT1, 8 R V3021.0, 1 //R V3021.0, 4 R M0.0, 1 CRETI LD Always_On:SM0.0 WDR MOVB Receive_Char:SMB2, VB1567 AN M0.0 AB= VB1567, VB1403 S M0.0, 1 LD M0.0 MOVB VB1567, *VD1562 INCB VB200 INCD VD1562 |
一粒尘 游士 ![]() 经验值:230 发帖数:45 精华帖:1 |
87楼
![]() ![]()
下面是我从MICRO/WIN帮助文件里改的一段自由口通信程序,实现接收到后(结束字为H0A),再发回去。
1、补充了发送完成中断启动接收服务程序 2、增加了模式开关切换通信口的模式,当开关切换由RUN切换到TERM时,为PPI从属模式;当开关由TERM切换到RUN时,P0口为自由口模式。 3、上一条有局限性,在用软件启动和停止PLC时,P0口初始化为自由口,不论PLC模式开关是在TERM还是RUN位置 程序如下 ORGANIZATION_BLOCK 主程序:OB1 TITLE=程序注释 BEGIN Network 1 // 主程序 LD SM0.1 // 首次扫描时, MOVB 16#09, SMB30 // 初始化自由端口: // - 选择9600波特 // - 选择8个数据位 // - 选择无校验 MOVB 16#B0, SMB87 // 初始化RCV信息控制字节: // - RCV被启用 // - 检测到信息字符结束 // - 将空闲行条件检测为 // 信息开始条件。 MOVB 16#0A, SMB89 // 将信息字符结束设为hex OA(换行符)。 MOVW +5, SMW90 // 将空闲行超时设为5毫秒。 MOVB 100, SMB94 // 将最大字符数设为100。 ATCH INT0, 23 // 将中断附加在接收完成事件上。 ATCH INT2, 9 // 将中断2附加在传送完成事件上。 ENI // 启用用户中断 RCV VB100, 0 // 为端口0在VB100位置启用带缓冲区的接收服务 Network 2 LD SM0.7 //PLC上模式开关状态: //"RUN"时,SM0.7=1 //"TERM"时,SM0.7=0 EU O SM0.1 S SM30.0, 1 R SM30.1, 1 //[SM30.1 SM30.0]=[0 1]为P0口为自由口通信 RCV VB100, 0 //切换到自由口后,先开接收服务 LD SM0.7 ED R SM30.0, 2 //[SM30.1 SM30.0]=[0 0]为P0口为PPI从属模式 END_ORGANIZATION_BLOCK INTERRUPT_BLOCK INT_0:INT0 TITLE=中断程序注释 BEGIN Network 1 // 中断0 // 接收完成中断例行程序 LDB= SMB86 16#20 // 如果接收状态显示接收结束字符, MOVB 10 SMB34 // 则附加一个10毫秒计时器, ATCH INT_1 10 // 触发传送 CRETI // 并返回。 NOT RCV VB100 0 // 如果因任何其他原因接收完成, // 则开始新的接收。 END_INTERRUPT_BLOCK INTERRUPT_BLOCK INT_1:INT1 TITLE=中断程序注释 BEGIN Network 1 // 中断1 // 10毫秒计时器中断 LD SM0.0 DTCH 10 // 分离计时器中断 XMT VB100, 0 // 将信息传送端口0中的用户 Network 2 // 网络标题 END_INTERRUPT_BLOCK INTERRUPT_BLOCK INT_2:INT2 TITLE=中断程序注释 BEGIN Network 1 // 网络标题 LD SM0.0 RCV VB100, 0 //准备接收 END_INTERRUPT_BLOCK 管理员注:本帖已被纳入此次探讨发帖整理,请点此详阅。 |
半瓶醋 游侠 ![]() 经验值:522 发帖数:32 精华帖:2 |
95楼
![]() ![]() quote:以下是引用LaoHuai在2010-12-27 23:04:36的发言: quote:以下是引用happy Julia在2010-12-27 21:30:45的发言: 在这里真是受益非浅呀。 可还有许多不明白的,发送指令XMT很容易啦,可是接收指令RCV怎么那么多起始和结束条件。看的我都晕了,各位大侠能给我简单讲讲吗,大概是什么意思?我应该选择什么样的起始和结束条件呀? 条件多,给你选择的就多。再看几遍就能明白了。 如果觉得RCV麻烦,那就用字符中断方式接收数据,只要连接一个中断就可以了,但要一个一个收。 这个问题说起来和理解起来确实挺让人头疼的,但个人认为这是个非常好的问题,如果能把这部分理解清楚了,对于S7-200自由口的应用应该有很大的帮助。 这里大概讲一下自己的理解,其他的大侠们可以补充和更正: 以接收结束消息方式为例,通信伙伴的数据是一帧一帧发送的,比如通信伙伴每隔 100ms 发送一帧 01 02 03 04 05 给S7-200,S7-200接收这些数据,那么我们有几种方法可以正确接收到这些数据: 1、指定空闲线时间(可以理解为两帧数据之间的间隔)为50ms(小于发送间隔时间100ms),则当发送完第一帧 01 02 03 04 05 后,启动空闲时间检测,超过50ms即认为一帧数据结束,准备接收下一帧数据。这可以看做是“字符间定时器”结束消息方式。 2、指定接收结束字符为05,则当接收到 01 02 03 04 05 后,即收到结束字符05后,认为一帧数据结束,再接收到的 01 02 03 04 05 认为是下一帧数据,依此类推。这可以看做是“结束字符检测”结束消息方式。 3、指定接收数据长度为5,则收到 01 02 03 04 05 (5个字符)后,即认为一帧数据结束,再接收到的 01 02 03 04 05 认为是下一帧数据,依此类推。这可以看做是“最大字符计数”结束消息方式。 4、其他条件还包括“消息定时器”、“奇偶效验错误”、“用户终止”等结束消息的方式,或者这些条件的组合作为结束消息的方式。 那么在应用中选择哪种结束消息的方式,要具体情况具体分析。这话说起来很空洞,但确实如此,因为自由口通信本身就决定了,不同的通信对象间的数据帧格式(或协议)是设备厂家自由定义的,这就要求事先充分理解通信协议,并在此基础上进行选择。 另外一方面,如果能灵活掌握这部分内容,还可以解决一些实际问题。比如大家都知道数据要接收到接收缓冲区,而接收缓冲区的大小是有限制的(255个字节),那么怎么能够接收到大于255个字节的数据呢(缓冲区溢出后前面的数据被覆盖)?可以考虑设置“最大字符计数”为结束消息方式,将数据分为多个部分依次进行接收。 以上理解没有考虑s7-200的具体应用细节,详细的技术细节可以参考手册说明,仅供参考。 管理员注:本帖已被纳入此次探讨发帖整理,请点此详阅。 |
鼠老爹 侠圣 ![]() 经验值:3448 发帖数:2235 精华帖:13 |
112楼
![]() ![]()
手册上给出的一些自由口通讯示例,S7-200多以从站的面目出现。因此在逻辑上,PLC等待网络上的数据请求,再发送应答数据;发送完毕后再次启动接收。
如果PLC作为主站请求第三方仪表的数据,且使用的是自定义通讯协议在编程的时候会遇到一些看起来很奇怪的现象。以下是我在编通讯程序时遇到的问题和解决方法: 1、刚开始,按照一般的程序逻辑设置使用XMT和RCV指令。对仪表的轮询都很正常,没有异常情况发生。自以为程序走通了。 2、偶然切断了个别从站(在现场这种情况是很普遍的),发现整个通讯全部歇菜了。重启PLC,头几台仪表的通讯正常,但是到了被切断的从站又OVER了。 3、检查PLC的状态信息,看不出异常。监控RS485总线,发现走过了空站号后PLC的XMT发送不出信息。 4、于是用VB写了一个从站的模拟程序与PLC通讯。从监控上看出,从站有应答,RCV正常处理接受信息后,XMT的发送没问题。而从站没有应答,RCV始终在等待,XMT便无法发送信息。 5、因此PLC端必须考虑终止接收。反复使用了几种方法,最终选用了定时关闭接受功能的方法。 6、在程序的初始化中配置通讯口和接收控制参数,然后将SM87.7(SM187.7)复位。 7、XMT执行后将SM87.7(SM187.7)置位,启动接收以及一个定时器。 8、无论有否应答,都由定时器去处理信息并关闭RCV功能,等待下一个通讯。 9、RCV指令在主程序中由SM0.0使能。这点很重要。因为SM87.7(SM187.7)被修改后,必须执行一次RCV指令才能启停接收功能,所以RCV作为“指令”始终被执行不会影响整个程序的逻辑关系,且程序看上去也简洁,其它地方只要操作SM87.7(SM187.7)即可。 另外,在和一些集成了RS485端口的仪表做通讯时,发现波特率的匹配上会有些问题。主要原因还是对主频进行分频后时钟脉冲引起的误差。这点上西门子的PLC适应性比较强,而合信的PLC适应性差一些。 有网友问到“PLC能否同时与不同波特率的对象通讯”的问题,窃以为可以解决。SMB30(SMB130)随时可以赋值,也就是说用户可以即时修改自由口的配置。按此逻辑,只要在XMT和RCV使能之前定义SMB30(SMB130)就可以了。这一点与VB对COMM口的配置是一样的;如果程序中没有操作COMM配置的指令,VB就按控件特性栏中的配置执行;如果程序中有配置指令,就按程序的配置指令执行。 管理员注:本帖已被纳入此次探讨发帖整理,请点此详阅。
家养老鼠名MINNIE
|
鼠老爹 侠圣 ![]() 经验值:3448 发帖数:2235 精华帖:13 |
116楼
![]() ![]()
不管是什么通讯,传送的都是二进制代码。ASCII码与二进制协议的区别在于代码所表示内容的方式不同。
如果使用ASCII代码,则数据不能直接用于数学运算,而必须转换成普通的二进制代码。这样会加重程序负担。但是ASCII代码用于通讯有一个好处,起始字符与结束字符比较容易确定和判别,它们一般不会出现在数据区。而用二进制代码通讯,数据无需转换即可直接使用(高低位字节可能需要交换),PLC的负担较小。但是起始字符和结束字符经常会与数据重复。因此,用二进制代码通讯,通常是靠字符数和定时器来确定接收终点,主从站之间的步调协调非常重要。 管理员注:本帖已被纳入此次探讨发帖整理,请点此详阅。
家养老鼠名MINNIE
|
yanxiao 版主 ![]() 经验值:26885 发帖数:11964 精华帖:45 |
117楼
![]() ![]()
再谈一个于关通讯效率:
这里的通讯效率问题,针对主站。从站,一般根据主站的请求,及时发回应答就行了,不存在效率问题。 当主站要同多个从站通讯时,就有一个效率问题。以modbus-rtu为例。 1、定时轮询。这恐怕是最原始的方法,也是效率最低下的。比如1秒钟轮询一个站,如果3个从站,要3秒才轮到1次。 2、高效的轮询应该根据协议的定时来调整,尽量挤掉不必要的延时。modbus-rtu,3.5个字节传送时间作为帧间隔,但是从站的回应时间没有标准规定,要先问清楚。一般的仪表,回应时间都是很短的,几十ms内都会有回应,你可以把回应超时设在100ms。当然仪表能提供这个超时参数是最好了。 当主站发完请求帧后,立即进入接收状态,随时准备接收从站的回应。但若到达超时时间还未收到,则放弃继续接收,认为从站无响应,进入下一从站的通讯。 3、如果3个从站只有1个在线上,按理说是通讯速度是最快的,但如果不采取一些策略,则通讯速率会变成最慢的。轮询一个离线的从站,通讯要等到超时才结束,这肯定比在线的从站回应要慢得多,因此大部分时间浪费在离线的从站上了。策略是为每一个从站配置1个在线状态标记位,当从站有成功回应的,标记位=1,表示在线,若该从站连续N次(2次)没有回应或出错,置标记位=0,表示离线。 对于在线的从站,按正常顺序轮询,而离线的从站,则每隔一定时间或每隔一定的轮询周期,发一个请求给它,若有回应且正确,则置标记位为1,认为该从站已回到在线状态,若没有回应或出错,则继续保持离线状态。这样,可以把花在离线从站的通讯时间,控制在一个合理的范围。 管理员注:本帖已被纳入此次探讨发帖整理,请点此详阅。 |
半瓶醋 游侠 ![]() 经验值:522 发帖数:32 精华帖:2 |
126楼
![]() ![]() quote:以下是引用困惑迷茫求助在2011-01-04 09:51:24的发言: 我曾经使用过自由口通信,与36个仪表同时通讯,正常情况下通讯很好,可是只要其中一个仪表出现通讯中断后,整个通讯就全部崩溃,无法执行,请问那位高手能指点下,为什么会出现该问题 与多个设备进行通信时这时常见的问题,主要是因为在程序上缺少对错误时的考虑,也就是只考虑了在正常情况下怎么去进行轮询,而忽略了当伙伴没有响应或响应数据不对时的处理。错误处理的机制和方法在很大程度上影响着通信的质量和效率,而我们往往不注意这方面,高级的开发者一般习惯先考虑错误处理:)。错误处理的方法在于应用者的需求,对于简单的应用可以对错误进行相对简单的处理,比如在规定的时间内,某个伙伴没有响应时直接跳过对这个站的请求。 这里大家也不妨分享一下自己在错误处理方面经常所采用的方法。 管理员注:本帖已被纳入此次探讨发帖整理,请点此详阅。 |
Laohuai 至圣 ![]() 经验值:17410 发帖数:6225 精华帖:18 |
163楼
![]() ![]()
PLC做主站的时候,不管PLC连接的是单从站还是多从站,主站程序都应该考虑到从站会发生故障,从站故障有两种,一种是有故障,但不影响和主站通讯,另一种是有故障,不能和主站通讯,例如从站掉电,通讯线故障或者从站本身故障导致的不能和主站通讯。
对于后者,主站在发送后,从站是不会回复数据的,主站不能等,而应该结束RCV接收状态,然后发送,那么为什么和如何结束RCV接收状态呢? 一 为什么要结束RCV接收状态呢? 发送指令XMT将数据发送出去就完事,而接收RCV不一样,一次完整成功的RCV过程需要以下步骤: 1 使能位:SM87.7=1/SM187.7=1,执行RCV的时候会检查该位 2 执行RCV 3 等待消息起始条件 4 接收信息 5 等待消息结束条件 6 退出接收状态 RCV指令启动后并不一定就接收消息,如果消息起始条件没有达到,那就一直处于等待接收的状态; 如果消息始终没有开始或者结束,通信口就一直处于接收状态。这时如果尝试执行XMT指令,就不会发送任何消息。 所以要结束接收RCV接收状态后才能执行XMT。 二:如何结束RCV接收状态? 手册上给出6种结束条件: 1.结束字符检测 2.字符间计时器 3.信息计时器 4.最大字符计数 5.校验错误 6.用户终止 方法1:前4种条件在从站发生通讯故障后就失效了,必须要配合用户终止 一般执行XMT后,在发送完成中断里执行RCV,同时启动定时中断或者启动定时器或者执行开始间隔时间BITIM,计时时间到复位使能位SM87.7/SM187.7,同时执行RCV,这样结束RCV指令,比如定时中断里发送: LD SM0.0 R SM87.7, 1 RCV VB0, 0 S SM87.7, 1 LD SM0.0 DTCH 10 LD SM0.0 XMT VB100, 0 方法2:设置:SMB87=16#9C, SMW90/SMW190=0,SMW92/SMW192=x 执行RCV指令x毫秒后自动结束接收状态。 如果用的是字符中断方式接收信息,那么将中断分离后即可发送 DTCH 8 XMT VB100, 0 很多人说某个从站故障后,整个通讯就断了,那么问题可能就出在这里。 管理员注:本帖已被纳入此次探讨发帖整理,请点此详阅。 |
鼠老爹 侠圣 ![]() 经验值:3448 发帖数:2235 精华帖:13 |
191楼
![]() ![]() quote:以下是引用lqswyx在2011-01-17 17:51:55的发言: 请教高手: 1.“每接收一个字符会产生一次中断”; 2.“每接收一个结束字符会产生一次中断”。 这两种说法哪种对呀?或者情况不同? 1、“字符中断”指的是SMB2每接收一个字符即产生一次中断。 2、“结束字符中断”指的是接收缓冲区出现指定的结束字符时产生一次中断。 串口通讯协议都是由数个或更多的字符(字节)组成一帧,每个字符都有各自特定的意义。 对S7-200来说,接收到的每个字符都要从SMB2中过一遍。因此对于简单的通讯协议,可以利用SMB2的字符接收中断逐个读取字节,并排列成一个信息帧。但是这样的做法有个缺陷,即SMB2不断地发出中断请求;如果信息帧较长,处理一次所占用的资源较多。一旦出现中断排队,不仅影响其它的程序运行,还有可能影响通讯的准确率。而采用RCV指令的结束字符中断,可以等待通讯的信息帧全部接收完毕(数据保存在接受缓冲区内)再一次性处理这些数据。 管理员注:本帖已被纳入此次探讨发帖整理,请点此详阅。
家养老鼠名MINNIE
|
BABU 游民 ![]() 经验值:55 发帖数:7 精华帖:1 |
194楼
![]() ![]()
我回来了,项目终于做完了,可以回家过年了,:)。
自由口通信真是折腾的我好惨啊,简单回顾一下,希望对像我这样的菜鸟有些借鉴作用。 先感谢一下西门子论坛和热线,没少骚扰他们。 在完全没有准备的情况下甲方又加进一个仪表,做什么自有口通信,晕阿!没办法,迎着上吧! 网上搜资料,看手册,越看越糊涂!时间紧迫,还是直接上手做吧。 首先是把PLC和仪表连接起来,可仪表的口是rs232的,热线工程师告诉我得做rs232/485的转换,打车到市场上买个转换器(打车钱比设备钱还多,可见现场多么偏僻阿),听卖转换器的老板给我分析了一下每种的区别——不光是价格的区别,说实在的,当时非常惭愧,老板懂的比我多多了。 买回来后自己动手焊线,一个人费了九牛二虎之力,焊的那个惨样就不用说了,还好有壳可以包装一下。 焊好了,实验一下效果吧,不知到怎么做了,打电话。 热线工程师告诉我找个串口调试工具,连接到pc机上测试。 在串口调试工具上发一串数,在200上收,ok!高兴坏了,没白忙活。 硬件上应该没问题了,接下来开始做程序了。 先得理解仪表的协议,弄清了仪表先要收到请求数据的命令,然后根据命令做出响应。 同样,先用串口调试工具和仪表连接进行通信测试,还算聪明吧,:)! 然后开始在200里编写收发程序,开始时整个思路都是乱的,无从下手。就把200手册上的例子程序整个抄上,在cpu224的两个接口间进行通信实验。 经过不停的实验,终于一点一点地理解了控制字节、控制参数的含义,怎么设置接收结束条件,怎么使用中断、怎么控制接收和发送等等。 ok,开始真正地与仪表通信了。 发请求命令,收数据,可收到的数据是ASCII码,得进行数据转换。 根据大侠们的提醒,经过实验知道了怎么将ASCII码转换为实际的工程数据。 到此基本结束了,虽然说着好像也没什么,但只有我最了解其中的痛苦,不停地实验,不停地修改阿! 后面在实际运行中又遇到了有时通信中端的问题,将双绞线的屏蔽接到地上后暂时还没出现问题。 总结一下,个人认为作自由口通信需要做好以下几方面工作: 1、最主要的是多动手,光看资料是没有用的,只有自己亲自去动手实验一下才能发现问题和帮助理解。 2、做实验是找个串口调试工具(我用的是sscom32)是必须的,可以帮助你测试你的通信线,调试你的程序,尽量不要直接与设备进行通信,通信不上不好分析原因。 3、我认为200手册上的例子程序非常好,基本的处理方法和编程方法都涉及到了,可以根据你的需要做修改,当然首先要充分地理解他。 4、遇到不太容易理解的,或有问题的,多和别人交流一下,从中可以得到不同的思路。 提前给西门子和坛子里的专家们拜年了! 管理员注:本帖已被纳入此次探讨发帖整理,请点此详阅。
Engineer
|