?? modbus.pas
字號:
unit Modbus;
{
通訊協議 : Modbus;
}
interface
uses SysUtils;
type
TDevModbus=class
private
//********************************
Addr:integer;
Port:integer;
Baud:integer;
Mode:integer;//comm para
PortOpenOk:boolean;
DebugM:boolean;
id_RwDelayTime:integer;
id_DataLength:integer;
//***************************
Procedure GetCRC(Data:array of byte;Nums:integer;var CRCH,CRCL:byte);
Function CheckCrc(Data:array of byte;Nums:integer):Boolean;
procedure ClearInBuff;
procedure ClearOutBuff;
procedure ClearInOutbuff;
Function SendCmd(cmd:array of byte;len:integer):integer;//send cmd to pw
Function Recv(var rev:array of byte;len:integer):integer;
public
Constructor create;
destructor Destroy;override;
Function PortOpen:integer;
Function PortClose:integer;
Function Read(RegAddr,RegNum:integer;var revdata:array of byte):integer;
Function ReadByte(RegAddr:integer;High:boolean):integer;
function ReadWord(RegAddr:integer):integer;
Function Write(RegAddr:integer;writedata:Word):integer;
Function WriteByte(RegAddr:integer;writedata:byte;High:boolean):integer;
Function WriteMore(RegAddr:integer;data:array of byte;len:integer):integer;
property PortOk:boolean read portOpenOk write PortOpenOk;
published
property DevAddr:integer read Addr write Addr;
property ComPort:integer read Port write Port;// comm port
property ComBaud:integer read Baud write Baud;//comm baud
property ComMode:integer read Mode write Mode;//comm mode
property DebugMode:boolean read debugM write debugM;//
property RwDelayTime:integer read id_RwDelayTime Write id_RwDelayTime;
end;
implementation
uses PComm;
{ TPowerMtModule }
procedure TDevModbus.GetCRC(Data:array of byte;Nums:integer;var CRCH, CRCL: byte);
var
i,j:integer;
CRC:integer;
begin
CRC:=$FFFF;
for i:=0 to Nums-1 do
begin
CRC:=CRC xor ord(Data[i]);
for j:=0 to 7 do
begin
if (CRC mod 2=1) then
begin
CRC:= CRC div 2;
CRC:=$A001 xor CRC
end
else
begin
CRC:= CRC div 2;
end;
end;
end;
CRCH := crc mod 256;
CRCL := crc div 256;
end;
function TDevModbus.CheckCrc(Data: array of byte;
Nums: integer): Boolean;
var i:integer;
tmpdata:array of byte;
CRCH,CRCL : byte;
begin
setlength(tmpdata,Nums);
for i:=0 to Nums-1 do
tmpdata[i] := Data[i];
GetCrc(tmpdata,Nums-2,CRCH,CRCL);
if(CRCH=Data[Nums-2])and(CRCL=Data[Nums-1])then
result := true
else result := false;
end;
procedure TDevModbus.ClearInBuff;
begin
if not PortOpenOk then exit;
sio_flush(Port,0);
end;
procedure TDevModbus.ClearInOutbuff;
begin
if not portOpenOk then exit;
sio_flush(port,2);
end;
procedure TDevModbus.ClearOutBuff;
begin
if not PortOpenOk then exit;
sio_flush(Port,1);
end;
constructor TDevModbus.create;
begin
PortOpenOk:=false;
id_RwDelayTime:=3000;
inherited;
end;
destructor TDevModbus.Destroy;
begin
if portOpenOk then sio_close(Port);
inherited;
end;
Function TDevModbus.PortClose:integer;
begin
if portOpenOk then result:=sio_close(Port);
end;
function TDevModbus.PortOpen: integer;
var
ret:integer;
begin
//--------------打開并設置通訊端口
if DebugM then exit;
if Port<1 then
begin
PortOpenok:=false;
result:=-99;
exit;
end;
if portOpenOk then
begin
result:=0;
exit;
end;
PortOpenOk:=true;
ret:= sio_open(Port);
if ret<>SIO_OK then//打開端口出錯
begin
if ret=sio_openfail then
PortOpenOk:=false;
end;
result:=result+ret;
ret := ret+sio_ioctl (Port,Baud,Mode);//設置端口
if ret<>SIO_OK then
begin
// showmessage('SWRT端口通訊置錯誤: '+inttostr(ret));
PortOpenOk:=false;
// application.terminate;//終止程序
end;
portopen:=ret;
if portOpenok then Result:=0;
end;
function TDevModbus.SendCmd(cmd: array of Byte;len:integer): integer;
begin
if not portOpenOk then PortOpen;
if not portOpenOk then exit;
result:=sio_write(Port,@cmd,len);
end;
function TDevModbus.Recv(var rev: array of byte;len:integer): integer;
begin
if not portOpenOk then PortOpen;
if not portOpenOk then exit;
result:=sio_read(Port,@rev,len);
end;
function TDevModbus.ReadWord(RegAddr:integer):integer;
var i,ret:integer;
rev:array[0..1] of byte;
begin
ret:=read(regaddr,1,rev);
if(ret<0)then
begin
result:=-1;
exit;
end;
result := rev[0]*256+rev[1];
end;
function TDevModbus.ReadByte(RegAddr:integer;High:boolean):integer;
var i,ret:integer;
rev:array[0..1] of byte;
begin
ret:=read(regaddr,1,rev);
if(ret<0)then
begin
result:=-1;
exit;
end;
if(High)then
result := rev[0]
else
result := rev[1];
end;
function TDevModbus.Read(RegAddr,RegNum:integer; var revdata:array of byte):integer;
var cmd,rev:array of byte;
i,ret,revlen:integer;
begin
ClearInOutBuff;
setlength(cmd,8);
cmd[0]:=Addr;
cmd[1]:=$03;
cmd[2]:=RegAddr div 256;
cmd[3]:=RegAddr mod 256;
cmd[4]:=RegNum div 256;
cmd[5]:=RegNum mod 256;
getCRC(cmd,6,cmd[6],cmd[7]);
ret:=SendCmd(cmd,length(cmd));
sleep(200);
revlen:=RegNum*2+5;
setlength(rev,revlen);
ret:=ret+Recv(rev,revlen);
if(ret=revlen+8)then
result := 0
else
begin
result :=-1;
exit;
end;
if(CheckCRC(rev,revlen))then
result := 0
else
begin
result := -1;
exit;
end;
for i:=0 to RegNum*2-1 do
begin
revdata[i]:=rev[i+3];
end;
end;
Function TDevModbus.Write(RegAddr:integer;writedata:word):integer;
var cmd,rev:array of byte;
i,ret,revlen:integer;
begin
ClearInOutBuff;
setlength(cmd,8);
cmd[0]:=Addr;
cmd[1]:=$06;
cmd[2]:=RegAddr div 256;
cmd[3]:=RegAddr mod 256;
cmd[4]:=writedata div 256;
cmd[5]:=writedata mod 256;
getCRC(cmd,6,cmd[6],cmd[7]);
ret:=SendCmd(cmd,length(cmd));
sleep(100);
revlen:=8;
setlength(rev,revlen);
ret:=ret+Recv(rev,revlen);
if(ret=revlen+8)then
result := 0
else
begin
result :=-1;
exit;
end;
if(CheckCRC(rev,revlen))then
result := 0
else
result := -1;
end;
Function TDevModbus.WriteByte(RegAddr:integer;writedata:byte;High:boolean):integer;
var cmd,rev:array of byte;
i,ret,revlen:integer;
bHigh,bLow:byte;
begin
bHigh:=0;
bLow:=0;
//先讀出整個寄存器中的數據
setlength(rev,2);
ret:=Read(RegAddr,1,rev);
if(ret=0)then
begin
bHigh :=rev[0];
bLow := rev[1];
end;
//然后寫入相應的字節
ClearInOutBuff;
setlength(cmd,8);
cmd[0]:=Addr;
cmd[1]:=$06;
cmd[2]:=RegAddr div 256;
cmd[3]:=RegAddr mod 256;
if(not High)then
begin
cmd[4]:=bHigh;
cmd[5]:=writedata mod 256;
end
else
begin
cmd[4]:=writedata mod 256;
cmd[5]:=bLow;
end;
getCRC(cmd,6,cmd[6],cmd[7]);
ret:=SendCmd(cmd,length(cmd));
sleep(100);
revlen:=8;
setlength(rev,revlen);
ret:=ret+Recv(rev,revlen);
if(ret=revlen+8)then
result := 0
else
begin
result :=-1;
exit;
end;
if(CheckCRC(rev,revlen))then
result := 0
else
result := -1;
end;
function TDevModbus.WriteMore(RegAddr: integer; data: array of byte;
len: integer): integer;
var cmd,rev:array of byte;
i,ret,revlen:integer;
begin
ClearInOutBuff;
setlength(cmd,len+8);
cmd[0]:=Addr;
cmd[1]:=$10;
cmd[2]:=RegAddr div 256;
cmd[3]:=RegAddr mod 256;
for i:=0 to len-1 do
cmd[i+4]:=data[i];
getCRC(cmd,len+5,cmd[len+6],cmd[len+7]);
ret:=SendCmd(cmd,length(cmd));
sleep(100);
revlen:=8;
setlength(rev,revlen);
ret:=ret+Recv(rev,revlen);
if(ret=revlen+8+len)then
result := 0
else
begin
result :=-1;
exit;
end;
if(CheckCRC(rev,revlen))then
result := 0
else
result := -1;
end;
end.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -