понедельник, 18 февраля 2019 г.

Проблемы совместимости S7-200 и китайских PLC: глюк с оператором FOR

Обнаружен ещё один дефект китайских контроллеров. О первом дефекте, который был обнаружен касательно оператора JMP, можно прочитать тут:
 Проблемы совместимости S7-200 и китайских PLC: глюк с оператором JMP
Полный список косяков китайских поделок, пародирующих Siemens S7-200 тут:
Китайские поделки на тему Siemens S7-200

Напомню, что первый дефект проявил себя на китайских поделках GIPENG GF200 и Amsamotion AMX-200CN, но не проявился на Shenjuye (Lollette) LE-200.
Новый дефект касается оператора FOR и также проявился на контроллерах GIPENG, но не проявился на Shenjuye. К сожалению, в настоящее время контроллеров Amsamotion нет в моём распоряжении, но учитывая прошлый опыт, с большой долей вероятности можно сказать, что глюк проявится и на нём.

Почитаем официальное описание оператора FOR в инструкции к Step-7 Micro/WIN:

The FOR (FOR) instruction executes the instructions between the FOR and the NEXT. You specify the index value or current loop count (INDX), the starting value (INIT), and the ending value (FINAL).

If the starting value is greater than the final value, the loop is not executed. After each execution of the instructions between the FOR and the NEXT instruction, the INDX value is incremented and the result is compared to the final value. If the INDX is greater than the final value, the loop is terminated.


Как видим, в инструкции чётко сказано, что если стартовое значение больше конечного значения, то цикл не выполняется. В частности, это означает, что если  стартовое значение изначально выше конечного, то цикл не должен выполняться ни одного раза.

Проверим как это выполняется на примере функции, осуществляющей расчёт среднего квадратического значения за 1 секунду времени. В программе имеется массив на 10 чисел, представляющих собой исходные значения измеряемой величины, возведённые в квадрат. Массив реализован в виде десяти 4-байтных ячеек, идущих подряд в области данных: от VD6018 до VD6054. Каждые 100мс в массив добавляется новое число, которое записывается вместо самого старого элемента массива. Т.е. текущий индекс массива просто меняется от 0 до 9 (на 1) при каждом добавлении элемента, а после 9 следующим значением индекса будет 0. В соответствии с индексом высчитывается адрес в памяти для записи нового элемента. Т.е. к начальному адресу (&VB6018) прибавляется 4 байта столько раз, сколько соответствует индексу. Если индекс равен нулю, то ничего прибавлять к адресу &VB6018 не нужно, т.к. это и есть адрес нулевого элемента массива. Вот так это выглядит на Siemens S7-200:


Итак, на скриншоте запечатлён момент, когда значение индекса (VW6016) равно нулю. Цикл, прибавляющий к адресу первого элемента нужное количество байт, работает, начиная с 1. Соответственно, при вызове цикла с конечным значением 0, цикл не должен выполниться ни разу, т.к. конечное значение получается сразу меньше начального значения. Это и видно на скриншоте - строчка "+D     +4, LD12" не выполнилась.

И вот, как оказалось, данный алгоритм некорректно работает на контроллерах GIPENG, поскольку значение в ячейке VD6018 не обновлялось. Оказалось, что цикл FOR всегда выполнялся хотя бы один раз независимо от того, выполнялось ли условие, что стартовое значение должно быть меньше или равно конечному. Вот как это выглядит:


Ну, конечно, не является проблемой обойти эту проблему, просто игнорируя цикл для такого случая (т.е. выполняя JMP перед FOR). Для этого у меня и был написан закомментированный фрагмент с "JMP 5":


Но, в общем, нашлось уже два глюка с выполнением алгоритмов на китайских ПЛК, что ещё раз подтверждает моё утверждение, что на Aliexpress надо покупать оригинальные Siemens S7-200CN, а не всякий хлам. И даже тот факт, что на контроллерах Shenjuye алгоритмы выполняются правильно, никак не отменяет всех остальных косяков, которые были обнаружены на этом контроллере.

Комментариев нет:

Отправить комментарий