引言
計算機串行通信是計算機與控制設(shè)備(如變頻器)進行數(shù)據(jù)傳送的一種通信方式,也是實現(xiàn)工業(yè)自動控制經(jīng)常用到的通信模式。每一種通信方式都嚴格約定了與其對應(yīng)的通信協(xié)議。要確保計算機與變頻器之間能正常通信,就必須遵照變頻器通信協(xié)議編寫通信程序。本文就帶有rs-485通信接口的日普變頻器作為研究對象,設(shè)計了變頻器網(wǎng)絡(luò)監(jiān)控的方案,實現(xiàn)了對變頻器各項參數(shù)的在線監(jiān)視和控制。以下就圍繞如何在c++builder編程環(huán)境下,利用api函數(shù)編寫計算機與日普變頻器(rp3200)之間的串行通信程序進行闡述。
串行通信
串行通信在工業(yè)系統(tǒng)控制的范疇中一直占據(jù)著極其重要的地位,串行端口(rs-232)是計算機上的標(biāo)準(zhǔn)配置,常用于連接調(diào)制解調(diào)器來傳輸數(shù)據(jù),在計算機的硬件設(shè)備管理器中可以看到,定義為com1、com2等。常用的串行通信方式有兩種,分別是rs-232和rs-485,本文以rs-485方式為例進行介紹。
使用c++builder api函數(shù)編寫通信程序
c++builder本身不提供單獨的串行通信組件,這不是說它不能使用這項功能,而是必須使用一些windowsapi函數(shù)來達到這個目的。windowsapi是由操作系統(tǒng)提供的函數(shù),這些函數(shù)可以為程序設(shè)計人員提供相當(dāng)多的執(zhí)行功能,就連操作系統(tǒng)本身也是由這些api函數(shù)所組成,由于已經(jīng)將win32api均聲明進去了,因此在中使用api時只要直接使用即可。使用時必須以api函數(shù)的定義使用,才可以得到正確的結(jié)果,尤其參數(shù)的定義更是重要,使用時必須注意和定義相符,否則執(zhí)行結(jié)果將會出錯,以下就先說明這些必備的函數(shù)。
c++builder中與串行通信相關(guān)的api函數(shù)
c++builder本身并不提供單獨的串行通信組件,而是使用一些windowsapi的函數(shù)來達到此目的。這些函數(shù)是由操作系統(tǒng)所提供,可以為程序設(shè)計人員提供相當(dāng)多的執(zhí)行功能。api中與串行通信相關(guān)的函數(shù)約有20個,以下對經(jīng)常使用的函數(shù)作以討論。
打開串行端口
hcomm=createfile(comno,generic_read|generic_write,
0,null,open_existing,1,0)
函數(shù)參數(shù)定義如下:
hcomm:createfile()函數(shù)的返回值,程序使用此返回值進行相關(guān)的串行端口操作。
comno:定義串行端口號,為com1、com2等。
generic_read|generic_write:對串行端口的讀/寫操作。
0:是否共享串行端口,通常不會將串行端口與其它程序共享,因此設(shè)為0,否則為1。
null:函數(shù)的返回值hcomm是否可被子程序繼承,此處設(shè)為不可繼承。
open_existing:打開端口的方式,串行端口是一種設(shè)備,必須指定為open_existing方式。
1:使用同步或異步方式傳輸數(shù)據(jù),變頻器為異步方式,因此設(shè)為1。
0:由于使用串行端口編程,設(shè)為0。
得到串行端口狀態(tài)
getcommstate(hcomm,&dcb)
函數(shù)參數(shù)定義如下:
hcomm:createfile()函數(shù)的返回值。
dcb:串行端口控制塊地址,負責(zé)對串行端口參數(shù)進行設(shè)置,具體參數(shù)如下:
dcb.baudrate:設(shè)置串行端口的波特率,有19200kb/s、9600kb/s、4800kb/s幾種,一般為:9600kb/s。
dcb.bytesize:設(shè)置串行端口的數(shù)據(jù)位數(shù),有5、6、7、8幾種,變頻器數(shù)據(jù)位數(shù)為8。
dcb.parity:設(shè)置串行端口的校驗位檢查,有none、even、odd幾種,設(shè)為none。
dcb.stopbits:設(shè)置串行端口的停止位數(shù),有1、1.5、2幾種,變頻器的停止位數(shù)為1。
設(shè)置串行端口狀態(tài)
setcommstate (hcomm,&dcb)
函數(shù)參數(shù)定義與getcommstate()函數(shù)相同。
向串行端口寫數(shù)據(jù)
writefile(hcomm,senddata,bs,&lrc,null)
函數(shù)參數(shù)定義如下:
hcomm:createfile()函數(shù)的返回值。
senddata:寫數(shù)據(jù)的地址。
bs:寫入數(shù)據(jù)的字節(jié)數(shù)。
lrc:被寫入的數(shù)據(jù)地址。
null:寫入數(shù)據(jù)的同步檢查,串行端口采用同步通信時可以設(shè)為null。
清除串行端口的錯誤或?qū)⒋卸丝诋?dāng)前的數(shù)據(jù)狀態(tài)送至輸入緩沖區(qū)
clearcommerror(hcomm,&dwerror,&cs)
函數(shù)參數(shù)定義如下:
hcomm:createfile()函數(shù)的返回值。
dwerror:返回錯誤信息代碼。
cs:指向串行端口狀態(tài)的結(jié)構(gòu)變量。
從串行端口的輸入緩沖區(qū)讀出數(shù)據(jù)
readfile(hcomm,inbuff,cs.cbinque,&nbytesread,null);函數(shù)參數(shù)定義如下:
hcomm:createfile()函數(shù)的返回值。
inbuff:指向用來存儲數(shù)據(jù)的地址。
cs.cbinque:讀取數(shù)據(jù)的字節(jié)數(shù)。
nbytesread:總的讀取字節(jié)數(shù)。
null:如果不進行后臺工作,串行端口設(shè)為null。
關(guān)閉串行端口
closehandle(hcomm)
函數(shù)參數(shù)定義如下:
hcomm:createfile()函數(shù)的返回值。
變頻器的監(jiān)控系統(tǒng)設(shè)計
硬件連接框圖
本文設(shè)計的監(jiān)控系統(tǒng)采用平衡發(fā)送和差分接收方式實現(xiàn)通信。由于傳輸線通常使用雙絞線,又是差分傳輸,所以有極強的抗共模干擾的能力。rs-485最大的通信距離可達1219m,rs-485最大傳輸速率為10mb/s。rs-485采用半雙工工作方式,支持多點數(shù)據(jù)通信??偩€網(wǎng)絡(luò)拓撲一般采用終端匹配的總線型結(jié)構(gòu)。
rs-485總線一般最大支持32個節(jié)點。
本設(shè)計采用帶有rs-485接口的日普變頻器(rp3200)控制電機運轉(zhuǎn),上位計算機和變頻器進行通訊,計算機通過讀寫變頻器的參數(shù)來監(jiān)控變頻器的運行狀態(tài)。上位機為主控計算機,下位機為被控變頻器(最多為31個)。主控和被控之間的串行控制信號始終是主控啟動傳送,被控對此作出響應(yīng)。某一個時刻,主控和一個被控進行信號傳送,所以要預(yù)先給每個被控分配地址號,并由主控指定地址執(zhí)行發(fā)送。被控接收到主控來的信號后執(zhí)行其功能,并返回應(yīng)答給主控。由于計算機本身支持rs-232串行通信方式,所以需要用rs-232與rs-485轉(zhuǎn)換器將計算機與變頻器連接起來。上位機與變頻器控制組網(wǎng)結(jié)構(gòu)如圖1所示。
變頻器通信功能設(shè)置
此變頻器控制命令和方式有三種:數(shù)字面板控制、端子控制和rs-485通訊控制,變頻器的默認出廠設(shè)置為變頻器控制面板控制,這不符合我們與pc
機通訊的要求,為了能使變頻器與 pc機之間通訊,我們對變頻器作如下設(shè)置:
操作方式選擇
在數(shù)字面板中選擇參數(shù)設(shè)定,將運行方式按表1設(shè)置為rs-485運行方式。
通信參數(shù)設(shè)定
通信地址設(shè)定:定義設(shè)備地址 1 – 31,在線不允許兩個設(shè)備占用一個地址
傳送中斷檢測時間:設(shè)定 范圍為:0-60sec
通信規(guī)格設(shè)定:
接口:rs-485 同步方式:異步
傳輸參數(shù):
波特率:可從 1200,2400,4800,9600,19200 等中選擇
停止位:固定為 1位
變頻器通信命令介紹
通信數(shù)字符格式
數(shù)字符格式如圖2所示。
1位起始位,8位數(shù)據(jù)位,奇校驗,1位停止位。
糾錯方法
在信息后加checksum, checksum等于所有字節(jié)(hex)之和的最后一字節(jié),轉(zhuǎn)換為ascii碼。
數(shù)據(jù)包格式
類似modbus ascii格式,格式如下。
header akp1p0 d3d2d1d0 s delimiter
格式解析:
【header】:3ah
【delimiter】:0dh,0ah
a、k、p1p0、d3d2、d1d0、s分別為單字節(jié)十六進制數(shù),轉(zhuǎn)換為ascii碼。
【a】:從機(變頻器)地址。變頻器地址范圍為(1-31),a必須存在。
注:地址a=00h時對所有從機有效,且所有從機不回送響應(yīng)信息。故a=00h只能發(fā)送運行命令操作。
【k】:數(shù)據(jù)包功能代碼。
【p1p0】:參數(shù)序號。參數(shù)標(biāo)號,兩字節(jié)十六進制數(shù)。
【d3d2d1d0】:參數(shù)值:去掉小數(shù)點的參數(shù)值,共四字節(jié)的十六進制數(shù),先發(fā)高位,后發(fā)低位。
【s】:和校驗字。s是上面所有字節(jié)十六進制之和(a+k+p1p0+d3+d2+d1+d0)取最后一字節(jié)(bit7-bit0)值,轉(zhuǎn)換為ascii碼。
其中k、p、d3d2d1d0參數(shù)定義如表3所示。
計算機與變頻器串行通信程序?qū)崿F(xiàn)
通信主程序的設(shè)計架構(gòu)
設(shè)計通信主程序的主要功能是:實現(xiàn)計算機對變頻器的運行控制和狀態(tài)監(jiān)視,即構(gòu)成一個閉環(huán)監(jiān)控系統(tǒng)。程序設(shè)計架構(gòu)如圖3示。
例1:變頻起運行參數(shù)設(shè)定
1#變頻器在運行狀態(tài)下改變它的“設(shè)定頻率”為35.00hz
方法如下:
35.00去掉小數(shù)為3500d=0dach
a=1=01h (變頻器地址為“01h”)
k=04h (運行參數(shù)設(shè)定為“04h”)
p1p0=0001h (運行時設(shè)定頻率為“0001h”)
d3=00h (數(shù)據(jù)高字節(jié)為“00h”)
d2=00h (數(shù)據(jù)次高字節(jié)為“00h”)
d1=0dh (數(shù)據(jù)次字節(jié)為“0dh”)
d0=ach (數(shù)據(jù)低字節(jié)為“ach”)
s=c9h (和校驗字節(jié)為“c9h”)
(s=0bh+04h+00h+01h+00h+00h+00h+0dh+ach=c9h)
主機先后依次發(fā)送字節(jié)如下的數(shù)據(jù)包ascii:
3ah,30h,42h,30h,34h,30h,30h,30h,31h,30h,30h,30h,30h,30h,44h,41h,43h,43h,39h,0dh,0ah
變頻器回復(fù)主機相同數(shù)據(jù)。
部分通信代碼如下:
打開通訊端口代碼
char *comno;
dcb dcb;
string temp;
temp=“com”+inttostr(rdcom-》itemindex+1);
comno=temp.c_str() ;
hcomm=createfile(comno,generic_
read|generic_write,0,null,open_existing,0,0);
if(hcomm==invalid_handle_value)
{
statusbar1-》simpletext=“打開通信端口錯誤!”;
return;
}
else
statusbar1-》simpletext=“端口已打開!”;
sleep(100);
getcommstate(hcomm,&dcb);
dcb.baudrate=cbr_9600;
dcb.bytesize =8;
dcb.parity =noparity;
dcb.stopbits =onestopbit;
setcommstate(hcomm,&dcb);
if(!setcommstate(hcomm,&dcb))
{
statusbar1-》simpletext=“通信端口設(shè)置錯誤!”;
closehandle(hcomm);
return;
}
發(fā)送數(shù)據(jù)代碼
int i=0;
unsigned char sends[21];
unsigned long lrc,bs;
sends[0]=3ah; //header
sends[1]=30h; //a
sends[2]=31h;
sends[3]=30h;//k
sends[4]=34h;
sends[5]=30h; //p1
sends[6]=30h;
sends[7]=30h; //p0
sends[8]=31h;
sends[9]=30h; //d3
sends[10]=30h;
sends[11]=30h;//d2
sends[12]=30h;
sends[13]=30h; //d1
sends[14]=44h;
sends[15]=41h; //d0
sends[16]=43h;
sends[17]=43h; //s
sends[18]=39h;
sends[19]=0dh; //delimiter
sends[20]=0ah;
for(i=0;i++;i《21)
{
if(hcomm==0)
return;
writefile(hcomm,sends,1,&lrc,null);
}
接收數(shù)據(jù)代碼
int ln;
unsigned long lrc,bs;
char inbuff[1024];
dword nbytesread,dwevent,dwerror;
comstat cs;
if(hcomm==0)
{
mreceive-》text=“讀取過程有問題,已跳出!”;
return;
}
if(hcomm==invalid_handle_value)
{
mreceive-》text=“讀取過程有問題,已跳出!”;
return;
}
clearcommerror(hcomm,&dwerror,&cs);
if(cs.cbinque)
{
readfile(hcomm,inbuff,cs.cbinque,&nbytesread,null);
inbuff[cs.cbinque]=`\0`;
mreceive-》text=inbuff;
interceptrece(mreceive-》text);
}
else
mreceive-》text=“未讀取到數(shù)據(jù)!”;
以上代碼在winxp sp2操作系統(tǒng), c++builder6 編程環(huán)境下調(diào)試編譯通過。
結(jié)語
通過對帶有rs-485通信接口的日普系列變頻器的研究,設(shè)計了可行的變頻器網(wǎng)絡(luò)監(jiān)控系統(tǒng)方案,在c++builder編程環(huán)境下,利用api函數(shù),實現(xiàn)了變頻器各項參數(shù)的在線監(jiān)測與控制。提高了變頻器控制的自動化水平。
評論
查看更多