• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      Delphi開(kāi)發(fā)西門子S7-1200/1500 PLC 以太網(wǎng)心跳通信組件

      2019-01-11 06:00:16
      關(guān)鍵詞:窗體偏移量寄存器

      張 毅

      (東風(fēng)汽車有限公司刃量具廠 刀量具制造管理部, 湖北 十匽 442002)

      0 引 言

      西門子S7-1200/1500系列PLC以太網(wǎng)通信,支持TCP、UDP、ISO_on_TCP通信協(xié)議。此時(shí)PLC作為服務(wù)器端,支持8個(gè)主動(dòng)和8個(gè)被動(dòng)連接。采用Delphi開(kāi)發(fā)PLC客戶端組件,根據(jù)西門子TCP握手通信協(xié)議發(fā)送握手指令與PLC建立連接。當(dāng)連接成功后,遵循TCP讀-寫協(xié)議,定時(shí)器間隔約0.5秒自動(dòng)讀取PLC寄存器,并支持實(shí)時(shí)寫入PLC寄存器,實(shí)現(xiàn)完整的心跳通訊。

      為實(shí)現(xiàn)上述功能,本研究采用Delphi 7開(kāi)發(fā)了Windows規(guī)則DLL模塊,并在DLL內(nèi)部封裝了1個(gè)Form窗口、2個(gè)Timer定時(shí)器和1個(gè)TCPClient控件。當(dāng)DLL被EXE加載時(shí),由DLL啟動(dòng)連接、發(fā)送套接字完成握手,通過(guò)內(nèi)部窗口函數(shù)定時(shí)讀PLC寄存器,實(shí)現(xiàn)寫PLC寄存器函數(shù),并完成接口封裝。上位機(jī)EXE通過(guò)調(diào)用DLL接口,完成實(shí)時(shí)讀寫PLC寄存器功能,程序功能設(shè)計(jì)原理如圖1所示。

      1 硬件配置

      本通信方式基于以太網(wǎng)卡TCP/IP通信協(xié)議。首先采用網(wǎng)線連接PC和PLC網(wǎng)口,使用TIA博途軟件為S7-1200/1500系列PLC配置 IP地址,例如將PLC端IP設(shè)為192.168.0.2,端口號(hào)0,并將PLC配置為TCP Server,不主動(dòng)發(fā)送數(shù)據(jù)模式。在PC端,將本機(jī)IP地址設(shè)為與PLC位于同一網(wǎng)段,使用ping命令,確保能ping通PLC站。

      圖1 EXE應(yīng)用程序調(diào)用DLL實(shí)現(xiàn)PLC心跳通信原理圖

      Fig.1EXEapplicationcallsDLLtorealizePLCheartbeatcommunicationschematicdiagram

      2 實(shí)現(xiàn)過(guò)程

      (1)發(fā)送與接收TCP握手報(bào)文,完成與PLC連接

      在與S7-1200/1500系列PLC建立連接之前,需完成2次握手報(bào)文收發(fā),均為固定格式,代碼示例如下:

      Var Buf_Rec:array[0..99] of Byte; //定義數(shù)據(jù)接收數(shù)組

      發(fā)送第一次握手報(bào)文示例:

      Const Buf_Send1:array[0..21] of Byte=

      (3,0,0,22,17,224,0,0,0,1,0,193,2,16,0,194,2,3,1,192,1,10);

      接收第一次握手報(bào)文返回?cái)?shù)據(jù),判斷Buf_Rec[5]=208表示第一次握手成功,接收?qǐng)?bào)文示例:

      Buf_Rec[]=(3,0,0,22,17,208,0,1,0,17,0,192,1,10,193,2,16,0,194,2,3,1,…)

      發(fā)送第二次握手報(bào)文示例:

      Const Buf_Send2:array[0..24] of Byte =

      (3,0,0,25,2,240,128,50,1,0,0,204,193,0,8,0,0,240,0,0,1,0,1,3,192);

      接收第二次握手報(bào)文返回?cái)?shù)據(jù),判斷Buf_Rec [0] <> 0表示第二次握手成功,握手返回報(bào)文示例:

      Buf_Rec[]=( 3,0,0,27,2,240,128,50,3,0,0,204,193,0,8,0,0,0,0,240,0,0,1,0,1,0,240…)

      發(fā)送代碼示例:

      Form1.TcpClient1.SendBuf(Buf_Send1,SizeOf(Buf_Send1)); //發(fā)送第一次握手指令

      Form1.TcpClient1.SendBuf(Buf_Send1,SizeOf(Buf_Send2)); //發(fā)送第二次握手指令

      接收數(shù)據(jù)代碼示例:

      Form1.TcpClient1.ReceiveBuf(Buf_Rec[0],80); //接收數(shù)據(jù)

      (2)根據(jù)S7-1200/1500系列TCP讀數(shù)據(jù)協(xié)議,實(shí)現(xiàn)讀PLC寄存器值,讀指令代碼示例如下:

      Const ar_bRead:array[0..66] of Byte = ($03,$00, //[0-1]報(bào)頭

      $00,67, //[2-3]整條數(shù)據(jù)長(zhǎng)度

      $02,$F0,$80,$32, //[4-7]固定長(zhǎng)度:4(協(xié)議類型)

      $01, //[8]命令類型:發(fā)

      $00,$00,$00,$01, //[9-12]標(biāo)識(shí)序列號(hào):1(可自定義,與返回?cái)?shù)據(jù)一致)

      $00,50,$00,$00, //[13-16]命令數(shù)據(jù)總長(zhǎng)度:50

      $04, //[17]命令起始符:4

      $04, //[18]讀取數(shù)據(jù)塊個(gè)數(shù):4

      $12,$0A,$10,$02, //[19-22]固定長(zhǎng)度:4(讀取地址前綴)

      $00,$01, //[23-24]讀取數(shù)據(jù)byte個(gè)數(shù):1(8位)

      $00,200, //[25-26]讀取數(shù)據(jù)塊編號(hào):200

      $84, //[27]數(shù)據(jù)塊類型: DB

      $00,$00,0, //[28-30]地址偏移量:0 (DB200.0) = 1 Byte

      $12,$0A,$10,$02, //[31-34]固定長(zhǎng)度:4(讀取地址前綴)

      $00,$01, //[35-36]讀取數(shù)據(jù)byte個(gè)數(shù):1(8位)

      $00,200, //[37-38]讀取數(shù)據(jù)塊編號(hào):200

      $84, //[39]數(shù)據(jù)塊類型: DB

      $00,$00,17, //[40-42]地址偏移量:17 (DB200.2) = 17

      $12,$0A,$10,$02, //[43-46]固定長(zhǎng)度:4(讀取地址前綴)

      $00,$01, //[47-48]讀取數(shù)據(jù)byte個(gè)數(shù):1(8位)

      $00,200, //[49-50]讀取數(shù)據(jù)塊編號(hào):200

      $84, //[51]數(shù)據(jù)塊類型: DB

      $00,$00,81, //[52-54]地址偏移量:81 (DB200.10) = 1 Byte

      $12,$0A,$10,$02, //[43-46]固定長(zhǎng)度:4(讀取地址前綴)

      $00,$01, //[47-48]讀取數(shù)據(jù)byte個(gè)數(shù):1(8位)

      $00,200, //[49-50]讀取數(shù)據(jù)塊編號(hào):200

      $84, //[51]數(shù)據(jù)塊類型: DB

      $00,$00,89); //[52-54]地址偏移量:89 (DB200.11) = 1 Byte

      Var Buf_Read:array[0..66] of Byte; //聲明動(dòng)態(tài)讀數(shù)據(jù)指令數(shù)組

      Move(ar_bRead,Buf_Read,SizeOf(Buf_Read)); //賦值

      發(fā)送讀指令代碼示例: TcpClient1.SendBuf(Buf_Read,SizeOf(Buf_Read));

      TCP讀指令只需通過(guò)Timer控件間隔0.5-0.75秒定時(shí)發(fā)送即可,接收數(shù)據(jù)與(1)所示相同,修改讀指令可對(duì)Buf_Read數(shù)組動(dòng)態(tài)賦值。

      (3)根據(jù)TCP寫數(shù)據(jù)協(xié)議,實(shí)現(xiàn)寫PLC寄存器操作,代碼示例如下:

      Const ar_bWrite:array[0..35] of Byte = ($03,$00,//[0-1]固定報(bào)頭

      $00,36, //[2-3]數(shù)據(jù)總長(zhǎng)

      $02,$F0,$80,$32, //[4-7]固定長(zhǎng)度:4

      $01, //[8]命令類型:發(fā)

      $00,$00,$00,$09, //[9-12]標(biāo)記序列號(hào):9

      $00,$0E, //[13-14]固定長(zhǎng)度:2

      $00,$05, //[15-16]有效數(shù)據(jù)長(zhǎng)度:5(地址偏移量后面第一位開(kāi)始計(jì)算)

      $05, //[17]命令起始符

      $01, //[18]寫數(shù)據(jù)塊個(gè)數(shù):1

      $12,$0A,$10, //[19-21]固定長(zhǎng)度:3 (返回?cái)?shù)據(jù)前綴)

      $02, //[22]寫入方式:$01按bit寫入,$02按byte(8位)寫入

      $00,$01, //[23-24]寫入數(shù)據(jù)個(gè)數(shù):1 (byte方式可多寫,bit方式只能單個(gè)寫)

      $00,200, //[25-26]寫入數(shù)據(jù)塊編號(hào):200

      $84, //[27]數(shù)據(jù)類型:DB塊

      $00,$00,$09, //[28-30]地址偏移量(bit),此處按bit計(jì)算偏移量

      $00,$04, //[31-32]寫入方式: $03按bit寫入, $04按byte(8位)寫入

      $00,8, //[33-34]寫入bit的個(gè)數(shù):8

      9); //[35]寫入的值

      Var Buf_Write:array[0..35] of Byte; //聲明動(dòng)態(tài)寫數(shù)據(jù)指令數(shù)組

      Move(ar_bWrite,Buf_Write,SizeOf(Buf_Write)); //賦值

      修改地址偏移量示例(按位計(jì)算地址):Buf_Write[30] := Byte(1);

      修改寫入值示例:Buf_Write[35] := Byte(i_value);

      發(fā)送寫數(shù)據(jù)指令代碼: TcpClient1.SendBuf(Buf_Write,SizeOf(Buf_Write));

      接收數(shù)據(jù)與(2)所示相同。寫數(shù)據(jù)需通過(guò)DLL接口函數(shù)帶形參(a:寄存器地址,b:待修改的值) ,由EXE調(diào)用實(shí)現(xiàn)。

      (4)在DLL中使用窗體

      Delphi支持在DLL工程內(nèi)部使用窗體。當(dāng)DLL被調(diào)用時(shí),DLL中的窗體被加入調(diào)用方的EXE進(jìn)程,并在DLL被釋放時(shí)銷毀資源。在本例中,首先在DLL工程中添加一個(gè)窗體Form1,在窗體上加入一個(gè)TcpClient控件和PLC通信,一個(gè)1 000 MS定時(shí)器處理PLC握手信號(hào),一個(gè)650MS定時(shí)器用于向PLC定時(shí)接收和發(fā)送指令。然后在Form的Public部分申明被調(diào)用函數(shù)接口,提供給DLL接口函數(shù)使用。示例如下:

      public

      { Public declarations }

      function fun_ReceiveData():Boolean; //接收數(shù)據(jù)函數(shù)

      procedure fun_SendRead; //發(fā)送讀指令

      function fun_ReadHeartTime():Integer; //讀心跳次數(shù)

      function fun_WriteParmData(i_addr,i_value:Integer):Integer; //寫操作

      end;

      在Form的implementation部分寫函數(shù)實(shí)現(xiàn)代碼,DLL接口函數(shù)可直接調(diào)用上述內(nèi)部窗口函數(shù),示例如下:

      function m23s71200_readio(a:integer):integer;export;stdcall; //讀心跳次數(shù)

      begin

      Result := Form1.fun_ReadHeartTime(); //獲取心跳次數(shù)

      end;

      exports m23s71200_writeio; //聲明導(dǎo)出函數(shù)

      由于DLL內(nèi)部封裝了窗體和定時(shí)器控件,在DLL被EXE加載時(shí),內(nèi)部定時(shí)器可通過(guò)接口函數(shù)控制開(kāi)啟或關(guān)閉,也可自動(dòng)開(kāi)啟定時(shí)器維持與PLC心跳通信。EXE定時(shí)從DLL模塊讀數(shù),并通過(guò)DLL接口實(shí)時(shí)向PLC寫值,此調(diào)用方式可簡(jiǎn)化EXE程序設(shè)計(jì),實(shí)現(xiàn)松耦合結(jié)構(gòu)。

      傳統(tǒng)上位機(jī)軟件大多采用IO模塊、繼電器加采集卡等硬接線方式與PLC實(shí)現(xiàn)信號(hào)交互,處理的信息量較小,且占用大量PLC IO端口資源。本研究采用上位機(jī)軟件通過(guò)網(wǎng)線直接讀寫PLC內(nèi)部寄存器,可實(shí)時(shí)監(jiān)控PLC各IO口和DB塊信號(hào)狀態(tài),并通過(guò)實(shí)時(shí)寫寄存器值與S7-1200/1500系列PLC雙向交互信號(hào)。該方法不僅能簡(jiǎn)化通訊設(shè)計(jì),節(jié)約PLC IO資源,降低通信硬件成本,且能極大提高通信信息量,具有IO硬接線無(wú)法比擬的優(yōu)勢(shì)。

      3 結(jié)束語(yǔ)

      在工控領(lǐng)域,本研究采用的方法具有通訊設(shè)計(jì)簡(jiǎn)單、實(shí)施成本低廉、方案靈活性好、通信信息量大等優(yōu)點(diǎn),目前已在多個(gè)工程項(xiàng)目中得到成功應(yīng)用。

      猜你喜歡
      窗體偏移量寄存器
      基于格網(wǎng)坐標(biāo)轉(zhuǎn)換法的矢量數(shù)據(jù)脫密方法研究
      Lite寄存器模型的設(shè)計(jì)與實(shí)現(xiàn)
      試談Access 2007數(shù)據(jù)庫(kù)在林業(yè)檔案管理中的應(yīng)用
      檔案天地(2019年5期)2019-06-12 05:12:02
      攪拌針不同偏移量對(duì)6082-T6鋁合金接頭勞性能的影響
      基于最小二乘平差的全極化SAR配準(zhǔn)偏移量估計(jì)方法
      分簇結(jié)構(gòu)向量寄存器分配策略研究*
      基于LayeredWindow的異形窗體局部刷新
      中文信息(2014年2期)2014-03-06 23:49:14
      巧設(shè)WPS窗體控件讓表格填寫更規(guī)范
      基于Andriod多屏互動(dòng)的遙控器設(shè)計(jì)
      高速數(shù)模轉(zhuǎn)換器AD9779/AD9788的應(yīng)用
      调兵山市| 澄江县| 邳州市| 东至县| 东宁县| 商河县| 和政县| 民乐县| 禄丰县| 茶陵县| 苍梧县| 大关县| 大宁县| 涡阳县| 梧州市| 珠海市| 嘉峪关市| 桂平市| 尉氏县| 调兵山市| 绥阳县| 海丰县| 丰原市| 荆门市| 揭阳市| 望城县| 丰台区| 洪泽县| 金阳县| 新兴县| 共和县| 金秀| 广灵县| 中西区| 邮箱| 突泉县| 枝江市| 盖州市| 汶上县| 山阴县| 金门县|