CoDeSys. pointer to array |
Ответить | Страница <1234> |
Автор | |
Новичок Присоединился: 15 Январь 2013 Online Status: Offline Публикации: 11 |
Опубликовано: 18 Январь 2013 23:20 |
Вот что получилось с использованием OSCAT.Lib, а точнее не получилось |
|
Профили участников
Послать частное письмо
Поиск публикаций участников
Посетить домашнюю страницу участника
Добавить в список приятелей
Действительный член Присоединился: 14 Май 2003 Online Status: Offline Публикации: 770 |
|
Почему 1021, когда в условии ясно сказано 16#1021?
|
|
Инженер-системотехник
+7 (916) 477 3925 |
|
Новичок Присоединился: 15 Январь 2013 Online Status: Offline Публикации: 11 |
|
|
|
Новичок Присоединился: 15 Январь 2013 Online Status: Offline Публикации: 11 |
|
Поменял на 16#1021 и то же не сошлось
|
|
Действительный член Присоединился: 08 Март 2006 Категория: Russian Federation Online Status: Offline Публикации: 440 |
|
Функция 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 |
|
Новичок Присоединился: 15 Январь 2013 Online Status: Offline Публикации: 11 |
|
Благодарю вас sanwork за ваш ответ! Я точно так же перевёл его на ST,
но прибор почему-то не отвечал. Должно было из вот этого массива OpCode 0x1A len-1 0x00 data[0] 0x0000 Получится при расчёте CRC: CRC = 0x730C К сожалению пока я ковырялся с этим CRC, мне прислали ответ от производителя штуковины которой я пытаюсь управлять. Как оказалось код который они используют не такой уж и стандартный как это было указано в документации. собственно вот он: Если вас не затруднит переведите его на ST пожалуйста, а то я уже несколько недель вокруг этого CRC кручусь. |
|
Действительный член Присоединился: 08 Март 2006 Категория: Russian Federation Online Status: Offline Публикации: 440 |
|
Да и правда, сумму там считают как-то по своему по фирменному
Вот функция на 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 |
|
Новичок Присоединился: 15 Январь 2013 Online Status: Offline Публикации: 11 |
|
Круто!!! Так быстро вы ответили!
Благодарю за ответ!!! Буду ковыряться дальше:) |
|
Новичок Присоединился: 15 Январь 2013 Online Status: Offline Публикации: 11 |
|
Хотел спросить.
А получался ли у вас ответ 16#730C или 16#0C73 при подстановки массива (16#1А00 16#0000)? |
|
Действительный член Присоединился: 08 Март 2006 Категория: Russian Federation Online Status: Offline Публикации: 440 |
|
У меня вообще получается 16#ECB8. Тут не надо забывать что работа идет с массивом слов - WORD (по заявлению авторов), и если массив слов рассматривать побайтно то первыми будут идти младшие байты слов (по системе IBM), то-биш 16-ти битное число 16#1A00 в массиве памяти будет выглядеть так: .. 00 A1 .. . А например двойное слово DWORD 1A000000 в памяти побайтно будет распологаться так - 00 00 00 1A. Для сведения, есть еще Motorola-вская система- там старший байт идет первым в памяти С уважением, SAN |
|
Ответить | Страница <1234> |
Переход на форум | Права доступа на форуме Вы не можете публиковать новые темы в этом форуме Вы не можете отвечать на сообщения в этом форуме Вы не можете удалять Ваши сообщения на этом форуме Вы не можете редактировать Ваши сообщения на этом форуме Вы не можете создавать голосования на этом форуме Вы не можете выражать своё мнение в голосованиях на этом форуме |