ПЕРЕМЕННЫЕ
PROGRAM PSM_PLC_Communication
VAR
bPointerMemoryError: BOOL; //TRUE, если есть ошибка выделения памяти под указатели буфеоров команлы и статуса
fb_COM_Control: OCL.COM_Control;
fb_Serial_Request: OCL.UNM_SerialRequest;
bNeedReset: BOOL; // флаг, активируется при окончании отсылки пакета и появлении необходимости очистки буфера
abyCommand: ARRAY [0..16] OF BYTE; //буфер команды плате
abyCommand_for_CRC: ARRAY [0..11] OF BYTE; //массив для расчета CRC
abyStatus: ARRAY [0..16] OF BYTE; //буфер ответа платы
dwCRC_Command: DWORD; //переменная для расчёта CRC
wCRC_command: WORD; //младший байт предыдущей переменной
byCRC_LSB: BYTE; //младший байт CRC
byCRC_MSB: BYTE; //старший байт CRC
i: INT; //номер опрашиваемого устройства
abyID_LSB: ARRAY [1..PSM.iPS_county] OF BYTE; //массив младших байт ID опрашиваемого устройства
abyID_MSB: ARRAY [1..PSM.iPS_county] OF BYTE; //массив старших байт ID опрашиваемого устройства
END_VAR
VAR CONSTANT
//параметры обмена
udiBaudrate: UDINT:=115200; //скорость обмена
udiComPortNumber:UDINT:=1; //номер COM порта
udiByteSize:UDINT:=8; //биты информации
tTimeout: TIME:= T#100MS; //таймаут опроса
usiRetry: USINT:=3;//число попыток
END_VAR
КОД ПРОГРАММЫ
//открытие COM порта с заданными параметрами (номер порта 1, скорость 9600, биты информации 8, контроля четности нет, стоповые биты 1)
fb_COM_Control(
xEnable:=TRUE,
udiComPort:=udiComPortNumber,
udiBaudrate:=udiBaudrate,
udiByteSize:=udiByteSize,
eParity:=2,
eStopBit:=0
);
//код для очистки буферов после работы ФБ SerialRequest
IF bNeedReset THEN
MEM.MemFill(ADR(abyCommand), SIZEOF(abyCommand), 0);
MEM.MemFill(ADR(abyStatus), SIZEOF(abyStatus), 0);
bNeedReset:=FALSE;
END_IF
// *далее код, заполняющий буфер данными на отправку (17 байт) и никак не задействующий ФБ SerialRequest
//проверка корректности выделения памяти указателей.
IF fb_Serial_Request.pRequest <> CAA.Constants.gc_pNULL AND fb_Serial_Request.szRequest > CAA.Constants.gc_szZERO AND fb_Serial_Request.pResponse <> CAA.Constants.gc_pNULL AND fb_Serial_Request.szResponse > CAA.Constants.gc_szZERO THEN
bPointerMemoryError:= FALSE;
ELSE
bPointerMemoryError:= TRUE;
END_IF
// вызов ФБ Serial Request, отсылание запроса
fb_Serial_Request (
xExecute:=TRUE AND NOT bPointerMemoryError AND NOT bNeedReset ,
tTimeout:=tTimeout,
usiRetry:=usiRetry,
hCom:=fb_COM_Control.hCom,
pRequest:=ADR(abyCommand),
szRequest:=17, pResponse:=ADR(abyStatus),
szResponse:=17,
szExpectedSIze:=17,
wStopChar:=16#FF
);
IF fb_Serial_Request.xDone THEN
//разбор ответа платы, если адрес совпадает с ожидаемым
IF abyStatus[4]=INT_TO_BYTE((1+16#200) AND 16#FF) AND abyStatus[5]=INT_TO_BYTE (SHR(1+16#200,8) AND 16#FF) THEN
PSM.ar_PS_statuses[1].bMagFanError:= abyStatus[6].1; //бит ошибки вентилятора магнетрона (6 байт 1-й бит)
PSM.ar_PS_statuses[1].bPSFanError:= abyStatus[6].2; //бит ошибки вентилятора БП (6-й байт 2-й бит)
PSM.ar_PS_statuses[1].bPSLocked:= abyStatus[6].5; //бит блокировки БП (6 байт 5-й бит)
PSM.ar_PS_statuses[1].bIllegalTurnOn:= abyStatus[6].6; //бит несанкционированного включения магнетрона (6 байт 6-й бит)
PSM.ar_PS_statuses[1].bMagNotTurnedOn:= abyStatus[6].7; //TRUE, если магнетрон не смог запуститься (6-й байт 7-й бит)
PSM.ar_PS_statuses[1].bConnect:= abyStatus[7].5; // TRUE, если связь установлена, 7 байт 5-й бит
PSM.ar_PS_statuses[1].bTurnOnCommandReceived:= abyStatus[13].2; // TRUE, если команда на включение получена БП, 13 байт 2-й бит
PSM.ar_PS_statuses[1].bMagNotTurnedOn:= abyStatus[13].3; //TRUE, если есть ток магнетрона, 13 байт 3-й бит
PSM.ar_PS_statuses[1].rMagnetronCurrent:= OCL.WORD2_TO_REAL (BYTE_TO_WORD (abyStatus[3]),BYTE_TO_WORD (abyStatus[4]), FALSE);// ток магнетрона. TODO проверить работу, порядок операндов.
END_IF
bNeedReset:=TRUE; // флаг необходимости очистки буферов
fb_Serial_Request(xExecute:=FALSE);
ELSIF fb_Serial_Request.xError THEN
bNeedReset:=TRUE; // флаг необходимости очистки буферов
fb_Serial_Request(xExecute:=FALSE);
END_IF