西門子Prodave60在C中地應(yīng)用_第1頁
西門子Prodave60在C中地應(yīng)用_第2頁
西門子Prodave60在C中地應(yīng)用_第3頁
西門子Prodave60在C中地應(yīng)用_第4頁
西門子Prodave60在C中地應(yīng)用_第5頁
已閱讀5頁,還剩12頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、合用文案近來在做一個數(shù)據(jù)采集項目,涉及到好多與西門子S7系列PLC的通訊,由于自己的VC水平屬于半瓶子晃悠,所以就想利用C#來進行開發(fā)(個人比較喜歡C#的代碼風(fēng)格,看著很清爽),誠然C#這種高級語言與基層的設(shè)備通訊效率確實不如C+,但幸好數(shù)據(jù)量不大,實時性要求不算太高,用C#還是可以應(yīng)付的。在界面開發(fā)方面,高級語言確實不如WinCC,Intouch之類的組態(tài)軟件,但在數(shù)據(jù)辦理上面,卻有很大的靈便性。在這里很感謝吳旭日,在中國工控網(wǎng)上面發(fā)現(xiàn)了他的文章,由于我是從C#轉(zhuǎn)到工控方向的,以前對PLC一點都不懂,剛接觸這一行時,學(xué)習(xí)起來很費力,看了他的這篇文章,讓我對PLC的有了更加深入的認識。我的這個

2、DCProdave.cs就是在他的基礎(chǔ)上更正的,加了一些自己的東西。還望各位多多提建議,多多交流!Prodave版本:PRODAVE6.0-W95_S7.DLLPLC模擬環(huán)境:PLCSIMV5.4開發(fā)環(huán)境:VS.NET2005.從w95_s7.dll中導(dǎo)入PLC通訊件數(shù)的方法DllImport在使用DllImport以前,必定引入InteropServices,代碼以下:usingSystem.Runtime.InteropServices;詳細使用方法可以參照我的博客中轉(zhuǎn)載的一篇文章C#(.net)中的DllImport用法轉(zhuǎn)寫的很不錯,千萬要注意C+數(shù)據(jù)種類到C#的對應(yīng)關(guān)系,采用合適的種類

3、。比方char*可以用string來變換,指針種類可以ref也許數(shù)組。二.定義結(jié)構(gòu)體種類2.1PLC連接參數(shù)結(jié)構(gòu)體/定義結(jié)構(gòu)體連接PLC所需參數(shù)publicstructPLCConnParam標準文檔合用文案4publicbyteAddres;/定義CPU的MPI/DP地址5/publicbyteSegmentId;/保留為06publicbyteRack;/定義CPU的機架號7publicbyteSlot;/定義CPU的槽號82.2PLC儲藏地域種類編號/定義列舉種類PLC的儲藏地域編號publicenumPLCBlockTypeI=1,/InputbytesQ=2,/Outputbytes

4、M=3,/FlagbytesT=4,/TimerwordsZ=5,/CounterwordsD=6,/DatafromDB10三.常用函數(shù)詳細講解3.1建立PLC連接函數(shù)第一從W95_S7.DLL中導(dǎo)入連接函數(shù),接見權(quán)限為私有,C#將會對此函數(shù)進行封裝,供外面調(diào)用,稍后講解./與PLC建立連接,該函數(shù)必定在其他全部函數(shù)調(diào)用以前被調(diào)用/標準文檔合用文案3/連接數(shù),在DOS,WIN3.1最多可以有4個,在WIN95以上最多可以有16個4/與PLC通訊的設(shè)備名稱,一般為S7ONLINE/參數(shù)列表,4個值分別為MPI/DP地址,保留值=0,槽號,機架號6/0正常返回,非0為錯誤號7DllImport(

5、w95_s7.dll)8privateexternstaticintload_tool(bytenr,stringdevice,byte,adr_table);說明:在一個MPI/DP網(wǎng)絡(luò)中若有多個PLC時,可指定多個連接列。最后一列的全部參數(shù)須置0,以標志參數(shù)列結(jié)束。比方一個MPI/DP網(wǎng)中有兩個PLC,他們的MPI地址分別為2和3,槽號均為2,機架號均為0,則可按以下方式調(diào)用:byte,ba=2,0,2,0,3,0,2,0,0,0,0,0;interr=load_tool(1,s7online,ba);返回值為int型,若是返回0則表示執(zhí)行成功,非零值,則需要依照錯誤號查找到錯誤詳細信息,

6、詳細參照本文第五部分:錯誤代碼字典自然若是PLC使用的是DP網(wǎng)絡(luò)時,只需要將SetPG/PCInterface中接口參數(shù)分配選為PLCSIM(PROFIBUS)即可,Prodave不需要做任何更正(自然PLC地址必定也是DP口的地址哦),詳細以下圖:標準文檔合用文案個人不太習(xí)慣西門子的這種函數(shù)命名,干脆就依照C#的常用習(xí)慣,進行一下簡單的封裝,供外面調(diào)用.1/建立連接,同一個連接只同意調(diào)用一次2/3/連接號connNo為1-44/連接參數(shù),PLCConnParam定義的參數(shù)結(jié)構(gòu)體5/返回10進制錯誤號,0表示沒有錯誤6publicstaticintOpen(byteconnNo,PLCConn

7、ParamconnParam)intPLCCPUCnt=connParam.Length;9if(PLCCPUCnt=0)/傳達參數(shù)不正確return-1;標準文檔合用文案1213byte,btr=newbytePLCCPUCnt+1,4;/多分配1個,用于存放0作為連接結(jié)束標志/變換連接表for(inti=0;iconnParam.Length;i+)17btri,0=connParami.Addres;18btri,1=0;19btri,2=connParami.Slot;20btri,3=connParami.Rack;2122btrconnParam.Length,0=0;23btrc

8、onnParam.Length,1=0;24btrconnParam.Length,2=0;25btrconnParam.Length,3=0;/調(diào)用初始化函數(shù),打開連接27interrCode=load_tool(connNo,S7ONLINE,btr);28returnerrCode;29建立于PLC的連接,只需在數(shù)采程序啟動的時候調(diào)用即可,并且只能打開一次,否則報錯.驅(qū)動設(shè)備名稱S7ONLINE,一般情況下是不會有變化的,所以這里就寫死了.特別需要指出的是,這個函數(shù)的第一個參數(shù)(連接號),是指當(dāng)前連接有多少個PLC連接(嚴格意義上來講,是CPU的個數(shù),由于有可能2個PLC共用1個CPU,

9、之間經(jīng)過IM467組態(tài)),激活連接并交換數(shù)據(jù)的時候,和這個值有點關(guān)系.在建立連接的時候默認激活第1個連接.標準文檔合用文案3.2斷開與PLC的連接從W95_S7.DLL中導(dǎo)入函數(shù),仍舊是私有,由于我要對全部的導(dǎo)入函數(shù)進行封裝.1/斷開與PLC的連接,必定退出數(shù)采軟件以前調(diào)用,否則PLC的連接素來被占用,影響下次連接2/3/0正常返回,非0為錯誤號4DllImport(w95_s7.dll)5privateexternstaticintunload_tool();關(guān)閉PLC的連接函數(shù)進行C#封裝,沒有改變?nèi)魏未a,可是換了個函數(shù)名.publicstaticintClose()returnunlo

10、ad_tool();3.3激活連接,當(dāng)前連接列中某個時刻有且只有1個PLC是激活狀態(tài).建立連接的時候,默認激活第1個連接.1/激活與MPI網(wǎng)中的哪個CPU通訊,load_tool后默認激活第一個CPU連接2/3/連接號,對應(yīng)于參數(shù)adr_table所傳達的連接參數(shù)序次4/0正常返回,非0為錯誤號,若激活的連接在MPI網(wǎng)中沒有,則返回錯誤號5175DllImport(w95_s7.dll)6privateexternstaticintnew_ss(byteno);標準文檔合用文案其參數(shù)與load_tool中參數(shù)adr_table所傳達的連接參數(shù)序次對應(yīng)比方byte,btr=2,0,2,0,3,0

11、,2,0,0,0,0,0,new_ss(1)則激活第1個連接即與MPI地址為2的PLC通訊,近似的new_ss(2)則激活與MPI地址為3的PLC通訊,在數(shù)采系統(tǒng)中,為了讀取全部PLC的數(shù)據(jù),采用準時循環(huán)激活每個PLC的連接,爾后讀取其數(shù)據(jù).C#封裝以下:1publicstaticintActiveConn(intconnNO)returnnew_ss(byte)connNO);3.4從DB塊中讀取字節(jié)數(shù)據(jù)(返回BYTE數(shù)組)1/從DB中讀取BYTE數(shù)組(字節(jié)數(shù)可以是任意長度的)2/3/DB塊號4/DBB初步編號,0表示DBB0,1表示DBB1,跨度為BYTE/讀取的BYTE長度(任意長度,可

12、以為奇數(shù))/返回值,BYTE型buffer7/0正常返回,非0為錯誤號8DllImport(w95_s7.dll)9privateexternstaticintd_field_read(intblockno,intno,intamount,bytebuffer);C#封裝以下:1/讀取DB塊的BYTE數(shù)據(jù)2/標準文檔合用文案3/DB塊號,如:DB24/DB數(shù)據(jù)的初步字節(jié),如DBB2則從2開始讀5/要讀取的字節(jié)數(shù),如從DBB2-DBB5,共4個字節(jié)6/BYTE型緩存區(qū),儲藏讀取的數(shù)據(jù)7/數(shù)據(jù)緩存區(qū)的初步地址8/返回值0:成功非0:錯誤代碼9publicstaticintGetDBByteData

13、(intDBBlockNO,intDBBNO,intDBByteAmount,bytebuffer,intStartIndex)bytebBufTemp=newbyteDBByteAmount;interrCode=d_field_read(DBBlockNO,DBBNO,DBByteAmount,bBufTemp);for(inti=0;iDBByteAmount;i+)bufferi+StartIndex=bBufTempi;returnerrCode;這個函數(shù)是用的最多的一個函數(shù),在數(shù)采系統(tǒng)中,習(xí)慣一次性的將全部需要用到數(shù)據(jù),全部讀到字節(jié)數(shù)組中,一致辦理,防備不相同時期紛雜讀取造成的數(shù)據(jù)

14、不一致.需要提示的是,必定保證數(shù)據(jù)辦理函數(shù)獲取的數(shù)據(jù),是PLC一次掃描周期內(nèi)的.3.5從DB中讀取整數(shù)值(int32型)標準文檔合用文案1/從DB中讀取INT數(shù)據(jù)(DBW:INT16也許DBD:INT32),最多4個字節(jié)的整數(shù)2/3/DB塊號4/DBW初步編號,0表示DBW0,1表示DBW2,跨度為WORD5/讀取的WORD長度(1個WORD=2個BYTE)2:DBW,4:DBD6/返回值,int型整數(shù)(十進制)7/0正常返回,非0為錯誤號8DllImport(w95_s7.dll)9privateexternstaticintdb_read(intdbno,intdwno,refintanz

15、ahl,refintbuffer);C#封裝1/從DB塊中讀取整型數(shù)據(jù)2/要讀取DB2.DBW6,則DB塊號為2,DBB號為6,字節(jié)長度為23/要讀取DB2.DBD6,則DB塊號為2,DBB號為6,字節(jié)長度為44/5/DB塊號,如:DB26/DBB的初步字節(jié)號,如DBW2則從2開始讀,由于是WORD(2個BYTE),DBB號必定為偶數(shù)/要讀取的BYTE數(shù),必定是偶數(shù)(這里只能是2和4,在PLC中只有DBW,DBD兩種整數(shù))8/INT32型緩存區(qū),儲藏讀取的十進制數(shù)據(jù)9/返回值0:成功非0:錯誤代碼10publicstaticintGetDBInt32Data(intDBBlockNO,intD

16、BBNO,intDBByteAmount,refintbuff標準文檔合用文案er)1112intDBWNO=DBBNO/2;13intDBWordAmount=DBByteAmount/2;14interrCode=db_read(DBBlockNO,DBWNO,refDBWordAmount,refbuffer);15bytebbuf=newbyte4;16GetByteFromInt32(buffer,bbuf,true);17buffer=bbuf0*0 x1000000+bbuf1*0 x10000+bbuf2*0 x100+bbuf3;returnerrCode;這個函數(shù)讀取的是一

17、個整數(shù),由于DB中有DBB,DBW,DBD3種數(shù)據(jù)種類,最大的DBD是4個字節(jié),所以設(shè)計了這個函數(shù),讀取單個的整型值,不用再進行BYTE到INT的變換了.這里值得一提的是整數(shù)高位優(yōu)先,還是低位優(yōu)先的問題,字節(jié)數(shù)組的序次切記要更正,別的buffer=bbuf0*0 x1000000+bbuf1*0 x10000+bbuf2*0 x100+bbuf3;這行代碼很有意思,16進制的字節(jié)進位是0 x100.3.6M,I,Q3種塊的讀取函數(shù)近似(參數(shù)都是相同的),這里放在一起進行說明區(qū)讀取函數(shù)/讀取PLC中的M字節(jié)數(shù)據(jù)/3/指定M字節(jié)號,比方要讀取MB10的值,則指定no等于104/指定讀取的字節(jié)數(shù),比

18、方需要讀取MB10至MB14之間的值,則可指定為5標準文檔合用文案5/返回獲取的值,這是一個十進制的值,若是需要獲取某一個M位的狀態(tài),需要把它變換成二進制6/0正常返回,非0為錯誤號7DllImport(w95_s7.dll)8privateexternstaticintm_field_read(intno,intanzahl,bytebuffer);I區(qū)讀取函數(shù),素來不理解為什么輸入?yún)^(qū)(單詞input)簡稱為I,而函數(shù)名卻為A,此后才了解,這個A是德文的表示方法,(Pordave是西門子公司的東東).1/讀取Output值2/3/QB號4/讀出多少個QB字節(jié)5/返回讀出的值,十進制6/0正常

19、返回,非0為錯誤號7DllImport(w95_s7.dll)8privateexternstaticinta_field_read(intno,intanzahl,bytebuffer);Q區(qū)讀取函數(shù),參數(shù)與I相同.1DllImport(w95_s7.dll)2privateexternstaticinte_field_read(intno,intanzahl,bytebuffer);C#封裝,M,I,Q3種塊的讀取函數(shù)近似,這里放在一個函數(shù)里,利用列舉種類PLCBlockType進行區(qū)分1/從M,I,Q區(qū)中讀取字節(jié)數(shù)組2/3/Block種類,在列舉PLCBlockType中定義,如要讀取M

20、區(qū)的值,則b標準文檔合用文案lockType=PLCBlockType.M4/區(qū)號,如IB10,MB105/要讀取的字節(jié)數(shù)量,如IB10-IB14共5個字節(jié)6/byte種類的buffer7/byte儲藏的初步地址8/0正常返回,非0為錯誤號9publicstaticintGetMIQByteData(PLCBlockTypeblockType,intBlockNO,intByteAmount,bytebbuf,intStartIndex)1011interrCode=0;12bytebBufTemp=newbyteByteAmount;/局部變量,不用擔(dān)憂內(nèi)存釋放的問題.C+程序員看到new估

21、計很謹慎.13switch(blockType)/依照塊種類,調(diào)用相應(yīng)的塊讀取函數(shù).1415casePLCBlockType.M:errCode=m_field_read(BlockNO,ByteAmount,bBufTemp);break;16casePLCBlockType.I:errCode=e_field_read(BlockNO,ByteAmount,bBufTemp);break;17casePLCBlockType.Q:errCode=a_field_read(BlockNO,ByteAmount,bBufTemp);break;1819for(inti=0;iByteAmoun

22、t;i+)/由于C#中對指針有所限制,從數(shù)組指定的初步地址,逐個賦值.bbufi+StartIndex=bBufTempi;標準文檔合用文案returnerrCode;,BYTE,INT,BOOL幾各種類的數(shù)據(jù)變換函數(shù)4.1從32位整數(shù)中提取字節(jié)數(shù)組(4個byte)1/從INT32型數(shù)據(jù)中提取byte字節(jié)數(shù)組2/3/源數(shù)據(jù)(long型)4/字節(jié)數(shù)組,存放提取的Byte數(shù)據(jù)5/初步地址6/提取的字節(jié)數(shù)7/long型源數(shù)據(jù)可否高位優(yōu)先,若是不是,則進行反向提取8publicstaticvoidGetByteFromInt32(intibuf,bytebbuf,boolisBigEndian)9if

23、(isBigEndian)/高位優(yōu)先,則反向提取.12for(inti=0;i=8;/右移8位16標準文檔合用文案else/低位優(yōu)先,按序次提取.20for(inti=3;i=0;i-)2122bbufi=(byte)(ibuf&0 x000000ff);23ibuf=8;4.2從字節(jié)數(shù)據(jù)中提取bit數(shù)組(8個bit),以bool型數(shù)據(jù)代替位表示.1/從Byte數(shù)據(jù)中獲取全部bit的值(1Byte=8Bit,false:0,true:1)2/3/源數(shù)據(jù)(Byte型),其中的8個bit位,從右到左0-7編號4/bit數(shù)組,存放Byte中的8個bit的值,0:false,1:true5/在bit數(shù)

24、組中存放的初步地址6publicstaticvoidGetBitFromByte(bytebyteData,boolbitArray,intstartIndex)78bytebyteArray=newbyte1;9byteArray0=byteData;10BA=newSystem.Collections.BitArray(byteArray);標準文檔合用文案11for(inti=0;i=7;i+)/依次取8個位,逐個賦值bitArraystartIndex+i=BA.Get(i);4.3從字節(jié)數(shù)據(jù)中提取某一位的狀態(tài),以bool型返回1/從Byte數(shù)據(jù)中獲取某一位bit的值(false:0,

25、true:1)2/3/源數(shù)據(jù)(Byte型),其中的8個bit位,從右到左0-7編號4/bit位編號,從右到左以0-7編號5/bit值,以bool型返回,false:0,true:16publicstaticvoidGetBitFromByte(bytebyteData,intbitNo,refboolbitData)78if(bitNo=0&bitNo=7)/位號必定在07之間910bytebyteArray=newbyte1;11byteArray0=byteData;BA=newSystem.Collections.BitArray(byteArray);bitData=BA.Get(bitNo);標準文檔合用文案五.錯誤代碼字典1/依照錯誤代碼返回錯誤信息/比方interrCode=ActiveConn(1);sringerrInfo=GetErrInfo(err);/4/錯

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論