1 引言
可編程序控制器(programmable controller)簡(jiǎn)稱plc是以微處理器為基礎(chǔ)的新型控制裝置,是將計(jì)算機(jī)技術(shù)應(yīng)于工業(yè)控制領(lǐng)域的嶄新產(chǎn)品。它集邏輯運(yùn)算、順序控制、定時(shí)、計(jì)數(shù)、算術(shù)運(yùn)算功能為一體。另外還可以與其他計(jì)算機(jī)進(jìn)行通信聯(lián)網(wǎng),這種通信不但包括不同的plc之間的數(shù)據(jù)交換,而且還包括plc與計(jì)算機(jī)之間的通信。本文介紹筆者使用vb6.0實(shí)現(xiàn)plc與上位機(jī)之間的通信,使運(yùn)行人員通過油機(jī)配電屏的顯示可以監(jiān)測(cè)并控制遠(yuǎn)端設(shè)備的工作。
2 系統(tǒng)構(gòu)成
本系統(tǒng)采用plc采集模擬信號(hào)、數(shù)據(jù)處理,通過串行通信口上傳到計(jì)算機(jī),計(jì)算機(jī)對(duì)傳上來的數(shù)據(jù)進(jìn)行分析、分類記入數(shù)據(jù)庫,實(shí)時(shí)顯示在配電屏上并提供數(shù)據(jù)查詢。plc為s7-224,串行通信接口的信號(hào)線采用rs-485,此信號(hào)線為半雙工,即不能同時(shí)接收和發(fā)送。將plc置于run狀態(tài),就可以將plc中存于發(fā)送緩沖區(qū)中的數(shù)據(jù)及信號(hào)送入上位機(jī)的串口,上位機(jī)通過串口通信程序接收這些數(shù)據(jù)后顯示并通過數(shù)據(jù)庫控件adodc的綁定,把數(shù)據(jù)記錄到數(shù)據(jù)庫,從而完成數(shù)據(jù)的采樣。本工程所需采集的數(shù)據(jù)包括日常量、故障量和設(shè)備動(dòng)作量。對(duì)于日常量需每時(shí)每刻的數(shù)據(jù)顯示在配電屏的主控制平面上,以便工作人員觀察實(shí)時(shí)數(shù)據(jù),但是不需要把日常量都記入數(shù)據(jù)庫,只需隔一段時(shí)間記錄一次(在這里每隔半小時(shí)記錄一次),對(duì)于故障量和設(shè)備動(dòng)作量要求只要設(shè)備發(fā)生故障或動(dòng)作就要記錄到數(shù)據(jù)庫,以便工作人員查詢。
3 s7-200的通信方式與通信參數(shù)的設(shè)置
s7-200的通信功能很強(qiáng)大,有多種通信方式可供用戶選擇,包括單主站方式、多主站方式、使用調(diào)制解調(diào)器的遠(yuǎn)程通信方式等。本工程選擇 step7-micro/win32支持的通信硬件pc/ppi電纜,它所支持的波特率有9.6kbps和19.2kbps,支持的協(xié)議為ppi協(xié)議,即點(diǎn)對(duì)點(diǎn)接口協(xié)議,基于開放系統(tǒng)互聯(lián)模型osi。ppi是主/從協(xié)議,網(wǎng)絡(luò)上的s7-200cpu均為從站,其他cpu、simatic編程器或td200 為主站。s7-200 cpu的通信端口采用rs-485信號(hào)標(biāo)準(zhǔn)的連接口,pc/ppi電纜把s7-200 計(jì)算機(jī)連接起來,通過使用接收中斷、發(fā)送中斷和字符中斷等指令,自由端口通信可以控制s7-200cpu通信口的操作模式。本工程使用的是自由端口模式,允許在cpu處于run模式時(shí)通信口0使用自由端口模式,通過設(shè)定smb30的值,我們可以選擇波特率、奇偶校驗(yàn)、每個(gè)字符的數(shù)據(jù)位和協(xié)議。cpu處于stop模式時(shí),停止自由端口通信,通信口強(qiáng)制轉(zhuǎn)換成ppi協(xié)議模式,此時(shí),就可以向cpu中輸入plc程序,實(shí)現(xiàn)編程軟件對(duì)plc的編程和控制功能。在這里的通訊過程采用主從方式,即計(jì)算機(jī)為主機(jī),plc為從機(jī),只有主機(jī)計(jì)算機(jī)發(fā)送請(qǐng)求報(bào)文后,從機(jī)plc才向pc返回發(fā)送緩沖區(qū)中的數(shù)據(jù)。
4 自由端口模式下plc的通信
由于本工程使用的是pc/ppi電纜,所以要在plc的程序中考慮電纜的切換時(shí)間。plc接收到請(qǐng)求報(bào)文到它返回發(fā)送緩沖區(qū)的數(shù)據(jù)的延遲時(shí)間必須不小于電纜的切換時(shí)間。波特率為9600bps時(shí),電纜的切換時(shí)間是2ms。在本工程的程序中是用定時(shí)中斷實(shí)現(xiàn)切換延時(shí)的。
定時(shí)中斷子程序:
network title ’定時(shí)中斷程序int_2
ld sm0.0
dtch 10
xmt vb200, 0
當(dāng)程序運(yùn)行到“啟動(dòng)定時(shí)中斷”(即atch int_2, 10)的語句時(shí),就會(huì)跳到如上所示的中斷子程序中,sm0.0是特殊存儲(chǔ)器,該位始終為1,即只要plc處于run狀態(tài),這一開關(guān)即是接通的。xmt vb200, 0語句是用來發(fā)送數(shù)據(jù)到串口的,此時(shí)發(fā)送的是存儲(chǔ)在以vb200為首地址的連續(xù)的存儲(chǔ)空間中的數(shù)據(jù),是通過端口0發(fā)送的。
另外為了提高通信的可靠性,我們需要使用到異或校驗(yàn),即在通信的雙方都將每一幀的每一個(gè)字符作異或校驗(yàn),將兩者進(jìn)行對(duì)比,如果不相同則可以判定通信有誤。
network1 network title ’求異或校驗(yàn)碼的子程序fcs
ld sm0.0
movb 0, #xorc
bti #numb, #numi
for #temp1, +1, #numi
movb 0, #xorc ’用來把異或校驗(yàn)碼
清零, 用bti#numb,
#numi將字節(jié)數(shù)
轉(zhuǎn)換為整數(shù)
network2
ld sm0.0
xorb *#pnt, #xorc
incd #pnt
network3
next
for到next語句指明了一個(gè)循環(huán),從這一幀的第一個(gè)字符開始(不包括起始字符)到該幀中最后一個(gè)字符作異或運(yùn)算。通過調(diào)用這個(gè)子程序可以計(jì)算所指定的數(shù)據(jù)存儲(chǔ)空間內(nèi)的字符的異或校驗(yàn)碼,如果在上位機(jī)中的vb程序中也有計(jì)算校驗(yàn)碼的子程序,那么就可以比較這兩次計(jì)算的校驗(yàn)碼是否相同。可以使用語句(call fcs, &vb102, vb99, vb90)來調(diào)用該子程序,其中&vb102是指出子程序fcs進(jìn)行校驗(yàn)的起始地址,vb99是用來存儲(chǔ)需要異或的字節(jié)數(shù),而vb90是用來存儲(chǔ)計(jì)算出來的校驗(yàn)和。假設(shè)把從上位機(jī)接收到的校驗(yàn)碼存儲(chǔ)在vb91中,比較vb90和 vb91中的數(shù)據(jù)就可以檢驗(yàn)這次通信是否正確。同樣,我們可以使用這個(gè)子程序計(jì)算從plc中發(fā)送的數(shù)據(jù)的校驗(yàn)碼,把它送到上位機(jī)中某一特定的地址中,在上位機(jī)中比較兩個(gè)數(shù)據(jù)是否正確(在上位機(jī)的計(jì)算異或校驗(yàn)碼的vb程序?qū)⒃诤竺娼o出)。
因?yàn)閳?bào)文的起始字符和結(jié)束字符只有8位,接收的報(bào)文數(shù)據(jù)區(qū)內(nèi)出現(xiàn)與起始字符和結(jié)束字符相同的字符的幾率很大,這就可能會(huì)是數(shù)據(jù)區(qū)字符與起始字符或結(jié)束字符發(fā)生混淆,為了避免這種情況,可以在發(fā)送數(shù)據(jù)前對(duì)數(shù)據(jù)作一下處理,把數(shù)據(jù)字符轉(zhuǎn)換為bcd碼,在s7-200中專門提供了整數(shù)與bcd碼的轉(zhuǎn)換指令,可以使用語句(ibcd vw200)就把輸入的整數(shù)轉(zhuǎn)換為bcd碼,結(jié)果送入了vw200中。上位機(jī)接收到后需要將其轉(zhuǎn)換回整數(shù)。
另外,在初始化時(shí)要注意自由端口通信協(xié)議的設(shè)定,一定要使通信過程中的波特率,數(shù)據(jù)位,奇偶校驗(yàn)及停止位與上位機(jī)vb以及通信線上中設(shè)定的參數(shù)相同,否則將不能實(shí)現(xiàn)通信過程,要么接收不到數(shù)據(jù),要么會(huì)出現(xiàn)“下標(biāo)越界”的錯(cuò)誤。
5 上位機(jī)的通信部分采用vb語言編程
上位機(jī)通信接口部分采用vb語言來編寫, 在vb中專門有一個(gè)控件microsoft comm control(簡(jiǎn)稱mscomm控件)用來提供串行通信。在編程過程中只要設(shè)置mscomm控件的屬性, 就可以實(shí)現(xiàn)串行通信。mscomm控件一般不包括在常用的工具框中, 需要在右邊的工具框的空白處點(diǎn)擊鼠標(biāo)右鍵,選擇components選項(xiàng),就會(huì)出現(xiàn)components對(duì)話框,在其中的controls標(biāo)簽下就會(huì)找到 microsoft comm control6.0,選定它, 點(diǎn)擊確定就可以把這一控件加入到右邊的工具框中, 圖標(biāo)為。
用鼠標(biāo)拖動(dòng)這個(gè)圖標(biāo)到form中,即可設(shè)置其屬性。在此控件眾多的屬性當(dāng)中,需要重新定義的屬性只有commport(傳輸數(shù)據(jù)的通信端口號(hào))、settings(設(shè)置數(shù)據(jù)傳輸?shù)牟ㄌ芈省⑵媾夹r?yàn)、數(shù)據(jù)位以及停止位,注意,此參數(shù)一定要與plc通信程中設(shè)置的參數(shù)相一致)、 portopen(設(shè)置通信端口的狀態(tài))、inputmode(讀取接收緩沖區(qū)的格式)等。本工程采用事件驅(qū)動(dòng)方式處理接受信息,即把 rthreshold屬性設(shè)置為非零的值,此時(shí)只要接收字符或傳輸線發(fā)生變化就會(huì)產(chǎn)生串口事件oncomm。通過查詢commevent屬性可以捕獲這些通信事件。
在vb中實(shí)現(xiàn)異或計(jì)算的程序及注釋如下:
nbyte(1)=ubound(sdata)+1 ’送數(shù)據(jù)區(qū)字節(jié)數(shù)#p#分頁標(biāo)題#e#
fcs=nbyte(1) ’校驗(yàn)碼初始化
for i=2 to ubound(sdata)+2
nbyte(i)=sdata(i - 2) ’待發(fā)送數(shù)據(jù)報(bào)文數(shù)
組的數(shù)據(jù)區(qū)
fcs=fcs xor nbyte(i) ’異或運(yùn)算, 求校驗(yàn)碼
next
nbyte(i)=fcs ’送校驗(yàn)碼
其中sdata為發(fā)送的數(shù)據(jù)數(shù)組的變量名稱,for-next語句實(shí)現(xiàn)所發(fā)送的數(shù)據(jù)每一位都進(jìn)行異或運(yùn)算。這樣就可以把發(fā)送數(shù)據(jù)的異或校驗(yàn)碼送到plc中,在plc比較兩次計(jì)算出的校驗(yàn)碼是否相同,從而提高通信的可靠性。
本工程中把計(jì)算機(jī)向下發(fā)送控制命令的部分寫成自定義函數(shù)send(xi)(i從1到6),在每一個(gè)需要發(fā)送控制命令的按鈕處調(diào)用此函數(shù),只是在send中參數(shù)設(shè)置為不同的控制數(shù)。
圖1 設(shè)備動(dòng)作狀態(tài)接收表
圖1為模擬一個(gè)油機(jī)配電屏控制面,該軟件可以對(duì)三相輸出電壓、電流、功率因數(shù)這些實(shí)時(shí)信號(hào)進(jìn)行采集、顯示并存儲(chǔ),并對(duì)設(shè)備的動(dòng)作狀態(tài)、故障情況采集到數(shù)據(jù)庫中。該控制面上方有一系列的控制按鈕,點(diǎn)擊某一按鈕就會(huì)向下位機(jī)發(fā)送相應(yīng)的控制命令,控制下位機(jī)動(dòng)作。
在通信過程中,由于計(jì)算機(jī)為主機(jī),而plc為從機(jī),因此,plc只有在接收到計(jì)算機(jī)發(fā)送的信息后,才發(fā)送數(shù)據(jù)。計(jì)算機(jī)發(fā)送數(shù)據(jù)的次數(shù)并不是與其接收數(shù)據(jù)次數(shù)是一一對(duì)應(yīng)的,計(jì)算機(jī)每點(diǎn)擊一次發(fā)送控制命令的按鈕(請(qǐng)參看圖1)后,plc就要向計(jì)算機(jī)傳輸存于其緩沖區(qū)內(nèi)的所有數(shù)據(jù),而每引發(fā)一次 oncomm事件只能傳輸8個(gè)字節(jié),因此假如plc的發(fā)送緩沖區(qū)中一共右50個(gè)數(shù)據(jù),那么每要求向上傳送一次數(shù)據(jù),就會(huì)相應(yīng)的引發(fā)7次oncomm事件,而且,每引發(fā)一次oncomm事件程序就會(huì)一直執(zhí)行到end sub為止。這一點(diǎn)可以通過在發(fā)送數(shù)據(jù)的程序中加入測(cè)試語句 “debug.print‘start’”,在end sub前加一測(cè)試語句“debug.print‘end’”來驗(yàn)證,我們可以清楚的在立即窗口中發(fā)現(xiàn)每一個(gè)start后有7個(gè)end。
6 與數(shù)據(jù)庫綁定的控件
采集數(shù)據(jù)的最終目的不僅要把需要顯示的數(shù)據(jù)(比如:日常量)顯示在界面上,另外還要把數(shù)據(jù)記錄到數(shù)據(jù)庫中,以備日后查詢。顯示數(shù)據(jù)的過程很容易實(shí)現(xiàn),就是把接收緩沖區(qū)的內(nèi)容按照事先約定好的順序依次取出即可。要把數(shù)據(jù)記錄到數(shù)據(jù)庫就需要用到數(shù)據(jù)庫綁定控件,在本工程中用到的是adodc控件,這一控件也不包括在常用的工具框中,仍然要依照加mscomm控件的方法把工具條microsoft ado data control6.0(sp4)(oledb)加到工具框中,然后就可以把這一控件拖入form(在本次工作中把a(bǔ)dodc控件放在了程序運(yùn)行時(shí)不顯示的查詢畫面中,這樣就可以同時(shí)完成記錄到數(shù)據(jù)庫和查詢工作)中,通過設(shè)定adodc1的connectionstring(要求與事先建好的數(shù)據(jù)庫所存儲(chǔ)的地址相聯(lián)接)、 commandtype(由于要向數(shù)據(jù)庫寫入數(shù)據(jù)因此要把它設(shè)置為2-adcmdtable)以及recordsource(如果指定的數(shù)據(jù)庫包含多個(gè)表,就要選擇一個(gè)與此adodc1相對(duì)應(yīng)的表)屬性(其他屬性用默認(rèn)值即可)就綁定完畢。
在編程序時(shí),可以通過下面的語句把傳遞上來的信息整理并寫進(jìn)數(shù)據(jù)庫:
if rcv(5) then
with adodc1
.recordset.addnew
.recordset(“設(shè)備名稱”)=“斷路器1”
.recordset(“動(dòng)作狀態(tài)”)=“合”
.recordset(“動(dòng)作時(shí)間”)=now
.recordset.update
end with
end if
其中“設(shè)備名稱”“動(dòng)作狀態(tài)”“動(dòng)作時(shí)間”是所綁定的數(shù)據(jù)庫的字段名,等號(hào)后面的值是滿足條件語句時(shí)向所綁定的數(shù)據(jù)庫的相應(yīng)的字段所加的字段值,在本工程中在數(shù)組rcv中暫放了從接收緩沖區(qū)中接收到的所有數(shù)據(jù),而rcv(5)所放置的是是否合斷路器1這個(gè)動(dòng)作信息,約定plc送上來的數(shù)據(jù)中 rcv(5)=1表示合斷路器1,因此有上述語句,其他的動(dòng)作狀態(tài)記錄、故障狀態(tài)記錄及日常量記錄與上述程序幾乎相同,但是由于日常量不需要每時(shí)每刻都要記錄到數(shù)據(jù)庫,因此在日常量向數(shù)據(jù)庫寫入時(shí)用了靜態(tài)變量count來計(jì)時(shí),假如count的值每增加1時(shí)間就增加1s,要求每半個(gè)小時(shí)記錄一次,那么就可以用count mod 1800 =0來實(shí)現(xiàn)這一時(shí)間的控制。
7 結(jié)束語
文中列出了筆者認(rèn)為plc與計(jì)算機(jī)通信程序編寫過程中需要注意的問題,并給出筆者認(rèn)為有難度的程序代碼,本工程已經(jīng)成功的通過了測(cè)試,已交付使用。
參考文獻(xiàn)
[1] 羅朝盛等. visual basic6.0程序設(shè)計(jì)教程[m]. 北京:人民郵電出版社,2002.
[2] 廖常初. plc編程及應(yīng)用[m]. 北京:機(jī)械工業(yè)出版社,2002.
轉(zhuǎn)載請(qǐng)注明出處。