Показано с 1 по 10 из 20

Тема: Контрольная сумма ТРМ201

Комбинированный просмотр

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1

    По умолчанию

    вы меня извините, но на расчет crc у меня пальцев не хватит. алгоритм на с в этой ветке приведен. если вас интересует математическая основа, ее несложно найти в интернете.

    если коротко, число состоящее из всех битов пакета делится на выбранный полином. crc - остаток от деления.

  2. #2
    незарегистрированный
    Гость

    По умолчанию контрольная сумма для ТРМ138

    Попоробовал посчитать КС по алгоритму Дмитрия Егоренкова для такого запроса:
    GGHIONOKGGGGRVSM получил 2e77, а на самом деле как видите bfc6.
    В чем дело?

  3. #3

    По умолчанию

    Цитата Сообщение от незарегистрированный Посмотреть сообщение
    получил 2e77, а на самом деле как видите bfc6.
    В чем дело?
    не знаю. у меня получается bfc6.

  4. #4

    По умолчанию

    Цитата Сообщение от Дмитрий Егоренков Посмотреть сообщение
    не знаю. у меня получается bfc6.
    "ОПИСАНИЕ протокола обмена между ПЭВМ и приборами ОВЕН" не совсем корректное, особенно это касается "СТРУКТУРНОЙ СХЕМЫ ПРОТОКОЛА ОВЕН", вот и претензий много

    я, честно говоря, не первый раз такие спецификации читаю и работаю с ними, поэтому когда писал конфигуратор команд для протокола owen, делал ровно то, что написано в этих документах,

    а получилось это только после того, как увидел 2 "живые" команды на форуме

    вот чтобы такого не происходило, я бы порекомендовал сделать всего 3 дополнения:
    1. перерисуйте эту схему так, чтобы был виден четкий порядок бит, раз уж там они есть
    2. ваш CRC расчитывается с исключением из пакета кроме маркеров еще и самой контрольной суммы, т.е. не текущая, не нулевая, а вообще без этого члена
    3. в документации приведите 1-2 готовые команды, чтобы не ломать мозг

    получается, что заголовок имеет такую структуру:
    Код:
    typedef struct tagOwenHeader{
    	WORD	Low	: 8;
    	WORD	Size	: 4;
    	WORD	Query	: 1;
    	WORD	High	: 3;
    }OWEN_HEADER, *POWEN_HEADER;
    Low - младший байт адреса
    Size - размер поля данных - 2 (2 - это размер хеша имени)
    Query - признак запроса
    High - старшие 3 бита адреса

    перед расчетом CRC хеш команды записывается в пакет перевернутым байтами, т.е. сначала high, потом low,
    после расчета CRC, сам CRC так же переворачивается, после чего, вся полученная последовательность кодируется тетрадами

    на счет уровня приложения-представления - пока не проверял, будем смотреть дальше

    на счет переворачиваний, я пока без самого девайса не понял, но если разбить пакет на 3 сущности: заголовок, команда, CRC, то можно в принципе перевернуть все это дело перед кодированием тетрадами, но тогда не будет сходиться CRC и в данных будет бардак, либо можно тетрады выводить старшим полубайтом вперед, тогда можно не переворачивать, (все зависит от конечной реализации авторов; сам склюняюсь к тому, что все таки напутали порядок полубайтов), вобщем я сделал пока как есть

    в приложении мой конфигуратор команд, это консолька, которая позволяет просто собрать команду, в конечный вид, перед отправкой, так что сам девайс ей не нужен (если кто-то будет вводить имя команды, не забывайте про пробелы в конце этой команды, например "dev " или "ver ")

    (завтра проверю на девайсе, если успею, а сегодня просто выкладываю, т.к. команды уже сходятся по текущей теме и еще по этой: http://www.owen.ru/forum/showthread.php?t=7784)
    Вложения Вложения
    • Тип файла: zip owen.zip (44.6 Кб, Просмотров: 62)
    Последний раз редактировалось mega; 09.06.2010 в 15:18. Причина: подправил приложение: сдвиг старшей части адреса был на 4 бита, теперь как положено - на 8

  5. #5

    По умолчанию

    а вот и мой исходник этой консольки,
    кто желает встроить этот генератор себе в программу:
    Код:
    #include <windows.h>
    #include <tchar.h>
    #include <locale.h>
    #include <stdio.h>
    #include <conio.h>
    //
    BOOL ASCIIToCode( CHAR ch, CHAR*char_for_hash ){
    	ch	= toupper( ch ); 			//преобразуем все в верхний регистр
    	if( strchr( "0123456789", ch ) ){
    		*char_for_hash	= ch - '0';
    	}else if( (ch >= 'A') && (ch <= 'Z') ){
    		*char_for_hash	= ch - 'A' + 10;
    	}else{
    		switch( ch ){
    			case '-':
    				*char_for_hash	= 10 + 26;
    				break;
    			case '_':
    				*char_for_hash	= 10 + 26 + 1;
    				break;
    			case '/':
    				*char_for_hash	= 10 + 26 + 2;
    				break;
    			case ' ':
    				*char_for_hash	= 10 + 26 + 3;
    				break;
    			default:
    				return FALSE;
    		}
    	}
    	*char_for_hash	*= 2;
    	return TRUE;
    }
    //
    USHORT Hash( BYTE Byte, BYTE nbit, USHORT CRC ){
    	for( INT i = 0; i < nbit; i++, Byte <<= 1){
    		if(  ( Byte ^ ( CRC >> 8 ) ) & 0x80  ){
    			CRC	<<= 1;
    			CRC	^= 0x8F57;
    		}else{
    			CRC <<= 1;
    		}
    	}
    	return CRC;
    }
    //
    typedef union tagOwenHeader{
    	struct{
    		WORD	Low		: 8;
    		WORD	Size	: 4;
    		WORD	Query	: 1;
    		WORD	High	: 3;
    	};
    	BYTE		Bytes[2];
    }OWEN_HEADER, *POWEN_HEADER;
    //
    int _tmain( int argc, TCHAR *argv[] ) {
    	INT addr, size, Byte;
    	TCHAR query[2], cmd_fmt[2];
    	CHAR a_cmd[100];
    	BYTE Data[15];
    	BYTE Command[50];
    	OWEN_HEADER hdr;
    	INT l, i;
    	USHORT hash;
    	CHAR chfh;
    	//
    	_tsetlocale( LC_ALL, TEXT("Russian") );
    	//
    loop:
    	do{
    		fflush( stdin );
    		_tprintf_s( TEXT("Введите адрес устройства (0-2047): ") );
    	}while( _tscanf_s( TEXT("%i"), &addr ) != 1 );
    	//
    	do{
    		fflush( stdin );
    		_tprintf_s( TEXT("Это запрос? (y/n): ") );
    	}while( _tscanf_s( TEXT("%1[yn]"), &query, sizeof(query)/sizeof(TCHAR) ) != 1 );
    	//
    	do{
    		fflush( stdin );
    		_tprintf_s( TEXT("Введите размер блока данных (2-17): ") );
    	}while( (_tscanf_s( TEXT("%i"), &size ) != 1) || (size < 2) || (size > 17) );
    	//
    	do{
    		fflush( stdin );
    		_tprintf_s( TEXT("команда будет введена строкой? (y-строка/n-HASH): ") );
    	}while( _tscanf_s( TEXT("%1[yn]"), &cmd_fmt, sizeof(cmd_fmt)/sizeof(TCHAR) ) != 1 );
    	//
    	switch( cmd_fmt[0] ){
    		case TEXT('y'):
    cmd_loop:
    			do{
    				fflush( stdin );
    				_tprintf_s( TEXT("Введите имя команды (допустимый набор символов: [a-zA-Z0-9-_/ .]): ") );
    			}while( _tscanf_s( TEXT("%h[a-zA-Z0-9-_/ .]"), &a_cmd, sizeof(a_cmd)/sizeof(CHAR) ) != 1 );
    			//
    			_tprintf_s( TEXT("Имя команды: \"%hs\"\r\n"), a_cmd );
    			//
    			for( hash = 0, l = strlen( a_cmd ), i = 0 ; l-- ; ++i ){
    				if( a_cmd[i] != '.' ){
    					if( !ASCIIToCode( a_cmd[i], &chfh ) ){
    						goto cmd_loop;
    					}
    					if( a_cmd[i + 1] == '.' ){
    						++chfh;
    					}
    					hash	= Hash( chfh << 1, 7, hash );
    				}
    			}
    			break;
    		case TEXT('n'):
    			do{
    				fflush( stdin );
    				_tprintf_s( TEXT("Введите HASH команды: ") );
    			}while( _tscanf_s( TEXT("%hi"), &hash ) != 1 );
    			break;
    	}
    	_tprintf_s( TEXT("HASH команды: 0x%.4hx\r\n"), hash );
    	//
    	for( i = 0, l = size - 2 ; l-- ; ++i ){
    		do{
    			fflush( stdin );
    			_tprintf_s( TEXT("Введите %i-й байт команды (0-255): "), i + 3 );
    			if( _tscanf_s( TEXT("%i"), &Byte ) != 1 ){
    				continue;
    			}
    			if( Byte < 0 || Byte > 255 ){
    				continue;
    			}
    			Data[i] = Byte;
    			break;
    		}while( TRUE );
    	}
    	//
    	hdr.Low		= addr;
    	hdr.High	= addr >> 8;
    	hdr.Query	= ( query[0] == TEXT('y') ) ? 1 : 0;
    	hdr.Size	= (BYTE)(size - 2);
    	Command[0]	= hdr.Bytes[0];
    	Command[1]	= hdr.Bytes[1];
    	Command[2]	= (BYTE)(hash >> 8);
    	Command[3]	= (BYTE)hash;
    	for( i = 0, l = size - 2 ; l-- ; ++i ){
    		Command[4 + i]	= Data[i];
    	}
    	//
    	for( hash = 0, i = 0, l = 2 + size ; l-- ; ++i ){
    		hash	= Hash( Command[i], 8, hash );
    	}
    	Command[2 + size]	= (BYTE)(hash >> 8);
    	Command[3 + size]	= (BYTE)hash;
    	//
    	_tprintf_s( TEXT("--------\r\nКоманда:\r\n") );
    	for( i = 0, l = 4 + size ; l-- ; ++i ){
    		_tprintf_s( TEXT("%.2x"), Command[i] );
    	}
    	_tprintf_s( TEXT("\r\n#") );
    	for( i = 0, l = 4 + size ; l-- ; ++i ){
    		_tprintf_s( TEXT("%c"), 'G' + ( Command[i] >> 4 ) );
    		_tprintf_s( TEXT("%c"), 'G' + ( Command[i] & 0x0f ) );
    	}
    	_tprintf_s( TEXT("\\r\r\n--------\r\n") );
    	//
    	do{
    		fflush( stdin );
    		_tprintf_s( TEXT("Продолжить? (y/n): ") );
    	}while( _tscanf_s( TEXT("%1[yn]"), &query, sizeof(query)/sizeof(TCHAR) ) != 1 );
    	//
    	if( query[0] == TEXT('y') ){
    		goto loop;
    	}
    	return 0;
    }
    несколько похожий код я использовал у себя в трансляторе этого протокола в SCPI форму, пока все работает

    т.е. для съема-установки параметров использую формат обмена в удобочитаемой форме, типа такого:

    #devno:query:command\r

  6. #6

    По умолчанию

    то, что вы языком C плохо владеете, было ясно еще по первому сообщению. совершенно не обязательно выставлять это напоказ.

  7. #7

    По умолчанию

    Цитата Сообщение от дмитрий егоренков Посмотреть сообщение
    то, что вы языком C плохо владеете, было ясно еще по первому сообщению. совершенно не обязательно выставлять это напоказ.
    интересное умозаключение :)
    особенно интересно это слышать от человека, совершенно не понимающего битовую логику (я делаю такой вывод из посыла почитать тот самый документ, очевидные ошибки в котором я уже подчеркнул)

    если это техподдержка "овен", сочуствую вашей администрации, т.к. ликбез в культуре общения и программирования тут неизбежен :))

  8. #8

    По умолчанию

    Mega, огромное вам спасибо за прогу!!!!!!!!!! Замучился получать эту CRC Для СИ 8. Когда же в России кончится самопал!? И появятся нормальные описания протоколов с примерами.

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •