Современные технологии автоматизации» («СТА») —  журнал для квалифицированных специалистов по промышленной автоматизации Форум СТА — современные технологии автоматизации Домашняя страница
Домашняя страница форума CTA Домашняя страница форума CTA > II. АСУТП и SCADA > Программное обеспечение
  Активные темы Активные темы
  FAQ FAQ  Искать в форуме   Зарегистрироваться Зарегистрироваться  Вход в систему Вход в систему

CoDeSys. pointer to array

 Ответить Ответить Страница  <1234>
Автор
Сообщение
Egonohek Смотреть выпадающим
Новичок
Новичок


Присоединился: 15 Январь 2013
Online Status: Offline
Публикации: 11
Свойства публикации Свойства публикации   Ответить, цитируя автора - Egonohek Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Тема сообщения: CoDeSys. pointer to array
    Опубликовано: 18 Январь 2013 23:20


Вот что получилось с использованием OSCAT.Lib, а точнее не получилось
Наверх
Максим Ананских Смотреть выпадающим
Действительный член
Действительный член
Аватар

Присоединился: 14 Май 2003
Online Status: Offline
Публикации: 770
Свойства публикации Свойства публикации   Ответить, цитируя автора - Максим Ананских Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 18 Январь 2013 23:34
Почему 1021, когда в условии ясно сказано 16#1021?
Инженер-системотехник
+7 (916) 477 3925
Наверх
Egonohek Смотреть выпадающим
Новичок
Новичок


Присоединился: 15 Январь 2013
Online Status: Offline
Публикации: 11
Свойства публикации Свойства публикации   Ответить, цитируя автора - Egonohek Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 22 Январь 2013 08:29
Наверх
Egonohek Смотреть выпадающим
Новичок
Новичок


Присоединился: 15 Январь 2013
Online Status: Offline
Публикации: 11
Свойства публикации Свойства публикации   Ответить, цитируя автора - Egonohek Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 22 Январь 2013 08:30
Поменял на 16#1021 и то же не сошлось
Наверх
sanwork Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 08 Март 2006
Категория: Russian Federation
Online Status: Offline
Публикации: 440
Свойства публикации Свойства публикации   Ответить, цитируя автора - sanwork Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 22 Январь 2013 20:29
Функция crc16 по полиному 0x1021 в CoDeSys на ST:

-------------------------------
FUNCTION crc16_1021 : WORD

VAR_INPUT
pcBlock: POINTER TO BYTE;
len: WORD;
END_VAR

VAR
crc, i, w: WORD;
END_VAR
-------------------------------
crc := 16#FFFF;
WHILE (LEN > 0) DO
w := pcBlock^;
pcBlock := pcBlock + 1;
w := SHL(w,8);
crc := crc XOR w;
FOR i := 0 TO 7 DO
IF ((crc AND 16#8000) <> 0) THEN
crc := SHL(crc,1) XOR 16#1021;
ELSE
crc := SHL(crc,1);
END_IF
END_FOR
LEN := LEN - 1;
END_WHILE
crc16_1021 := crc;
RETURN;
-------------------------------

Тип INT в CoDeSys - 16-ти разрядный, потому что генерится для разных аппаратных платформ. Поэтому в настройках платформы проекта на закладке 'Общие' надо поставить галочку 'Байт-адресация всех типов'. Лучше всегда ставить эту галку так как это снимет многие другие проблемы.

Еще хочу сказать один важный вещь:
в протоколе MODBUS котрольная сумма считается совсем по другому! Особенно в очень популярных приборах ОВЕН, МВ110 и подобных. Там используется полином 0xA001 и сдвиг идет вправо.
Вот один из вариантов функции  crc16mbus  для контр.суммы в сетях MODBUS на C:

//------------------------------------------
unsigned short crc16mbus(char *buf, int Len)
{
int i, ib;
unsigned short crc = 0xFFFF;

for (ib=0; ib<Len; ib++)
{
crc ^= buf[ib];
for (i=0; i<8; i++)
{
if (crc & 0x0001) res = (res >> 1) ^ 0xA001;
else crc >>= 1;
}
}
return crc;
}
//------------------------------------------

А в CoDeSys на ST это будет так:

-------------------------------
FUNCTION crc16mbus : WORD

VAR_INPUT
pBuf: POINTER TO BYTE;
len: WORD;
END_VAR

VAR
crc, i, w: WORD;
END_VAR
-------------------------------
crc := 16#FFFF;
WHILE (LEN > 0) DO
w := pBuf^;
pBuf := pBuf + 1;
crc := crc XOR w;
FOR i := 0 TO 7 DO
IF ((crc AND 16#0001) <> 0) THEN
crc := SHR(crc,1) XOR 16#A001;
ELSE
crc := SHR(crc,1);
END_IF
END_FOR
LEN := LEN - 1;
END_WHILE
crc16mbus := crc;
-------------------------------

С уважением, SAN
Наверх
Egonohek Смотреть выпадающим
Новичок
Новичок


Присоединился: 15 Январь 2013
Online Status: Offline
Публикации: 11
Свойства публикации Свойства публикации   Ответить, цитируя автора - Egonohek Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 22 Январь 2013 23:25
Благодарю вас sanwork за ваш ответ! Я точно так же перевёл его на ST,
но прибор почему-то не отвечал.
Должно было из вот этого массива
OpCode  0x1A
len-1       0x00
data[0]   0x0000
Получится при расчёте CRC:   CRC   =     0x730C

К сожалению пока я ковырялся с этим CRC, мне прислали ответ от производителя штуковины которой я пытаюсь управлять.
Как оказалось код который они используют не такой уж и стандартный как это было указано  в документации.

собственно вот он:


Если вас не затруднит переведите его на ST пожалуйста, а то я уже несколько недель вокруг этого CRC кручусь.
Наверх
sanwork Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 08 Март 2006
Категория: Russian Federation
Online Status: Offline
Публикации: 440
Свойства публикации Свойства публикации   Ответить, цитируя автора - sanwork Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 23 Январь 2013 15:18
Да и правда, сумму там считают как-то по своему по фирменному
Вот функция на ST:

-------------------------------
FUNCTION CalcFieldCRC : WORD

VAR_INPUT
pDataArray: POINTER TO WORD;
numberOfWords: WORD;
END_VAR

VAR
shifter, c, carry, CRC: WORD;
END_VAR
-------------------------------
CRC := 0;
WHILE (numberOfWords <> 0) DO
shifter := 16#8000;
c := pDataArray^;
pDataArray := pDataArray + 2;
REPEAT
carry := CRC AND 16#8000;
CRC := SHL(CRC,1);
IF ((c AND shifter) <> 0) THEN CRC := CRC + 1; END_IF
IF (carry <> 0) THEN CRC := CRC XOR 16#1021; END_IF
shifter := SHR(shifter,1);
UNTIL (shifter = 0)
END_REPEAT
numberOfWords := numberOfWords - 1;
END_WHILE
CalcFieldCRC := CRC;
-------------------------------

тут надо кое что сказать: судя по исходнику в этой функции элементы берутся не байтами а целыми словами (двойными батами), и значит указатель в буфере должен увеличиваться на 2. Так вот, в Си это происходит автоматически за счет указания типа WORD*. В CoDeSys такой номер не прокатит даже при указании типа POINTER TO WORD. Поэтому тут указатель передвигается на 2, сравнивал с работой оригинала - ответ вроде сходится.
Вобщем попробуйте

С уважением, SAN
Наверх
Egonohek Смотреть выпадающим
Новичок
Новичок


Присоединился: 15 Январь 2013
Online Status: Offline
Публикации: 11
Свойства публикации Свойства публикации   Ответить, цитируя автора - Egonohek Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 23 Январь 2013 17:04
Круто!!! Так быстро вы ответили!

Благодарю за ответ!!!

Буду ковыряться дальше:)
Наверх
Egonohek Смотреть выпадающим
Новичок
Новичок


Присоединился: 15 Январь 2013
Online Status: Offline
Публикации: 11
Свойства публикации Свойства публикации   Ответить, цитируя автора - Egonohek Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 24 Январь 2013 19:55
Хотел спросить.
А получался ли у вас ответ 16#730C или 16#0C73
при подстановки массива (16#1А00 16#0000)?
Наверх
sanwork Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 08 Март 2006
Категория: Russian Federation
Online Status: Offline
Публикации: 440
Свойства публикации Свойства публикации   Ответить, цитируя автора - sanwork Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 25 Январь 2013 17:26

У меня вообще получается  16#ECB8.  Тут не надо забывать что работа идет с массивом слов -  WORD  (по заявлению авторов),  и если массив слов рассматривать побайтно то первыми будут идти младшие байты слов (по системе IBM), то-биш  16-ти битное число  16#1A00  в массиве памяти будет выглядеть так:  .. 00 A1 .. . А например двойное слово DWORD 1A000000 в памяти побайтно будет распологаться так - 00 00 00 1A.  Для сведения, есть еще Motorola-вская система- там старший байт идет первым в памяти

С уважением, SAN

Наверх
 Ответить Ответить Страница  <1234>

Переход на форум Права доступа на форуме Смотреть выпадающим

Bulletin Board Software by Web Wiz Forums® version 9.64
Powered by Web Wiz Forums Free Express Edition
Copyright ©2001-2009 Web Wiz