林 濤 張聲興
摘要:文章介紹了可編程控制器(PCL)與上位機(PC機)實現(xiàn)串行通信功能的硬件組成、通信協(xié)議,重點闡明在上位機(PC機)上基于VC++6.0的編程實現(xiàn)細節(jié),并進一步展望PLC對控制系統(tǒng)應(yīng)用的前景。
關(guān)鍵詞:可編程控制器(PCL);VC++
中圖分類號:TP312文獻標(biāo)識碼:A文章編號:1006-8937(2009)08-0112-02
鑒于目前由可編程控制器(PCL)和PC機所構(gòu)成的監(jiān)控系統(tǒng)在工業(yè)控制領(lǐng)域得以廣泛的運用,文章將對PCL作下位機,完成現(xiàn)場設(shè)備的直接控制、數(shù)據(jù)收集等工作,PC機作上位機,完成數(shù)據(jù)的分析存儲、狀態(tài)顯示等工作進行技術(shù)探討,通過上位機對PLC的讀寫操作,從而完成現(xiàn)場數(shù)據(jù)的接收、傳達與監(jiān)控功能。文章以O(shè)MRON公司的CJ1G型PLC作下位機,以PC機為上位機,重點研究此分布式控制系統(tǒng)的通訊方式。
1硬件互聯(lián)技術(shù)細節(jié)
1.1PLC與PC的硬件互聯(lián)
經(jīng)過對該品牌PLC的分析,可知PLC本身配有RS-232接口,大大方便了與PC機串口通信的硬件連接,文章直接采用自制電纜將PLC的RS-232口與PC機RS-232口相連,引腳對應(yīng)關(guān)系圖如圖1:
1.2設(shè)定PLC通信方式,確定通信協(xié)議幀
CJ系列PLC單元支持以下5種串行通信功能:上位機鏈接通信、無協(xié)議通信、1:N或1:1鏈接通信、外設(shè)總線通信和串行PLC鏈接通信,其中上位機鏈接通信功能適用于上下位機并以會話的方式進行實時數(shù)據(jù)通信。
一般在控制系統(tǒng)中,采用單臺PLC與PC機通信,上位機擔(dān)當(dāng)命令發(fā)起端,通過向PLC發(fā)送不同格式的命令幀,完成對PLC寄存器的讀寫操作。因此文章選擇主機-->PLC的主鏈接命令通信方式。
該系統(tǒng)使用RS一232C端口進行通信。RS一232C端口的缺省設(shè)定是:上位機鏈接模式、1啟動位、7數(shù)據(jù)位、偶校驗、2停止位和9 600bps的波特率。用戶可以通過編程工具或者SETUP(237)指令改變RS一232C端口的設(shè)定。我們首先用編程工具對PLC進行設(shè)置,其中PLC的操作模式設(shè)定為監(jiān)控模式;然后斷開電源,將主機與PLC的CPU單元連接,并將CPU單元DIP的引腳5設(shè)定為OFF;最后接通電源,從主機發(fā)布主鏈接命令,進行上下位機的通信。
由于整個通信系統(tǒng)采用上位機主動的通信方式。上位機與PLC的通信是通過使用命令幀(command)和響應(yīng)幀(response)進行數(shù)據(jù)的發(fā)送和接收。幀的發(fā)送與接收圖2所示:
命令的格式如圖3所示,命令必須以@開始,機號No為2個十進制數(shù),表示上位機識別所連接PLC的機號。識別碼是2個字符的命令碼,如RR表示讀取CIO區(qū)域的內(nèi)容。正文部分為設(shè)定命令的參數(shù),對于不同的命令,正文的內(nèi)容和長度可能有所不同。FCS是2個字符的幀檢查序列。命令的最后2個字符是終端,表示命令的結(jié)束,由“*”和CR碼組成。命令格式圖3所示:
圖3 命令格式
響應(yīng)的格式與命令的格式相似,只是在識別碼后面多了2個十六進制字符的結(jié)束碼,用于返回命令的執(zhí)行狀態(tài)(有無錯誤及錯誤的原因)。一個幀最多由131個ACSⅡ字符組成,如果需要發(fā)送的字符超出131個,必須將數(shù)據(jù)分成若干個幀,第一幀和中間幀的結(jié)尾用分界符(CR)代替結(jié)束符(*CR)。
VC++6.0軟件實現(xiàn)VC++6.0開發(fā)環(huán)境為串口通訊已經(jīng)提供了ActiveX控件,名為MSComm控件。下面闡述對該控件屬性的初始化設(shè)置以及相關(guān)實現(xiàn)代碼。限于篇幅,此文只將重要的實現(xiàn)代碼羅列如下:
{
My_Comm.SetCommPort(1);//選擇 COM1口
My_Comm.SetSettings( 9600,E,7,1 );//設(shè)置通信參數(shù)
My_Comm.SetlnputMode(1);//設(shè)置二進制輸入模式
My_Comm.SetInBufferSize(1024);//設(shè)置輸入緩沖區(qū)大小
My_Comm.SetlnputLen(0);//使用Input將使MSComm控件讀取接收緩沖區(qū)中的全部內(nèi)容
My_Comm.SetOutBufferSize(1024);//設(shè)置輸出緩沖區(qū)大小
My_Comm.SetRThreshold(1);//設(shè)置每接收一個字符觸發(fā)一次OnComm事件
My_Comm.SetDTREnable(TRUE);//置DTR有效
int timeRes;
if(!My_Comm.GetPortOpen()) //如果沒有開
My_Comm.SetPortOpen(TRUE);//手工打開串口
My_Comm.Getlnput();//清空輸入緩沖區(qū)
timeRes=SetTimer(2,500,NULL);//安裝定時器
if(timeRes==0)
{
MessageBox( “設(shè)置定時器出錯” );
return ;
}
}
主要實現(xiàn)代碼處于在WM_TIMER消息的處理函數(shù)上
void CPLCCommDlg::OnTimer(UINT nlDEvent)
{
int len;
long j;
VARIANT inputdatal:
COleSafeArray inputdata2;
BYTE datatempl,datatemp2;
BYTE commstr[17]={ ‘@ ,0,‘0,R,D,0, 0, 0, 0, 0, 0, 0,2,0x00,0x00,*,0x0d}
//初始化命令參數(shù)
My_Comm.SetRTSEnable(TRUE);//設(shè)置RTS線有效,請求允許發(fā)送數(shù)據(jù)
verifcation(commstr,17);//對發(fā)送的命令進行幀校驗
CByteArray cbaArraylnsA;
cbaArraylnsA.RemoveAll();
for(int nlndex:0;nlndex<17;++nlndex)
{
cbaArraylnsA.Add(commstr[nIndex]);
}
My_Comm.SetOutput(COleVariant(cbaArraylnsA));//發(fā)送讀取數(shù)據(jù)的命令
My_Comm.SetRTSEnable(FALSE);//設(shè)置RTS線無效,不允許發(fā)送數(shù)據(jù)
inputdatal= My_Comm.Getlnput();//讀取接收緩沖區(qū)的數(shù)據(jù)
inputdata2=inputdatal;
len=inputdata2.GetOneDimSize();
for(j=0;j { inputdata2.GetElement(&j,inputdata+j); } datatempl=inputdata[15]; datatemp2=inputdata[16]; verfunction(inputdata,19);//計算接收數(shù)據(jù)的幀校驗碼 if(datatempl! = inputdata [15] || datatemp2 1=inputdata[16]) { MessageBox(”Receive data invalid! );//判斷接收數(shù)據(jù)是否有效 } else { for(i=0;j<8;j++) { OutputData[j]=inputdata[j+7];//將數(shù)據(jù)存儲到上位機的數(shù)據(jù)存儲區(qū)中 } } incount=0; CDialog::OnTimer(nlDEvent); } 上述函數(shù)所調(diào)用的對幀進行校驗的函數(shù)verifcation代碼如下: CPLCCommDlg::verfunction(BYTE vdata[],int K) { BYTE sum=0x00,vl=0x0f, v2=0xf0; for(int i=0;i { sum^=vdata[i]; } V1& =sum; V2& =sum; v2> > =4; if(vl>=0&& vl<=9) V1+ =0x30; else V1+ =0x37; if(v2>=0&& v2<=9) V2+ =0x30; else V2+=0x37; vdata[K-3]=vl;//幀貞校驗碼低位字節(jié) vdata[K-4]=v2;//幀校驗碼高位字節(jié) } 2結(jié)語 采用這種方法開發(fā)出了上位機與PCL的通信系統(tǒng),實現(xiàn)了上位機和PLC的數(shù)據(jù)交換功能。文章嘗試為一般化控制系統(tǒng)提供統(tǒng)一通信控制框架,這也是下一步研究方向,希望通過此類努力為硬件通訊提供一個方便調(diào)用的軟件接口,從而降低開發(fā)難度,提供開發(fā)效率。