Добрый день,
Я использую весы ТСК-5, для связи с ними используется com-порт (Описание -
http://www.baltves.ru/?module=articles&id=94). Чтобы весы ответили, нужно сформулировать запрос из четырёх байт:
- сетевой адрес устройства
- байт 55h
- два байта контрольной суммы crc16
В описании весов сказано(
http://baltves.ru/index.php?module=articles&id=94), что если "сетевой адрес равен 0, то посылка имеет вид 000h, 055h, 017h, 05Fh" (почему-то значения записаны именно так - с 0 перед байтом).
Я отправил запрос на весы (0х00,0х55,0х17,0х5F) и получил от весов правильный ответ.
Теперь у меня задача использовать весы с сетевым адресом 1, но я не знаю - как рассчитать два последние байта crc16.
В описании также коротко изложен расчёт crc16:
- crc16 состоит из 2х байтов В1 и B2, начальное значение которых B1=B2=0FFh;
- для каждого байта данных Di производится B1=(B1 xor Di)
- восемь раз сдвигается слово B1B2 на 1 бит в сторону старшего бита B1 и производится B1B2=(B1B2 xor 1021h) каждый раз, когда перед сдвигом старший бит B1=1.
Я долго гонял нули и единицы, пытаясь понять суть написанного, потом нашёл в Википедии пример расчёта crc16 CCITT (на СИ) с полиномом 0х1021:
http://ru.wikipedia.org/wiki/%D0%A6%D0%B8%D0%BA%D0%BB%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B8%D0%B7%D0%B1%D1%8B%D1%82%D0%BE%D1%87%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4Написал на Builder приведённую там программу:
unsigned char *pcBlock = "0x00,0x55";
unsigned short len = 8;
unsigned short crc=0xFFFF;
unsigned short i;
while( len--)
{
crc ^= *pcBlock++ << 8;
for(i=0;i<8:i++)
crc = crc & 0x8000 ? ( crc << 1 ) ^ 0x1021 : crc << 1;
}
// вывод crc на builder`e в десятеричном формате
ListBox1->Items->Add(crc);
Но и в этом алгоритме ожидаемые "0x17,0x5F" не получаются...
Скажите, где я ошибся или пришлите, пожалуйста, правильный алгоритм расчёта.