ppi协议的编写

evapengfei 贡献于2017-05-08

作者 微软中国  创建于2010-12-01 12:00:00   修改者微软中国  修改于2010-12-01 12:01:00字数32197

文档摘要:
关键词:

 SD LE LEr SD DA SA FC DSAP SSAP DU FCS ED ///////////////////////////////////////// SD:开始符(68H) LE、Ler:长度(从DA到DU) DA:目的地址 SA:源地址 FC:功能码 (6CH) DSAP:目的服务存取点 SSAP:源服务存取点 DU:数据单元 FCS:校验和 ED:结束符(16H) //////////////////////////////////////// 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 一次读一条数据 对于一次读取一个数据,读命令都是33个字节。前面的0—21字节是相同的,为 : 68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 01 00 01 00 00 82 00 00 00 64 16 读q0.0 68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 01 00 01 00 00 83 00 00 00 65 16 读m0.0 68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 01 00 01 00 00 83 00 00 01 66 16 读M0.1 68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 02 00 01 00 00 05 00 01 10 F9 16 读SMB34 68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 02 00 01 00 01 84 00 03 20 8B 16 读VB100 68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 04 00 01 00 01 84 00 03 20 8D 16 读VW100 68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 06 00 01 00 01 84 00 03 20 8F 16 读vd100 68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 01 00 01 00 00 81 00 00 05 68 16 读i0.5 68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 01 00 01 00 00 81 00 00 07 6A 16 读i0.7 /////////////////////////////////////////////////////////////////////////////////////////////////////////// Byte 22 读取数据的长度 01:1 Bit 02:1 Byte 04:1 Word 06:Double Word 读取长度 数据个数 存储器类型 存储器偏移量指针 校验和 结束 Byte 24数据个数 这里是01 ,一次读多个数据时见下面的说明。 Byte 26 存储器类型 01:V存储器 00:其它 Byte 27 存储器类型 04:S 05:SM 06:AI 07:AQ 1E: C 81:I 82:Q 83:M 84:V 1F: T Byte 28,29,30存储器偏移量指针(存储器地址*8),如:VB100,存储器地址为100,偏移量指针为800,转换成16进制就是 320H,则Byte 28—29这三个字节就是:00 03 20。 Byte 31 校验和,前面已说到这是从(DA+SA+DSAP+SSAP+DU) Mod 256 。 一次读多条数据 对于一次读多个数据的情况,前21Byte与上面相似只是长度LD,LDr及Byte 14不同: Byte 14 数据块占位字节,它指明数据块占用的字节数。与数据块数量有关,长度=4+数据块数*10,如:一条数据时为 4+10=0E(H);同时读M,V,Q三个不同的数据块时为4+3*10=22(H)。 Byte 22 总是02 即以Byte为单位。 Byte 24 以字节为单位,连续读取的字节数。如读2个VD则Byte24=8 Byte 19---30 按上述一次读一个数据的格式依次列 出, Byte 31---42 另一类型的数据,也是按上述格式给出。 以此类推,一次最多读取222个字节的数据。 //////////////////////////////////////// 写命令分析 一次写一个Double Word类型的数据,写命令是40个字节,其余为38个字节。 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 写一个Double Word类型的数据,前面的0—21字节为 : 68 23 23 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 写一个其它类型的数据,前面的0—21字节为 :(与上面比较,只是长度字节发生变化) 68 21 21 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 从22字节开始根据写入数据的值和位置不同而变化。表二是几个写命令的Byte22—40。 字 节 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 写入位置及值 长度 数据个数 存储器类型 存储器偏移量指针 位数 值、校验码、结束符 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 M0.0=1 01 00 01 00 00 83 00 00 00 00 03 00 01 01 00 71 16 M0.0=0 01 00 01 00 00 83 00 00 00 00 03 00 01 00 00 70 16 M0.1=1 01 00 01 00 00 83 00 00 01 00 03 00 01 01 00 72 16 vb100=10 02 00 01 00 01 84 00 03 20 00 04 00 08 10 00 AE 16 vb100=FF 02 00 01 00 01 84 00 03 20 00 04 00 08 FF 00 9D 16 VW100=FFFF 04 00 01 00 01 84 00 03 20 00 04 00 10 FF FF A6 16 VD100=FFFFFFFF 06 00 01 00 01 84 00 03 20 00 04 00 20 FF FF FF FF B8 16 表二 写命令的Byte22—40 经分析我们可以得出以下结果: Byte 22-- Byte 30 写入数据的长度、存储器类型、存储器偏移量与读命令相同。T,C等不能用写命令写入。 Byte 32 如果写入的是位数据这一字节为03,其它则为04 Byte 34 写入数据的位数 01: 1 Bit 08: 1 Byte 10H: 1 Word 20H: 1 Double Word Byte 35--40值、校验码、结束符 如果写入的是位、字节数据,Byte35就是写入的值,Byte36=00,Byte37=检验码,Byte38=16H,结束。如果写个的是字数据(双字节),Byte35,Byte36就是写入的值, Byte37=检验码,Byte38=16H,结束。如果写个的是双字数据(四字节),Byte35—38就是写入的值, Byte39=检验码,Byte40=16H,结束。 3.3 其它命令分析 强制写入 I、Q、S 等不能使用上述的写命令写入数据,只能用强制写入的方式。 前0—35字节值如下(长度字段要根据实际情况而定),需要注意的是Byte8=07, 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 68 2B 2B 68 02 00 6C 32 07 00 00 00 00 00 0C 00 12 00 01 12 08 12 48 0B 00 00 00 00 00 FF 09 00 0E 00 01 10 后面的内容如下: Byte 32 占 位字节,从下一字节开始到校验和前的字节数。说明同读数据的Byte 14. Byte 36 强制写入数据的长度 01:1 Bit 02:1 Byte 04:1 Word 06:Double Word Byte 38 数据个数,这里是01 ,一次强制写多个数据时见下面的说明。 Byte 40 存储器类型 Byte 41 存储器类型,见读命令的说明。 Byte 42、43、44存储器偏移量指针(存储器地址*8) Byte 45、46、47、48 值、校验码、结束符 取消强制写 强制写入I、Q 等后,这些值就不能被程序改变,除非使用”取消强制命令”。 取消强制命令的格式与强制写入相似,变化的有以下几点:(1)是没有”值”这一段,即没有Byte45—48。这影响到长度字节LE,LEr;占位字节Byte 32. (2)Byte16=10H, (3) Byte32=0CH,也就是第一条,没有”值”这一段,数据块长度变短了。 对于一次强制写入或取消多个数据的情况可以参照写入命令写出相应的报文,这里不再给出。 STOP命令 STOP命令使得S7-200 CPU从RUN状态转换到STOP状态(此时CPU模块上的模式开关开应打在RUN或TERM位置)。PC发出如下命令,PLC返回F9,此时PLC已进入等待状态,PC再发确认报文(10 02 5C 5E 16),完成一个命令过程。 68 1D 1D 68 02 00 6C 32 01 00 00 00 00 00 10 00 00 29 00 00 00 00 00 09 50 5F 50 52 4F 47 52 41 4D AA 16 RUN 命令 RUN命令使得S7-200 CPU从STOP状态转换到RUN状态(此时CPU模块上的模式开关开应打在RUN或TERM位置)。PC发出下命令,PLC返回F9,此时PLC已进入运行状态,PC再发确认报文(10 02 5C 5E 16),完成一个命令过程。 68 21 21 68 02 00 6C 32 01 00 00 00 00 00 14 00 00 28 00 00 00 00 00 00 FD 00 00 09 50 5F 50 52 4F 47 52 41 4D AA 16 3.4 读出数据分析 一次读出一条数据 PLC响应的数据也是用PPI封装的。如果用一次读一条数据命令,响应的报文中就只包含一条数据,此响应报文的Byte16<=8。 Byte 04:DA=00 Byte 05:SA=02 即从02 PLC站发往PC。 Byte 16:数据块占位字节,从Byte21到校验和前的字节数。 一条数据时:Word=06 Double Word=08 其它为 05。 Byte 22:数据类型,位=3,其它=4。 Byte 24:数据宽度,Bit=01,Byte=08,Word=10H,Double Word=20H Byte 25—28:值。 如果网络上只可能有一个站会发回响应报文,那么可以简单的根据LE长度字节判断返回值的位置:LE=16H,返回值是字节,或位类型的值,响应报文的Byte 25即是返回值;LE=17H,返回值是字(双字节)类型的值,响应报文的Byte 25,26即是返回值;LE=19H,返回值是双字(四字节)类型的值,响应报文的Byte 25—28即是返回值。更准确的方式是要根据返回报文的SA,DA,及存储器位置等信息识别目标地址和源地址,确认是这次申请的返回数据,然后经过校验检查,得到正确的数据。 一 次读出多条数据 如果用的是一次读多条数据的命令,响应的报文中就包含有多条数据。这些数据只有类型参数,没有偏移量参数,所以要注意根据读命令的顺序将其一一对应起来。 Byte 16:数据块占位字节,从Byte21到校验和前的字节数,与数据块数量和类型有关。 Byte 20:数据块的个数。 Byte 21 开始为数据块,每一个数据块都以FF 04开始,接下来的两个字节表示这一数据块的长度,以位计算,然后依次是连续的数据。下一个数据块也是以FF 04开始,重复上述格式,直到结束。 4 应用 PC与与PLC通讯 在采用PC机与PLC通讯时,计算机采用PPI电缆或普通的485串口卡与PLC的编程口连接, PC机采用VB编程,遵循PPI协议,主从式的通讯方式,一次读写操作的步骤包括:首先上位机发出读写命令,PLC作出接收正确的响应(返回应答数据E5H),上位机接到此响应则发出确认命令(10 02 5C 5E 16),PLC完成正确的读写响应,返回给上位机相应数据。这样收发两次数据,完成一次数据的读写。那么我们就可以利用上述 PPI协议,读写S7-200PLC中的各种类型数据,包括I、Q、SM、M、V、T、C、S等数据类型,能够直接读出以上变量中的位、字节、字、双字等,(其中读位变量时,实际是读取该位所在的字节值)。可以改变PLC的运行状态(RUN/STOP)。 在编程时,最好将读取的检测值、输出值等数据,存放在PLC的一个连续的变量区中,当上位机读取PLC的数据时,就可以一次读出这组连续的数据,减少数据的分次频繁读取。当修改设定值等数据时,进行写数据的通讯操作。 现场设备与PLC通讯 利用PPI协议除了能与上位机(PC)通讯外,更重要的是为现场设备与S7-200CPU之间的通讯提供了捷径。自行开发的设备可以方便的利用 PPI协议通过485/232接口接入S7-200CPU,联入PLC的网络,包括控制面板,采集器等。 5 总结 通过分析STEP7 Micro/win32软件与S7-200CPU的通讯数据,我们得到了西门子PPI协议的关键报文格式,这一结果对工程实践具有较高的参考价值。在不使用西门子或其它组态软件的情况下,利用分析得到的PPI协议实现了上位机对PLC的监控。现场设备与PLC通讯方面的工作正在进行中。另外这种对通讯端口进行监测、分析的方法也对一些未知协议的测定和通讯错误的检查具有指导意义。 西门子PPI通讯协议 S7-200 PLC之PPI协议 通过硬件和软件侦听的方法,分析PLC内部固有的PPI通讯协议,然后上位机采用VB编程,遵循PPI通讯协议,读写PLC数据,实现人机操作任务。这种通讯方法,与一般的自由通讯协议相比,省略了PLC的通讯程序编写,只需编写上位机的通讯程序资源 S 7-226的编程口物理层为RS-485结构,SIEMENS提供MicroWin软件,采用的是PPI(Point to Point)协议,可以用来传输、调试PLC程序。在现场应用中,当需要PLC与上位机通讯时,较多的使用自定义协议与上位机通讯。在这种通讯方式中,需要编程者首先定义自己的自由通讯格式,在PLC中编写代码,利用中断方式控制通讯端口的数据收发。采用这种方式,PLC编程调试较为烦琐,占用PLC的软件中断和代码资源,而且当PLC的通讯口定义为自由通讯口时,PLC的编程软件无法对PLC进行监控,给PLC程序调试带来不便。 SIEMENS S7-200PLC的编程通讯接口,内部固化的通讯协议为PPI协议,如果上位机遵循PPI协议来读写PLC,就可以省略编写 PLC的通讯代码。如何获得PPI协议?可以在PLC的编程软件读写PLC数据时,利用第三个串口侦听PLC的通讯数据,或者利用软件方法,截取已经打开且正在通讯的端口的数据,然后归纳总结,解析出PPI协议的数据读写报文。这样,上位机遵循PPI协议,就可以便利的读写PLC内部的数据,实现上位机的人机操作功能。 软件设计 系统中测控任务由SIEMENS S7-226PLC完成,PLC采用循环扫描方式工作,当定时时间到时,执行数据采集或PID控制任务,完成现场的信号控制。计算机的监控软件采用VB编制,利用MSComm控件完成串口数据通讯,通讯遵循的协议为PPI协议。 PPI协议 西门子的PPI(Point to Point)通讯协议采用主从式的通讯方式,一次读写操作的步骤包括:首先上位机发出读写命令,PLC作出接收正确的响应,上位机接到此响应则发出确认申请命令,PLC则完成正确的读写响应,回应给上位机数据。这样收发两次数据,完成一次数据的读写[5]。 其通讯数据报文格式大致有以下几类: 1、读写申请的数据格式如下: SD LE LER SD DA SA FC DASP SSAP DU FCS ED SD:(Start Delimiter)开始定界符(68H) LE:(Length)报文数据长度 LER:(Repeated Length)重复数据长度 SD: (Start Delimiter)开始定界符(68H) SA:(Source Address)源地址,指该地址的指针,为地址值乘以8 DA:(Destination Address)目标地址,指该地址的指针,为地址值乘以8 FC:(Function Code)功能码 DSAP:(Destination Service Access Point)目的服务存取点 SSAP:(Source Service Access Point)源服务存取点 DU:(Data Unit)数据单元 FCS:(Frame Check Sequence)校验码 ED:(End Delimiter)结束分界符(16H) 报文数据长度和重复数据长度为自DA至DU的数据长度,校验码为DA至DU数据的和校验,只取其中的末字节值。 在读写PLC的变量数据中,读数据的功能码为 6CH,写数据的功能码为 7CH。 2、PLC接收到读写命令,校验后正确,返回的数据格式为 E5H 3 、确认读写命令的数据格式为: SD SA DA FC FCS ED 其中SD为起始符,为10H SA为数据源地址 DA为目的地址 FC为功能码,取5CH FCS为SA+DA+FC的和的末字节 ED为结束符,取16H PPI协议的软件编制 在采用上位机与PLC通讯时,上位机采用VB编程,计算机采用PPI电缆或普通的485串口卡与PLC的编程口连接,通讯系统采用主从结构,上位机遵循PPI协议格式,发出读写申请,PLC返回相应的数据。程序实现如下: 1、串口初始化程序: MSComm1.CommPort = 1 MSComm1.Settings = "9600,e,8,1" MSComm1.InputLen = 0 MSComm1.RThreshold = 1 MSComm1.InputMode = comInputModeBinary PPI协议定义串口为以二进制形式收发数据,这样报文的通讯效率比ASCII码高。 2、串口读取数据程序,以读取VB100数据单元为例: Dim Str_Read(0 To 32) ‘定义发送的数据为字节为元素的数组。 Str_ Read (32) = &H16 ‘相应的数组元素赋值,按照以下格式: Str_ Read (29) = (100*8) \ 256 ‘地址为指针值,先取高位地址指针 Str_ Read (30) = (100*8) Mod 256 ‘取低位地址指针 Str_ Read (24) = 1 ‘读取的数据长度(Byte的个数) For I=4 to 30 Temp_FCS = Temp_FCS + Str_Read(i) Next I Str_Read(31)= Temp_FCS Mod 256 ‘计算FCS校验码,其它数组元素赋值省略。 68 1B 1B 68 2 0 6C 32 1 0 0 0 0 0 E 0 0 4 1 12 A 10 2 0 1 0 1 84 0 3 20 8B 16 PLC返回数据 E5 后,确认读取命令,发送以下数据: 10 2 0 5C 5E 16 然后上位机VB程序接受到以下数据: 68 16 16 68 0 2 8 32 3 0 0 0 0 0 2 0 5 0 0 4 1 FF 4 0 8 22 78 16 首先识别目标地址和源地址,确认是这次申请的返回数据,然后经过校验检查,正确后解析出第26号数据(&H22)即为VB100字节的数据。 3、串口写入数据程序,以写VB100数据单元为例: Dim Str_Write(0 To 37) ‘定义发送的数据为字节为元素的数组。 Str_Write (37) = &H16 ‘相应的数组元素赋值,按照以下格式 Str_Write (35) = &H10 ‘要写入的数据值 68 20 20 68 2 0 7C 32 1 0 0 0 0 0 E 0 5 5 1 12 A 10 2 0 1 0 1 84 0 3 20 0 4 0 8 C B9 16 PLC返回数据 E5 后,确认写入命令,发送以下数据: 10 2 0 5C 5E 16 然后上位机VB程序接受到以下数据: 68 12 12 68 0 2 8 32 3 0 0 0 0 0 2 0 1 0 0 5 1 FF 47 16 这是PLC正确接收并写入信息的返回数据。 4、串口接收程序: 在数据接收程序中,利用VB中MSComm控件,一次接收缓冲区中的全部数据,存放到数组形式的暂存单元中,然后分析每个元素的值,得到读写的数据。 Dim RCV_Array() As Byte Dim Dis_Array As String Dim RCV_Len As Long RCV_Array = MSComm1.Input ‘取出串口接收缓冲器的数据。 RCV_Len = UBound(RCV_Array) ReDim Temp(0 To UBound(RCV_Array)) For i = 0 To RCV_Len Dis_Array = Dis_Array & Hex(RCV_Array (i)) & " " Next i Text1 .Text = Dis_Array ‘接收到的数据送显示。 在程序的读写过程中,一次最大可以读写222个字节,目前给出的数据读写为整数格式。 数据类型 Str_ Read(27) S 04H SM 05H I 81H Q 82H M 83H V 84H 以上程序,是以读写PLC的V变量区为例,利用PPI协议还可以读写S7-200PLC中的各种类型数据,包括I、Q、SM、M、V、T、C、S 等数据类型,能够直接读出以上变量中的位、字节、字、双字等,其中读位变量时,是读取该位所在的字节值,然后上位机自动识别出该位的值。按照读写的数据类型,其中Str_ Read(27)的值各不同: 在控制系统中,PLC与上位计算机的通讯,采用了PPI通讯协议,上位机每0.5秒循环读写一次PLC。PLC编程时,将要读取的检测值、输出值等数据,存放在PLC的一个连续的变量区中,当上位机读取PLC的数据时,就可以一次读出这组连续的数据,减少数据的分次频繁读取。当修改设定值等数据时,进行写数据的通讯操作。 2、PLC接收到读写命令,校验后正确,返回的数据格式为 E5H 3、确认读写命令的数据格式为: SD SA DA FC FCS ED SD SA DA FC FCS ED 其中SD为起始符,为10H SA为数据源地址 DA为目的地址 FC为功能码,取5CH FCS为SA+DA+FC的和的末字节 ED为结束符,取16H 10 2 0 5C 5E 16 VERSION 5.00 Object = "{8D5F39A6-EF30-4558-AC0F-E43789C0D87F}#1.0#0"; "S7_PPI.ocx" Begin VB.Form frmTest BorderStyle = 3 'Fixed Dialog Caption = "PPI Client demo" ClientHeight = 3255 ClientLeft = 735 ClientTop = 330 ClientWidth = 5970 LinkTopic = "Form1" LockControls = -1 'True MaxButton = 0 'False MinButton = 0 'False ScaleHeight = 3255 ScaleWidth = 5970 StartUpPosition = 3 '窗口缺省 Begin PPI.S7_PPI S7_PPI1 Left = 945 Top = 1710 _ExtentX = 3784 _ExtentY = 2672 End Begin VB.Frame Frame2 Caption = "发送数据/修改数据" Height = 1905 Left = 210 TabIndex = 3 Top = 1080 Width = 5565 Begin VB.TextBox txtAddr Height = 285 Left = 1080 TabIndex = 11 Text = "0" Top = 330 Width = 465 End Begin VB.CommandButton cmdReadData Caption = "读" Height = 315 Left = 4230 TabIndex = 10 Top = 720 Width = 555 End Begin VB.ComboBox cmbNum Height = 300 Left = 2130 Style = 2 'Dropdown List TabIndex = 9 Top = 330 Width = 675 End Begin VB.TextBox txtData Height = 585 Left = 210 MultiLine = -1 'True TabIndex = 8 Top = 1110 Width = 5145 End Begin VB.ComboBox cmbType Height = 300 ItemData = "frmTest.frx":0000 Left = 3450 List = "frmTest.frx":0016 Style = 2 'Dropdown List TabIndex = 7 Top = 330 Width = 645 End Begin VB.CommandButton cmdWriteData Caption = "写" Height = 315 Left = 4800 TabIndex = 6 Top = 720 Width = 555 End Begin VB.CheckBox chkRun Alignment = 1 'Right Justify Caption = "连续读" ForeColor = &H00FF8080& Height = 345 Left = 3120 TabIndex = 5 Top = 720 Width = 885 End Begin VB.Timer tmrRead Enabled = 0 'False Interval = 1000 Left = 5370 Top = 690 End Begin VB.ComboBox cmbLen Height = 300 ItemData = "frmTest.frx":002D Left = 4710 List = "frmTest.frx":003A Style = 2 'Dropdown List TabIndex = 4 Top = 330 Width = 645 End Begin VB.Label Label1 Caption = "变量地址:" Height = 285 Index = 0 Left = 210 TabIndex = 16 Top = 390 Width = 1065 End Begin VB.Label lblLen Caption = "个数:" Height = 285 Index = 1 Left = 1620 TabIndex = 15 Top = 390 Width = 705 End Begin VB.Label Label1 Caption = "类型:" Height = 285 Index = 2 Left = 2940 TabIndex = 14 Top = 390 Width = 705 End Begin VB.Label Label1 Caption = "数据:" Height = 285 Index = 3 Left = 210 TabIndex = 13 Top = 780 Width = 1065 End Begin VB.Label lblLen Caption = "类别:" Height = 285 Index = 0 Left = 4200 TabIndex = 12 Top = 390 Width = 1125 End End Begin VB.Frame Frame4 Caption = "PLC连接" Height = 795 Left = 210 TabIndex = 0 Top = 120 Width = 5565 Begin VB.CommandButton cmdLogin Caption = "登录" Height = 345 Left = 2880 TabIndex = 19 Top = 270 Width = 795 End Begin VB.CommandButton cmdRun Caption = "运行" Height = 345 Left = 3720 TabIndex = 18 Top = 270 Width = 795 End Begin VB.CommandButton cmdStop Caption = "停止" Height = 345 Left = 4560 TabIndex = 17 Top = 270 Width = 795 End Begin VB.ComboBox cmbNo Height = 300 Left = 600 Style = 2 'Dropdown List TabIndex = 2 Top = 300 Width = 2115 End Begin VB.PictureBox picFlag BackColor = &H000000FF& Height = 315 Left = 150 ScaleHeight = 255 ScaleWidth = 285 TabIndex = 1 Top = 300 Width = 345 Begin VB.PictureBox picOk Appearance = 0 'Flat BackColor = &H000000FF& ForeColor = &H80000008& Height = 105 Left = 180 ScaleHeight = 75 ScaleWidth = 75 TabIndex = 20 Top = 150 Width = 105 End End End End Attribute VB_Name = "frmTest" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False '************************************************************************* '**模 块 名:frmTest '**说 明:YFsoft 版权所有2005 - 2006(C) '**创 建 人:叶帆 '**日 期:2005-08-23 14 :45:36 '**修 改 人: '**日 期: '**描 述:PPIClient 控件示例(需连接西门子200PLC) '** 非注册版本只能读取变量区的前10个地址,注册用户读写数据无限制,也无用户个数限制 '** 获取注册图片后,直接拷贝到控件的当前目录即可完成注册,注意在程序中添加下面一行代码: '** S7_PPI1.RegCompany="×××公司" 公司名称要和你注册提交的公司名称一致 '** 最新版本请关注:http://blog.csdn.net/yefanqiu '**在线注册:http://www.softreg.com.cn/shareware_view.asp?id=/B22DAFDD-B3F4-424C-9FCC-1B4C5DCBD898/ '**版 本:V1.0.0 '************************************************************************* '************************************************************************* '**函 数 名:chkRun_Click '**输 入:无 '**输 出:无 '**功能描述:连续读取PLC数据 '**全局变量: '**调用模块: '**作 者:叶帆 '**日 期:2005-08-28 11:11:25 '**修 改 人: '**日 期: '**版 本:V1.0.0 '************************************************************************* Private Sub chkRun_Click() tmrRead.Enabled = IIf(chkRun.Value = 0, False, True) End Sub '************************************************************************* '**函 数 名:cmdLogin_Click '**输 入:无 '**输 出:无 '**功能描述:登录指定地址的PLC '**全局变量: '**调用模块: '**作 者:叶帆 '**日 期:2005-07-26 20:39:33 '**修 改 人: '**日 期: '**版 本:V1.0.0 '************************************************************************* Private Sub cmdLogin_Click() If S7_PPI1.PlcLogin(cmbNo.ListIndex + 1) = 0 Then picFlag.BackColor = RGB(0, 255, 0) picOk.BackColor = RGB(0, 255, 0) Else picFlag.BackColor = RGB(255, 0, 0) picOk.BackColor = RGB(255, 0, 0) End If End Sub '************************************************************************* '**函 数 名:cmdSendData_Click '**输 入:无 '**输 出:无 '**功能描述:读PLC数据 '**全局变量: '**调用模块: '**作 者:叶帆 '**日 期:2005-08-27 23:59:32 '**修 改 人: '**日 期: '**版 本:V1.0.0 '************************************************************************* Private Sub cmdReadData_Click() On Error GoTo ToExit '打开错误陷阱 '------------------------------------------------ Dim i As Long Dim bytType As Byte Dim lngData() As Long Select Case cmbType.ListIndex Case 0: bytType = PPI_I Case 1: bytType = PPI_Q Case 2: bytType = PPI_M Case 3: bytType = PPI_V Case 4: bytType = PPI_S Case 5: bytType = PPI_SM End Select S7_PPI1.FixAddr = cmbNo.ListIndex + 1 If S7_PPI1.Re adData(Val(txtAddr), lngData(), Val(cmbNum.Text), Val(cmbLen.ListIndex), Val(bytType)) = 0 Then txtData = "" For i = 1 To Val(cmbNum.Text) txtData = txtData & Format(lngData(i - 1), "0") & " " Next Else txtData = "Error" End If '------------------------------------------------ Exit Sub '---------------- ToExit: MsgBox Err.Description End Sub '************************************************************************* '**函 数 名:cmdRun_Click '**输 入:无 '**输 出:无 '**功能描述:使PLC运行 '**全局变量: '**调用模块: '**作 者:叶帆 '**日 期:2005-07-26 20:55:15 '**修 改 人: '**日 期: '**版 本:V1.0.0 '************************************************************************* Private Sub cmdRun_Click() Dim lngRet As Long lngRet = S7_PPI1.PlcRun(cmbNo.ListIndex + 1) If lngRet = 0 Then picFlag.BackColor = RGB(0, 255, 0) picOk.BackColor = RGB(0, 255, 0) Else picOk.BackColor = RGB(255, 0, 0) End If If lngRet = 4 Then MsgBox "PLC拨码开关在停止位置" End If End Sub '************************************************************************* '**函 数 名:cmdStop_Click '**输 入:无 '**输 出:无 '**功能描述:停止PLC运行 '**全局变量: '**调用模块: '**作 者:叶帆 '**日 期:2005-07-26 21:03:23 '**修 改 人: '**日 期: '**版 本:V1.0.0 '************************************************************************* Private Sub cmdStop_Click() If S7_PPI1.PlcStop(cmbNo.ListIndex + 1) = 0 Then picFlag.BackColor = RGB(255, 255, 0) picOk.BackColor = RGB(0, 255, 0) Else picOk.BackColor = RGB(255, 0, 0) End If End Sub '************************************************************************* '**函 数 名:cmdWriteData_Click '**输 入:无 '**输 出:无 '**功能描述: '**全局变量: '**调用模块: '**作 者:叶帆 '**日 期:2005-08-28 11:43:08 '**修 改 人: '**日 期: '**版 本:V1.0.0 '************************************************************************* Private Sub cmdWriteData_Click() On Error GoTo ToExit '打开错误陷阱 '------------------------------------------------ Dim bytType As Byte Dim strData() As String Dim lngData() As Long Dim i As Long Select Case cmbType.ListIndex Case 0: bytType = PPI_I Case 1: bytType = PPI_Q Case 2: bytType = PPI_M Case 3: bytType = PPI_V Case 4: bytType = PPI_S Case 5: bytType = PPI_SM End Select If Len(txtData) > 0 Then strData = Split(txtData, " ") ReDim lngData(UBound(strData)) For i = 0 To UBound(strData ) lngData(i) = Val(strData(i)) Next If S7_PPI1.WriteData(Val(txtAddr), lngData, UBound(strData) + 1, Val(cmbLen.ListIndex), Val(bytType), cmbNo.ListIndex + 1) = 0 Then ' Else txtData = "Error" End If End If '------------------------------------------------ Exit Sub '---------------- ToExit: MsgBox Err.Description End Sub '************************************************************************* '**函 数 名:Form_Load '**输 入:无 '**输 出:无 '**功能描述: '**全局变量: '**调用模块: '**作 者:叶帆 '**日 期:2005-08-28 19:07:04 '**修 改 人: '**日 期: '**版 本:V1.0.0 '************************************************************************* Private Sub Form_Load() Dim i As Long For i = 1 To 222 cmbNo.AddItem Format(i, "0") Next For i = 1 To 100 cmbNum.AddItem Format(i, "0") Next cmbNum.ListIndex = 0 cmbNo.ListIndex = 0 cmbType.ListIndex = 3 cmbLen.ListIndex = 0 S7_PPI1.InitRegCompany "×××公司" '已注册的公司名称 S7_PPI1.OpenPort 1 '打开连接PLC的COM1接口 End Sub '************************************************************************* '**函 数 名:Form_Unload '**输 入:Cancel(Integer) - '**输 出:无 '**功能描述:关闭串口 '**全局变量: '**调用模块: '**作 者:叶帆 '**日 期:2005-08-23 14:40:05 '**修 改 人: '**日 期: '**版 本:V1.0.0 '************************************************************************* Private Sub Form_Unload(Cancel As Integer) S7_PPI1.ClosePort End End Sub '************************************************************************* '**函 数 名:S7_PPI1_ErrorMessge '**输 入:msgNo(Integer) - 信息号 '** :msgDescription(String) - 信息内容 '**输 出:无 '**功能描述:控件的事件 '**全局变量: '**调用模块: '**作 者:叶帆 '**日 期:2005-11-18 11:06:48 '**修 改 人: '**日 期: '**版 本:V1.0.0 '************************************************************************* Private Sub S7_PPI1_ErrorMessge(msgNo As Integer, msgDescription As String) MsgBox Str(msgNo) & " - " & msgDescription End Sub '************************************************************************* '**函 数 名:tmrRead_Timer '**输 入:无 '**输 出:无 '**功能描述: '**全局变量: '**调用模块: '**作 者:叶帆 '**日 期:2005-08-28 11:10:58 '**修 改 人: '**日 期: '**版 本:V1.0.0 '************************************************************************* Private Sub tmrRead_Timer() cmdReadData_Click End Sub 西门子S7-200系列PLC PPI协议及PPI动态链接库DLL(需VB、Delphi DEMO程序请回贴并留下Emial地址) 一、西门子S7-200系列PLC PPI协议动态链接库DLL(以下简称DLL),是为满足工业通信需要,针对工业领域要求上位机对西门子S7-200系列 PLC 实时采集与控制的组态编程而设计。本DLL是采用Delphi语言开发的标准串口通讯库,具有以下特点: 1)、实时性、可靠性好,可根据通信数据量自行调整通信时间; 2)、适用于多PLC联网和上位机通信,满足多方面的需要; 3)、函数接口功能全,操作简单; 4)、附加实用转换与读取函数,易于快速开发(VC等非RAD开发环境的开发); 5)、支持USB、PC扩展卡等扩展串口号; 6)、支持多种操作系统win9x/win2000/winXP(标注Win32 DLL); 7)、可在多种编程环境下使用,例如VB、VC、Delphi等开发环境。 二、PPI协议简介及S7-200CPU内存地址范围介绍 2.1 西门子PPI通讯协议 通过硬件和软件侦听的方法,分析PLC内部固有的PPI通讯协议,然后采用上位机编程,遵循PPI通讯协议,读写PLC数据,实现人机操作 任务。这种通讯方法,与一般的自由通讯协议相比,省略了PLC的通讯程序编写,只需编写上位机的通讯程序资源S7-226的编程口物理层为 RS-485结构,SIEMENS提供MicroWin软件,采用的是 PPI(Point to Point)协议,可以用来传输、调试PLC程序。在现场应用中,当需要PLC 与上位机通讯时,较多的使用自定义协议与上位机通讯。在这种通讯方式中,需要编程者首先定义自己的自由通讯格式,在PLC中编写代码, 利用中断方式控制通讯端口的数据收发。采用这种方式,PLC编程调试较为烦琐,占用PLC的软件中断和代码资源,而且当PLC的通讯口定义 为自由通讯口时,PLC的编程软件无法对PLC进行监控,给PLC程序调试带来不便。 SIEMENS S7-200PLC的编程通讯接口,内部固化的通讯协议为PPI协议,如果上位机遵循PPI协议来读写PLC,就可以省略编写PLC的通讯 代码。如何获得PPI协议?可以在PLC的编程软件读写PLC数据时,利用第三个串口侦听PLC的通讯数据,或者利用软件方法,截取已经打开 且正在通讯的端口的数据,然后归纳总结,解析出 PPI协议的数据读写报文。这样,上位机遵循PPI协议,就可以便利的读写PLC内部的数据, 实现上位机的人机操作功能。 西门子的PPI(Point to Point)通讯协议采用主从式的通讯方式,一次读写操作的步骤包括:首先上位机发出读写命令,PLC作出接收正确 的响应,上位机接到此响应则发出确认申请命令,PLC则完成正确的读写响应,回应给上位机数据。这样收发两次数据,完成一次数据的读写 (从这里可以看出PPI协 议的通讯效率并不好,一次读写需收发两次数据^_^)。 其通讯数据报文格式大致有以下几类: 1)、读写申请的数据格式如下: SD LE LER SD DA SA FC DASP SSAP DU FCS ED SD: (Start Delimiter)开始定界符(68H) LE:(Length)报文数据长度 LER: (Repeated Length)重复数据长度 SD: (Start Delimiter)开始定界符(68H) SA: (Source Address)源地址,指该地址; DA:(Destination Address)目标地址,指该地址; FC: (Function Code)功能码 DSAP:(Destination Service Access Point)目的服务存取点 SSAP: (Source Service Access Point)源服务存取点 DU:(Data Unit)数据单元 FCS: (Frame Check Sequence)校验码 ED:(End Delimiter)结束分界符(16H) 报文数据长度和重复数据长度为自DA至DU的数据长度,校验码为DA至DU数据的和校验,只取其中的末字节值。 读写一般数据的功能码为 6CH,读CT数据、置位、复位、强制等的功能码为 7CH,确认命令功能码5CH。 2)、PLC接收到读写命令,校验后正确,返回的数据格式为 E5H 3)、确认读写命令的数据格式为: SD SA DA FC FCS ED 其中SD为起始符,为10H SA为数据源地址 DA为目的地址 FC为功能码,取5CH FCS 为SA+DA+FC的和的末字节 ED为结束符,取16H 4)、数据类型码 04:S 05:SM 06:AI 07:AQ 1E: C 81:I 82:Q 83:M 84:V 1F: T 5)、读写功能数据命令实例 1、给写VW3值1200 68 21 21 68 02 00 6C 32 01 00 00 00 00 00 0E 00 06 05 01 12 0A 10 02 00 02 00 01 84 00 00 18 00 04 00 10 04 B0 50 16 2、读取IB0的数据值 68 1B 1B 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 02 00 01 00 00 81 00 00 00 64 16 感兴趣的朋友给你根据上述例子用串口精灵测试一下,当发送命令成功PLC返回E5,你再发送10 02 00 5C 5E 16,就可以完成一次读写命令。 (记得接收和发送采用16进制方式 o(∩_∩)o...哈哈) 2.2 S7-200PLC CPU内存地址范围(DLL所能寻址的范围) 被存取: 类型 CPU 221 CPU 222 CPU 224 CPU 226 位(字节. 位) V 0.0-2047.7 0.0-2047.7 0.0-5119.7 V 1.22 0.0-5119.7 V 1.23 0.0-8191.7 V 2.00 0.0-10239.7 V 2.00 0.0-10239.7 XP I 0.0-15.7 0.0-15.7 0.0 -15.7 0.0-15.7 Q 0.0-15.7 0.0-15.7 0.0 -15.7 0.0-15.7 M 0.0-31.7 0.0-31.7 0.0 -31.7 0.0-31.7 S 0.0-31.7 0.0-31.7 0.0 -31.7 0.0-31.7 SM 0.0-179.7 0.0-299.7 0.0 -549.7 0.0-549.7 字节 VB 0 - 2047 0 - 2047 0 - 5119 V 1.22 0 - 5119 V 1.23 0 - 8191 V 2.00 0 - 10239 V 2.00 0 - 10239 XP IB 0 - 15 0 - 15 0 - 15 0 - 15 QB 0 - 15 0 - 15 0 - 15 0 - 15 MB 0 - 31 0 - 31 0 - 31 0 - 31 SB 0 - 31 0 - 31 0 - 31 0 - 31 SMB 0 - 179 0 - 299 0 - 549 0 - 549 字 VW 0 - 2046 0 - 2046 0 - 5118 V 1.22 0 - 5118 V 1.23 0 - 8190 V 2.00 0 - 10230 V 2.00 0 - 10230 XP T 0 - 255 0 - 255 0 - 255 0 - 255 C 0 - 255 0 - 255 0 - 255 0 - 255 AIW 0 - 30 0 - 30 0 - 62 0 - 62 AQW 0 - 30 0 - 30 0 - 62 0 - 62 双字 VD 0 - 2044 0 - 2044 0 - 5116 V 1.22 0 - 5116 V 1.23 0 - 8188 V 2.00 0 - 10236 V 2.00 0 - 10236 XP 说明:S7-200PLC的字、双字地址和字节地址实际上是重叠的,下面做个说明如: VB0 VB1 VB2 VB3 VB4 VB5 VB6 VB7 VB8 VB9 VB10 VB11 VB12 VB13 VB14 VB15 ———— ———— ———— ———— ———— ———— ———— ———— VW0 VW2 VW4 VW6 VW8 VW10 VW12 VW14 ————————— ————————— ————————— ——————————— VD0 VD4 VD8 VD12 从上例可以看出PLC中字节、字与双字寻址的关系,当然如果你想使用VW1(VB1 VB2)、VD3(VB3 VB4 VB5 VB6)等寻址方式也是可以的, 但为了减少不必要的寻址错误造成程序的非法执行建议: 字寻址时使用(V、I、Q、M等等)0、2、4、6、8、 10 ……,(这从PLC的模拟量输入/输出(AIW/AQW)的寻址就可以看出奇数地址是不允许的) 双字寻址时使用(V、I、Q、M等等)0、4、8、12、16、20、24 …………………………,同时还要注意字节地址寻址最好也能不重叠; C、T区当前值读取时的地址按实际地址0~255来。 三、DLL函数说明 1、打开串口 Function ComOpen(nport,BaudRate,DataBits,Parity,StopBits:longint;User:Pchar):longint;stdcall; 参数:nport: 打开串口号,取值为1~8,代表COM1~COM8; BaudRate:波特率,取值为:1200、2400、4800、9600、19200、38400; DataBits:数据位,取值为5、 6、7、8; Parity: 校验位,取值1(代表Even)、取值2(代表Odd)、取值3(代表Mark)、取值 4(代表Space)、取值5(代表None); StopBits:停止位,取值1(代表1位停止位)、取值2(代表 2位停止位)、取值3(代表1.5位停止位); User:DLL授权用户名; 返回值:长整型,操作成功返回 “1” 或“2”;1表示注册授权用户,2表示用户未注册; 操作不成功返回为“0”时的原因:1)、串口不存在或被占用; 2)、DLL注册授权不正确。 注:本DLL用户不注册除了下面说明的功能限制外没有其他限制,未注册用户请使用特定用户名:wangjun。 注册用户功能上无任何限制,且将得到永久的软件使用和更新升级服务; 使用举例: Delphi:ComOpen(1,9600,8,1,1,Pchar('wangjun')) , 打开COM1口。 VB:ComOpen(1,9600,8,1,1,"wangjun") , 打开COM1口。 2、关闭串口 Function ComClose(nport:longint):longint;stdcall; 参数:nport: 串口号,取值为1~8,代表COM1~COM8; 返回值:长整型,操作成功返回“1”,否则返回“0”; 使用举例: ComClose(1) ,关闭打开的COM1口。 3、PLC内部元件读取功能函数 注:PLC 内部元件与数字的对应关系(DLL中的所有函数都遵循此规定): 0 : I 1 : Q 2 : M 3 : V 4 : S 5 : SM 6 : AI 7 : AQ 8 : C 9 : T 注:下面的读写等PLC操作函数使用举例都是按VB调用函数形式给出。 1)、字节元件数据读取 Function FcnBread(nport,purpose,source,name,address,Count:longint):Pchar;stdcall; 参数: nport: 串口号,取值为1~8,代表COM1~COM8; purpose:目标地址,取值0~126; source: 源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的) name: 取值0(代表I)、取值1(代表Q)、取值2(代表M)、取值3(代表V)、取值4(代表S)、取值5(代表SM); address: 元件地址,取值为请参照 2.2 S7-200PLC CPU内存地址范围; Count: 读取的字节个数,最多读取128个但不能超出寻址范围; 返回值:字符串数据,字符串数据的终止符为"@"; 使用举例: FcnBread(1,0,2,0,2,4),由COM1读取PPI 2号站 数据到0号站(计算机)IB2~IB5四个字节的值,如返回值为“01FF6403@”, 则表示 IB2=01, IB3=FF,IB4=64,IB5=03; ---------- -- 字符串返回序列: | 01 | FF | 64 | 03| @ | ---------- -- 返回值为16进制字符串,将返回值如上2位一组,可转换成“0~255”间的整数值。 在读取错误或不能读取的情况下返回“Error@” 注:没有注册用户不能读取S、SM区字节值,可寻址范围IB0~IB1、QB0~QB1、MB0~MB1、VB0~VB1; 2)、字元件数据读取 Function FcnWread(nport,purpose,source,name,address,Count:longint):Pchar;stdcall; 参数: nport: 串口号,取值为1~8,代表COM1~COM8; purpose:目标地址,取值0~126; source: 源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的) name: 取值3(代表V)、取值6(代表AI)、取值8(代表C)、取 值9(代表T); address: 元件地址,取值为请参照 2.2 S7-200PLC CPU内存地址范围; Count: 读取的字个数,最多读取64个但不能超出寻址范围,T区读取时不超过44个; 返回值:字符串数据,字符串数据的终止符为"@"; 使用举例: FcnWread(1,0,2,3,0,4), 由COM1读取PPI 2号站 数据到0号站(计算机)VW0~VW6四个字的值,如返回值为“006403E804B00010@”, 则表示VW0=0064, VW2=03E8,VW4=04B0,VW6=0010; ----------------- 字符串返回序列: | 0064 | 03E8 | 04B0 | 0010 | @ | ----------------- 返回值为16进制字符串,将返回值如上4位一组,可转换成无符号“0~65535”或有符号“-32768 ~ +32767”间的整数值。 如果你从PLC中读取的是有符号的数时,这个值小于等于32767,就得到你读的实际值,例如读到一个值“5EEE”转换成整数24302, 则实际值=+(24302-0)=+24302;如果大于32767,例如我读到一个值“8FC0”先转换成整数36800,那实际值=-(36800-32768)=-4032。 在读取错误或不能读取的情况下返回“Error@” 注:没有注册用户不能读取C、T区字当前值,可寻址范围VW0~VW8、AIW0~AIW2; 3)、双字元件数据读取 Function FcnDWread(nport,purpose,source,name,address,Count:longint):Pchar;stdcall; 参数: nport: 串口号,取值为1~8,代表COM1~COM8; purpose:目标地址,取值0~126; source: 源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的) name: 取值3(代表V); address: 元件地址,取值为请参照 2.2 S7-200PLC CPU内存地址范围; Count: 读取的双字个数,最多读取32个但不能超出寻址范围; 返回值:字符串数据,字符串数据的终止符为"@"; 使用举例: FcnDWread(1,0,2,3,0,2), 由COM1读取PPI 2号站 数据到0号站(计算机)VW0~VW6四个字的值,如返回值为“006403E804B00010@”, 则表示VD0=006403E8,VD4=04B00010; -------------- 字符串返回序列: | 006403E8 | 04B00010 | @ | -------------- 返回值为16进制字符串,将返回值如上8位一组,可转换成无符号“0~4294967295”或有符号 “-2147483648 ~ +2147483647”间的整数值。 如果你从PLC中读取的是有符号的数时,这个值小于等于 2147483647,就得到你读的实际值,例如读到一个值“5EEE8000”转换成整数 为1592688640,则实际值=+ (1592688640-0)=+1592688640;如果大于2147483647,例如我读到一个值“8FEFC000”先转换成整数 2414854144, 那实际值=-(2414854144-2147483648)=-267370496。 在读取错误或不能读取的情况 下返回“Error@” 注:没有注册用户可寻址范围VD0~VD4; 4)、位元件的状态读取 Function FcnBitread(nport,purpose,source,name,address,Bit:longint):longint;stdcall; 参数: nport: 串口号,取值为1~8,代表COM1~COM8; purpose:目标地址,取值0~126; source: 源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的) name: 取值0(代表I)、取值1(代表Q)、取值2(代表M)、取值3(代表V)、取值4(代表S)、取值5(代表SM); address: 元件地址,取值为请参照 2.2 S7-200PLC CPU内存地址范围; Bit: 读取的字节元件的位地址如I1.0指I1字节元件的第0位; 返回值: 长整数,返回为0表示状态为OFF,返回为1表示状态为ON,返回为-1表示读取错误或不能读取; 使用举例: FcnBitread(1,0,2,0,1,7), 由COM1读取PPI 2号站 数据到0号站(计算机)I1.7,如返回值为1,则表示I1.7=1; 注:没有注册用户不可以读取S、 SM区状态,可寻址范围I0.0~I1.7、Q0.0~Q1.7、M0.0~M1.7、V0.0~V1.7; 4、PLC内部元件写数据功能函数 1)、字节元件数据写入 Function FcnBwrite(nport,purpose,source,name,address,Count:longint;Sendstr:Pchar):longint;stdcall; 参数: nport: 串口号,取值为1~8,代表COM1~COM8; purpose:目标地址,取值0~126; source: 源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的) name: 取值0(代表I)、取值1(代表Q)、取值2(代表M)、取值3(代表V)、取值4(代表S); address: 元件地址,取值为请参照 2.2 S7-200PLC CPU内存地址范围; Count: 写入字节个数,这里1字节应写入2位16进制字符串; Sendstr: 给字节写入的值,该值为2个一组的16进制字符串组其取值为00~FF(整数值为0~255); 返回值: 长整数,操作成功返回1,不能写入或操作错误返回0; 当要写入多个字节值时依次排列即可。如给MB0与MB1写值100和80,先将100转成16进制字符串64、80 转成16进制字符串50,则sendstr=6450;一次最多写128个字节即字符串长应小于等于256; ---------- - ~ - ------ 写字符串序列如: | 00 | FF | 10 | 64 | ~ | 08 | 04 | ---------- - ~ - ------ 实际字符串与位地址的数值应如下表:(将上例的字节MB0'、MB1'转换为位地址M0.0~M1.7由下表对应,此对应也可以应用于字节读取) M: 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0.0 1.7 1.6 1.5 1.4 1.3 1.2 1.1 1.0 --------------------------------- 位地址: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | --------------------------------- 各位赋值: | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | --------------------------------- 16 进制串: | 6 | 4 | 5 | 0 | --------------------------------- 使用举例: FcnBwrite(1,0,2,2,0,2,"6450")由COM1 0号站(计算机) 写入PPI 2号站 数据 MB0=64(10进制100)、MB1=50(10进制80),操作成功返回1; 注:没有注册用户不能写S区字节值,可寻址范围 IB0、QB0、MB0、VB0; 2)、字元件数据写入 Function FcnWwrite(nport,purpose,source,name,address,Count:longint;Sendstr:Pchar):longint;stdcall; 参数: nport: 串口号,取值为1~8,代表COM1~COM8; purpose:目标地址,取值0~126; source: 源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的) name: 取值3(代表V)、取值7(代表AQ); address: 元件地址,取值为请参照 2.2 S7-200PLC CPU内存地址范围; Count: 写入字个数,这里1字应写入4位16进制字符串; Sendstr: 给字节写入的值,该值为4个一组的16进制字符串组其取值为 0000~FFFF(整数值为0~65535); 返回值: 长整数,操作成功返回1,不能写入或操作错误返回0; 当要写入多个字节值时依次排列即可。如给VW2与VW4写值100和1000,先将100转成16进制字符串0064、1000转成16进制字符串03E8, 则 sendstr=006403E8;一次最多写64个字即字符串长应小于等于256; ---------- ---- ~ --------- 写字符串序列如: | 0064 | 03E8 | 0010 | 6004 | ~ | 0008 | 0400 | ---------- ---- ~ --------- 使用举例: FcnWwrite(1,0,2,3,2,2,"006403E8")由COM1 0号站(计算机) 写入PPI 2号站 数据VW2=0064(10进制100)、VW4=03E8(10进制1000), 操作成功返回1; 注:没有注册用户不能写AQ区字值,可寻址范围VW0; 3)、双字元件数据写入 Function FcnDWwrite(nport,purpose,source,name,address,Count:longint;Sendstr:Pchar):longint;stdcall; 参数: nport: 串口号,取值为1~8,代表COM1~COM8; purpose:目标地址,取值0~126; source: 源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的) name: 取值3(代表V); address: 元件地址,取值为请参照 2.2 S7-200PLC CPU内存地址范围; Count: 写入双字个数,这里1双字应写入8位16进制字符串; Sendstr: 给字节写入的值,该值为8个一组的16进 制字符串组其取值为00000000~FFFFFFFF(整数值为 0~4294967295); 返回值: 长整数,操作成功返回1,不能写入或操作错误返回0; 当要写入多个字节值时依次排列即可。如给VD0与VD4写值10000和8000,先将10000转成16进制字符串00002710、8000转成16进制字符串 为 00001F40,则sendstr=0000271000001F40;一次最多写32个双字即字符串长应小于等于256; ---------- - ~ ------------ 写字符串序列如: | 00000064 | 00002710 | ~ | 10000008 | 04008010 | ---------- - ~ ------------ 使用举例: FcnDWwrite(1,0,2,3,0,2,"0000271000001F40")由COM1 0号站(计算机) 写入PPI 2号站 数据VD0=00002710(10进制10000)、 VD4=00001F40(10进制8000),操作成功返回1; 注:没有注册用户可寻址范围VD0; 4)、位元件的置位 Function FcnSet(nport,purpose,source,name,address,Bit:longint):longint;stdcall; 参数: nport: 串口号,取值为1~8,代表COM1~COM8; purpose:目标地址,取值0~126; source: 源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的) name: 取值2(代表M)、取值3(代表V)、取值4(代表S); address: 元件地址,取值为请参照 2.2 S7-200PLC CPU内存地址范围; Bit: 置位的字节元件的位地址如S1.0指S1字节元件的第0位; 返回值: 长整数,操作成功返回1,不能置位或操作错误返回0; 使用举例: FcnSet(1,0,2,2,2,6),由COM1 0号站(计算机) 置位PPI 2号站 M2.6,如返回值为1,则表示置位成功; 注:没有注册用户可寻址范围M0.0~M0.7、V0.0~V0.7、S0.0~S0.7; 5)、位元件的复位 Function FcnReset(nport,purpose,source,name,address,Bit:longint):longint;stdcall; 参数: nport: 串口号,取值为1~8,代表COM1~COM8; purpose:目标地址,取值0~126; source: 源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的) name: 取值2(代表M)、取值3(代表V)、取值4(代表S); address: 元件地址,取值为请参照 2.2 S7-200PLC CPU内存地址范围; Bit: 复位的字节元件的位地址如M1.0指M1字节元件的第0位; 返回值: 长整数,操作成功返回1,不能复位或操作错误返回0; 使用举例: FcnReset(1,0,2,3,2,6),由COM1 0号站(计算机) 复位PPI 2号站 V2.6,如返回值为1,则表示复位成功; 注:没有注册用户可寻址范围M0.0~M0.7、V0.0~V0.7、S0.0~S0.7; 5、 I/Q元件的强制功能 (未注册用户不可使用) 注:关于强制功能,如果你再操作时给一个元件强制了值,PLC程序的正常功能将不能改变被强值元件的状态,所 以在不需要对 某个元件进行强制时请使用取消强制函数,来取消对该位的强制状态,但取消强制状态并不改变元件的通段状态。 1)、位元件的强制置位 Function FcnEset(nport,purpose,source,name,address,Bit:longint):longint;stdcall; 参数: nport: 串口号,取值为1~8,代表COM1~COM8; purpose:目标地址,取值0~126; source: 源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的) name: 取值0(代表I)、取值1(代表Q); address: 元件地址,取值为请参照 2.2 S7-200PLC CPU内存地址范围; Bit: 置位的字节元件的位地址如I1.0指I1字节元件的第0位; 返回值: 长整数,操作成功返回1,不能置位或操作错误返回0; 使用举例: FcnEset(1,0,2,0,0,6),由COM1 0号站(计算机) 置位PPI 2号站 I0.6,如返回值为1,则表示置位成功; 注:没有注册用户不可以使用; 2)、位元件的强制复位 Function FcnEreset(nport,purpose,source,name,address,Bit:longint):longint;stdcall; 参数: nport: 串口号,取值为1~8,代表COM1~COM8; purpose:目标地址,取值0~126; source: 源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的) name: 取值0(代表I)、取值1(代表Q); address: 元件地址,取值为请参照 2.2 S7-200PLC CPU内存地址范围; Bit: 复位的字节元件的位地址如Q1.0指Q1字节元件的第0位; 返回值: 长整数,操作成功返回1,不能复位或操作错误返回0; 使用举例: FcnEreset(1,0,2,1,2,6),由COM1 0号站(计算机) 复位PPI 2号站 Q2.6,如返回值为1,则表示复位成功; 注:没有注册用户不可以使用; 3)、位元件取消强制 Function FcnECancel(nport,purpose,source,name,address,Bit:longint):longint;stdcall; 参数: nport: 串口号,取值为1~8,代表COM1~COM8; purpose:目标地址,取值0~126; source: 源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的) name: 取值0(代表I)、取值1(代表Q); address: 元件地址,取值为请参照 2.2 S7-200PLC CPU内存地址范围; Bit: 取消强制的字节元件的位地址如Q1.0指Q1字节元件的第0位; 返回值: 长整数,操作成功返回1,不能复位或操作错误返回0; 使用举例: FcnECancel(1,0,2,1,2,6),由COM1 0号站(计算机) 取消PPI 2号站 Q2.6的强制转状态,如返回值为1,则表示取消强制成功; 注:没有注册用户不可以使用; 6、PLC运行函数(该函数可在Run、Stop功能选项开关打在Run上且PLC处于停止模式时可将PLC转换到运行模式) Function FcnRun(nport, purpose,source:longint):Longint;stdcall;stdcall; 参数: nport: 串口号,取值为1~8,代表COM1~COM8; purpose:目标地址,取值0~126; source: 源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的) 返回值: 长整数,操作成功返回1,不能复位或操作错误返回0; 使用举例: FcnRun(1,0,2),由COM1 0号站(计算机) 使PPI 2号进入运行模式,如返回值为1,则表示运行成功; 注:没有注册用户不可以使用; 7、PLC停止函数(该函数可在Run、Stop 功能选项开关打在Run上且PLC处于运行模式时可将PLC转换到停止模式) Function FcnStop(nport,purpose,source:longint):Longint;stdcall; 参数: nport: 串口号,取值为1~8,代表COM1~COM8; purpose:目标地址,取值0~126; source: 源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的) 返回值: 长整数,操作成功返回1,不能复位或操作错误返回0; 使用举例: FcnStop(1,0,2),由COM1 0号站(计算机) 使PPI 2号进入停止模式,如返回值为1,则表示停止成功; 注:没有注册用户不可以使用; 四、DLL附加函数说明 (本段函数对未注册用户没有限制,完全可以使用。) 1、串口打开状态的读取 Function ComTrue(nport:longint):longint;stdcall; 参数: noprt: 串口号,取值为1~8,代表COM1~COM8; 返回值:长整型,串口成功打开返回“1”,否则返回 “0”; 2、整数转换成16进制字符串 (为VC等非RAD开发环境所增设) Function CIntToHex(Dcint,Digits:Longint):Pchar;stdcall; 参数: Cint: 待转换整数,取值为(0~65535); Digits: 转换的字符串位数,指定位数小于实际位数时按实际输出; 在参数错误等非法的情况下返回“Error@” 使用举例: CIntToHex(200,2), 则返回字符串“C8@”; CIntToHex(200,4),则返回字符串“00C8@”; CIntToHex(200,8),则返回字符串“000000C8@”; CIntToHex(4500,4),则返回字符串“1194@”; CIntToHex(4500,3), 则返回字符串“1194@”,因为“194”不足以表示4500这个数所以按实际输出字符串“1194@”; "@"为字符串数据的终止符。 3、16进制字符串转换成整数 (为VC等非RAD开发环境所增设) Function CHexToInt(CHex:Pchar):Longint;stdcall; 参数: CHex: 待转换字符串,取值为(0000~FFFF); 使用举例: CHexToInt("03E8"), 则返回整数1000; 注:在参数不正确等出错情况下返回值为“-1”。 4、抽取(0~65535)所示整数中 (0~15)某个位的值 Function CinBin(CHex,Start:longint):longint;stdcall; 参数: CHex: 待转换整数,取值为0~65535(0000~FFFF); Start: 抽取的位,取 值为(0~15); 使用举例: CinBin(15,3),则返回值1; CinBin(15,4),则返回值0; CinBin(1000,6), 则返回值1; 读取MB0组合成的字节值为“FC”(252)时,要读取M0.1的值时,则调用CinBin(252,1)返回值0表示 M0.1的值为0。 注:在参数不正确等出错情况下返回值为“-1”。 5、返回字符串Text左边的Count个字符 (为VC等非RAD开发环境所增设) Function CLeftStr(Text:Pchar;Count:longint):Pchar;stdcall; 参数: Text: 字符串原型; Count: 指定返回左侧字符串个数; 在参数错误等非法的情况下返回 “Error@” 使用举例: CleftStr("123456", 3) = "123@"; "@"为字符串数据的终止符。 6、返回字符串Text右边的Count个字符 (为VC等非RAD开发环境所增设) Function CRightStr(Text:Pchar;Count:longint):Pchar;stdcall; 参数: Text: 字符串原型; Count: 指定返回右侧字符串个数 在参数错误等非法的情况下返回 “Error@” 使用举例: CRightStr("123456", 3) = "456@"; "@" 为字符串数据的终止符。 7、返回字符串Text从Start开始的Count个字符 (为VC等非RAD开发环境所增设) Function CMidStr(Text:Pchar;Start,Count:longint):Pchar;stdcall; 参数: Text: 字符串原型; Start: 指定返回字符串的起始位置; Count: 指定返回字符串个数; 在参数错误等非法的情况下返回“Error@” 使用举例: CMidStr("123456",2,3) = "234@"; "@" 为字符串数据的终止符。 8、字符串Cstr开始于字符串Ostr的位置 (为VC等非RAD开发环境所增设) Function Cinstr(Ostr,Ckstr:Pchar;Dcint:Longint):Longint;stdcall; 参数: Ostr: 字符串原型; Cstr: 查询的字符串; Dcint: 设定查询字符串的起始位置,取值>=1,即最少从源字符串的第一个字符开始查询; 返回值:长整型; 使用举例: CinStr("1Tfdg23456","2",2) = 6 注:在参数不正确等出错情况下返回值为“0”。 9、PC喇叭的报警过程函数; Function MyBeep(SoundHz:longint):longint;stdcall; 参数:SoundHz:长整型; 返回值:长整型,操作成功返回“1”,否则返回“0”。 使用举例: MyBeep(2000); 按 2000的频率发出报警声。 DLL中关于传出字符串值的函数都以"@"为字符串函数值终止符,这是对多开发环境应用时方便用户正确读取返回字符串数据而设。 五、详细的DLL使用请参DEMO程序或DLL手册(DLL手册提供VB、VC、Delphi的调用说明),相关 DEMO程序和说明所使用的开发环境 VB指的是VB6.0,Delphi指的是Delphi6.0/Delphi7.0,VC指的是 VC6.0。如果使用了高版本开发环境请根据开发软件更新后所兼容 的声明方式进行声明调用。 作者: wjun7610 QQ: 157610979 淘宝店:http://shop34821629.taobao.com

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享文档获得金币 ] 0 人已下载

下载文档