Сообщение от
Валенок
Ну и чего хочешь услышать ? Творение выкладывай
Не вопрос !
Пример взят с пластинки, которая пришла с ПЛК.
hdkhdhfh.jpg
Вот его листинг:
Код:
PROGRAM PLC_PRG
VAR
get1_modbus: MB_RD_HOLD_REGS;
get2_modbus: MB_RD_INP_REGS;
get3_modbus: MB_RD_HOLD_REGS;
Buffer: ARRAY[0..255] OF BYTE;
cmpl: BOOL;
port_opened: BYTE := 0;
Init: BOOL;
Settings:COMSETTINGS;
com_num: PORTS:=0;
enabl: BOOL;
err: INT
TimeOut: TIME:=T#50ms;
Exception: BYTE;
DataSize: WORD;
master1: BYTE:= 1;
t: DWORD;
A: WORD := 0;
x: WORD;
x1: WORD;
x2: WORD;
x3: WORD;
d: REAL;
ptr_D:POINTER TO BYTE;
COM_SERVICE1: COM_SERVICE;
END_VAR
t:=t+1;
IF (t MOD 1000)=0 THEN
A := A + 1;
IF A > 9999 THEN
A := 0;
END_IF
END_IF
IF port_opened=0 THEN
Settings.Port:=com_num;
Settings.dwBaudRate:=115200;
Settings.byParity:=0;
Settings.dwTimeout:=0;
Settings.byStopBits:=0;
Settings.dwBufferSize:=0;
Settings.dwScan:=0;
END_IF
COM_SERVICE1(Enable:=(port_opened=0) , Settings:=Settings , Task:=OPEN_TSK );
IF COM_SERVICE1.ready THEN
port_opened:=2;
END_IF
IF port_opened=2 THEN
CASE master1 OF
0:
get1_modbus(
Enable:=enabl ,
Mode:=MB_ASCII ,
DevAddr:=2 ,
FirstAddr:=8 ,
Quantity:=1,
ComHandle:=Settings.Port ,
TimeOut:=TimeOut ,
Buffer:=Buffer ,
Complete=>cmpl ,
Exception=>err ,
ByteCnt=>DataSize );
IF cmpl THEN
IF err=0 THEN
x:=BYTE_TO_WORD(BUFFER[1]) OR SHL(BYTE_TO_WORD(BUFFER[0]),8);
END_IF
master1:=1;
END_IF
1:
get3_modbus(
Enable:=enabl ,
Mode:=MB_ASCII ,
DevAddr:=2 ,
FirstAddr:=10 ,
Quantity:=2,
ComHandle:=Settings.Port ,
TimeOut:=TimeOut ,
Buffer:=Buffer ,
Complete=>cmpl ,
Exception=>err ,
ByteCnt=>DataSize );
IF cmpl THEN
master1:=2;
IF err=0 THEN
ptr_D:=ADR(d);
ptr_D^:=buffer[1];
ptr_D:=ptr_D+1;
ptr_D^:=buffer[0];
ptr_D:=ptr_D+1;
ptr_D^:=buffer[3];
ptr_D:=ptr_D+1;
ptr_D^:=buffer[2];
END_IF
END_IF
2:
get2_modbus(
Enable:= enabl,
Mode:=MB_ASCII ,
DevAddr:=2 ,
FirstAddr:=12 ,
Quantity:=6 ,
ComHandle:= Settings.Port,
TimeOut:=TimeOut ,
Buffer:=Buffer ,
Complete=>cmpl ,
Exception=>err ,
ByteCnt=> DataSize);
IF cmpl THEN
IF err=0 THEN
x1:=BYTE_TO_WORD(BUFFER[1]) OR SHL(BYTE_TO_WORD(BUFFER[0]),8);
x2:=BYTE_TO_WORD(BUFFER[5]) OR SHL(BYTE_TO_WORD(BUFFER[4]),8);
x3:=BYTE_TO_WORD(BUFFER[9]) OR SHL(BYTE_TO_WORD(BUFFER[8]),8);
END_IF
master1:=0;
END_IF
END_CASE
IF enabl = FALSE THEN
enabl := TRUE;
END_IF
IF err <> 0 THEN
enabl := FALSE;
END_IF
END_IF
Коменты убрал чтобы не мешали иероглифы.
Вписываю сюда свои данные. Беру только нулевой блок для эксперимента. Хотя и со вторым и третьим вместе, все пакеты запросов и ответов проходят. Остальное рэмю.
Получается приблизительно как то вот так:
Код:
PROGRAM PLC_PRG
VAR
get1_modbus: MB_RD_HOLD_REGS;
(* get2_modbus: MB_RD_INP_REGS;
get3_modbus: MB_RD_HOLD_REGS;
*)
Buffer: ARRAY[0..255] OF BYTE;
cmpl: BOOL;
port_opened: BYTE := 0;
Init: BOOL;
Settings:COMSETTINGS;
com_num: PORTS:=0;
enabl: BOOL;
err: INT
TimeOut: TIME:=T#50ms;
Exception: BYTE;
DataSize: WORD;
master1: BYTE:= 0; (*Нулевой блок*)
t: DWORD;
A: WORD := 0;
x:WORD;
x1: WORD;
x2: WORD;
x3: WORD;
d: REAL;
ptr_D:POINTER TO BYTE;
COM_SERVICE1: COM_SERVICE;
END_VAR
t:=t+1;
IF (t MOD 1000)=0 THEN
A := A + 1;
IF A > 9999 THEN
A := 0;
END_IF
END_IF
IF port_opened=0 THEN
Settings.Port:=com_num;(*Можно и 0 поставить*)
Settings.dwBaudRate:=9600; (*Скорость*)
Settings.byParity:=0;
Settings.dwTimeout:=0;
Settings.byStopBits:=2;(*Стоп биты*)
Settings.dwBufferSize:=0;
Settings.dwScan:=0;
END_IF
COM_SERVICE1(Enable:=(port_opened=0) , Settings:=Settings , Task:=OPEN_TSK );
IF COM_SERVICE1.ready THEN
port_opened:=2;
END_IF
IF port_opened=2 THEN
CASE master1 OF
0:
get1_modbus(
Enable:=enabl ,
Mode:=MB_RTU , (*Можно и 0 поставить*)
DevAddr:=8 ,(*Адрес 8*)
FirstAddr:=15 ,(*Регистр для считывания (0FH)*)
Quantity:=1,(*Один регистр*)
ComHandle:=Settings.Port ,
TimeOut:=TimeOut ,
Buffer:=Buffer ,
Complete=>cmpl ,
Exception=>err ,
ByteCnt=>DataSize );
IF cmpl THEN
IF err=0 THEN
(*Убрал обработку буфера когда пытались определить момент при котором происходит зависание*)
(* x:=BYTE_TO_WORD(BUFFER[1]) OR SHL(BYTE_TO_WORD(BUFFER[0]),8);
так, что остались в работе только FB ModBus*)
END_IF
(* master1:=1;*)
END_IF
(*Отсюда последние два блока отключил, хотя и с ними все запросы и ответы пролетают*)
(*
1:
get3_modbus(
Enable:=enabl ,
Mode:=MB_RTU ,
DevAddr:=8 ,
FirstAddr:=15 ,
Quantity:=2,
ComHandle:=Settings.Port ,
TimeOut:=TimeOut ,
Buffer:=Buffer ,
Complete=>cmpl ,
Exception=>err ,
ByteCnt=>DataSize );
IF cmpl THEN
master1:=2;
IF err=0 THEN
ptr_D:=ADR(d);
ptr_D^:=buffer[1];
ptr_D:=ptr_D+1;
ptr_D^:=buffer[0];
ptr_D:=ptr_D+1;
ptr_D^:=buffer[3];
ptr_D:=ptr_D+1;
ptr_D^:=buffer[2];
END_IF
END_IF
2:
get2_modbus(
Enable:= enabl,
Mode:=MB_RTU ,
DevAddr:=8 ,
FirstAddr:=15 ,
Quantity:=6 ,
ComHandle:= Settings.Port,
TimeOut:=TimeOut ,
Buffer:=Buffer ,
Complete=>cmpl ,
Exception=>err ,
ByteCnt=> DataSize);
IF cmpl THEN
IF err=0 THEN
x1:=BYTE_TO_WORD(BUFFER[1]) OR SHL(BYTE_TO_WORD(BUFFER[0]),8);
x2:=BYTE_TO_WORD(BUFFER[5]) OR SHL(BYTE_TO_WORD(BUFFER[4]),8);
x3:=BYTE_TO_WORD(BUFFER[9]) OR SHL(BYTE_TO_WORD(BUFFER[8]),8);
END_IF
master1:=0;
END_IF
До этого места*)
END_CASE
IF enabl = FALSE THEN
enabl := TRUE;
END_IF
IF err <> 0 THEN
enabl := FALSE;
END_IF
END_IF
Окончательного варианта программы пока нет. Там ещё много чего надо будет написать, а пока экспериментируем и пытаемся понять почему происходит зависание и перезагрузка.