Вот кусок из рабочего проекта для ПЛК73. Вкраце что тут происходит...
Два устройства поочередно опрашиваются по 232 и 485. Тут только кусок от 485 оставил. Опрашиваются они через равные промежутки времени!!! Интервал опроса задается в переменной tMessInterval. Как только коммуникационный ФБ выдает COMPLETE по триггеру отключается флаг enableRsSend и коммуникационный ФБ отключается!!! Как только таймер отсчитает tMessInterval и enableRsSend отключен, смениться шаг в цикле CASE и отключится таймер (чтобы заново стал считать) и так по кругу.
Код:
(*ТАЙМЕР СМЕНЫ ШАГОВ КОММУНИКАЦИИ*)
tmrStepRs(IN:= com_ready1 AND com_ready2, PT:= tMessInterval); (*как только открылись оба порта запускаем отсчет шагов опроса*)
(*ОТПРАВКА И ЧТЕНИЕ КОМАНД RS232 и RS485*)
IF (com_ready1 = TRUE AND com_ready2 = TRUE)THEN
CASE stepRs OF
1: бла бла бла
2:
(*ПЕРЕДАЧА ЧАСТОТЫ ПЧВ*)
send1_modbus(
Enable := enableRsSend,
Mode := MB_RTU,
DevAddr := 2,
RegAddr := 50009, (*РЕГИСТР ЗАДАНИЯ ПО ИНТЕРФЕЙСУ*)
Value := freq1, (*ЧАСТОТА*)
ComHandle := Settings1.Port,
TimeOut := tWorkBlock,
Complete => cmpl3,
Exception => err3
);
rt_step_2(CLK:= cmpl3); (*По завершению работы ФБ включаем триггер*)
IF rt_step_2.Q THEN
enableRsSend := FALSE;
END_IF (*Если завершили отключаем работу ФБ*)
IF tmrStepRs.Q AND enableRsSend = FALSE THEN (*Как только досчитал таймер смены шага и блок отправки уже отработал*)
stepRs := 3; (*Меняем шаг*)
tmrStepRs(IN:= FALSE); (*Отключаем таймер*)
IF enableRsSend = FALSE THEN enableRsSend := TRUE; END_IF (*Ставим флаг для запуска следующего блока*)
END_IF
3:
(*ОТПРАВКА КОМАНДНОГО СЛОВА*)
IF freq < 0.09 THEN (*если частота ниже 1Hz то двигатель отключен*)
pcv_com_word := 1268; (*двигатель отключен (торможение с выбегом)*)
IF v1 < 2500 THEN
pcv_com_word := 1212; (*если скорость ниже 25м/c то используем быструю остановку*)
END_IF
ELSE
pcv_com_word := 1148 ; (*запуск двигателя*)
END_IF
send1_modbus(
Enable := enableRsSend,
Mode := MB_RTU,
DevAddr := 2,
RegAddr := 49999, (*РЕГИСТР КОМАНДНОГО СЛОВА ПРИВОДА*)
Value := pcv_com_word, (*КОМАНДНОЕ СЛОВО*)
ComHandle := Settings1.Port,
TimeOut := tWorkBlock,
Complete => cmpl4,
Exception => err4
);
rt_step_3(CLK:= cmpl4);
IF rt_step_3.Q THEN
enableRsSend := FALSE;
END_IF
IF tmrStepRs.Q AND enableRsSend = FALSE THEN
stepRs := 4;
tmrStepRs(IN:= FALSE);
IF enableRsSend = FALSE THEN enableRsSend := TRUE; END_IF
END_IF
4:
(*ЗАПРОС СОСТОЯНИЯ ЭЛЕКТРОДВИГАТЕЛЯ*)
get3_modbus(
Enable := enableRsSend,
Mode := MB_RTU,
DevAddr := 2,
FirstAddr := 50199, (*РЕГИСТР СЛОВА СОСТ. ПРИВОДА*)
Quantity := 1,
ComHandle := Settings1.Port,
TimeOut := tWorkBlock,
Buffer := buffer1,
Complete => cmpl5,
Exception => err5,
ByteCnt => dataSize1
);
rt_step_4(CLK:= cmpl5);
IF rt_step_4.Q THEN
IF err5 = 0 THEN
pcv_state_word := BYTE_TO_WORD(buffer1[1]) OR SHL (BYTE_TO_WORD(buffer1[0]),8);
END_IF
enableRsSend := FALSE;
END_IF
IF tmrStepRs.Q AND enableRsSend = FALSE THEN
stepRs := 1;
tmrStepRs(IN := FALSE);
IF enableRsSend = FALSE THEN enableRsSend := TRUE; END_IF
END_IF
END_CASE
Еще следует помнить что в библиотеке модбаса есть ошибка из-за которой через пачку в порт мусор идет. Для ее починки следует сделать следующее
Код:
(*
В БИБЛИОТЕКЕ OWEN MODBUS.LIB В ФБ MB_UNI_IO ЗАМЕНЯЕМ СТРОКУ 7 НА
WHILE SysComRead(ComHandle, ADR(DataBuf)+DataSize, SIZEOF(DataBuf)-DataSize, 0) <> 0 DO;
инче в случае получения ошибки таймаута FF в след пачке пойдем мусор.
Также для скорости 9600 необходимо установить значение таймера T_FRTU = ~5ms
*)