#include "lpc176x.h" #include "utils.h" #include "usb_hardware.h" #include "options.h" #include #ifdef USBTMC // #endif в конце файла #include #include <../usbtmc/gpib_parser.h> #include "../common/hal.h" #include "utilits.h" #include #include "gpib_parser_numutils.h" //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- >>> на начало числа unsigned int StrToInt( const char * str, unsigned int NumberLength, int * pReturn ) { char buffer[11]; unsigned int result; BOOL rc = FALSE; if( NumberLength > 10 ) return -1; // слишком длинное число или неверная длинна ( если принятое отриц число в unsigned, оно больше 0x7FFFFFFF s_memcpy( buffer, str, NumberLength ); buffer[NumberLength] = 0; // null terminator result = atoi( buffer ); if(result==0) // проверка на валидность результата, если ноль, проверяем валидность числа for(int m=0; buffer[m]; m++) // бежим по массиву до нультерминатора { if( IsDemicalChar( buffer[m]) ) // если это цифра ; // ничего не делаем else { if(buffer[m]==' ') // если это пробел ; // ничего не делаем else { // если это не цифра и не пробел, занчи число неверно задано и результат 0 // означает что число не распознано pReturn = NULL; // результат неверен break; } } } if( result != 0 || (result==0 && *buffer == '0' ) ) // число опознано или число нуль ( atoi нуль вернет если число не распознано !) if( pReturn != NULL ) { *pReturn = result; rc = TRUE; } return rc; } /* unsigned int Float2Str( float * pFloat, unsigned char * pBuffer, unsigned short wBufferLength ) { return Float2StrEx( pFloat, pBuffer, wBufferLength, 1000 ); } */ /* unsigned int Float2StrEx( float * pFloat, unsigned char * pBuffer, unsigned short wBufferLength, unsigned int accuracy ) { int FractAccuracy; // -- хранит точность числа после запятой, 10-один знак, 100-два int dwReturnBytes; // -- хранит длинну получаемой строки long int Integer; // -- хранит целочисленное представление целой и дробной части int counter; // -- хранит количество позиций ( символов ) целой и дробной частей числа int temp; // -- временное целое число float Float; // -- хранит 10-ый логарифм целочисленного представления дробной и целой частей числа // ----------------------------------------------------- unsigned int value = accuracy; FractAccuracy = 10; while(FractAccuracy0) { Float = log10( temp ); // вычисляю логарифм части (целой) для подсчета длинны части числа в символах counter = (unsigned int)Float; // получаю длинну части числа в символах ( 0 == один символ ) counter++; // увеличиваю длинну в символах, так как имеем десятичный логарифм. для числа 0-9 тоже должен быть символ (counter>1) } else { counter = 1; } // if( *pFloat < 0 ) *(pBuffer++) ='-'; // если число отрицательное, двигаю временно указатель вперед, чтобы сохранить знак '-' dwReturnBytes+=counter; // увеличиваю предположительную длинну получающейся строки // таким образом, в цикле он не затрется while( counter-- ) // converting // начинаем преобразование { // counter уменьшился на 1 в заголовке цикла и указывает на позицию символа в массиве pBuffer [ counter ] = (temp % 10) + '0'; // берем остаток от деления на 10 числа, прибавляем к нему ASCII код символа '0', ложим в массив temp /= 10; // делим число на 10, передвигаясь к следующей цифре в числе, справа на лево } // дойдем до нуля заголовке, значит часть числа преобразована // if( *pFloat < 0 ) { dwReturnBytes++; pBuffer--; } // двигаем обратно указатель, если сохраняли знак '-' и увеличиваем длинну строки с этим учетом // =============================================================== pBuffer+=dwReturnBytes; // оставляем позади преобразованную часть числа *(pBuffer++) ='.'; dwReturnBytes++; // ================ Converting fractional part ================== Float = (float)(*pFloat - (int) *pFloat); // Float = (FractAccuracy) * (Float); // берем дробную часть числа с заданной точностью. Integer = (int)Float; if( Float - (int)Float > 0.5 ) Integer++; // 0.15 = 0.14999 -> не должно выводиться 0,14 ! // 0,14999 * FractAccuracy --> 14.9 - 14 = 0.9; 0.9>0 => Integer++ temp = Integer; if( temp <0 ) temp=-temp; // сохраняем во временную переменную // get symbol count // ... и проверям знак временной переменной для вычисления log if(temp>0) { Float = log10( temp ); // вычисляю логарифм части (целой) для подсчета длинны части числа в символах counter = (unsigned int)Float; // получаю длинну части числа в символах ( 0 == один символ ) counter++; // увеличиваю длинну в символах, так как имеем десятичный логарифм. для числа 0-9 тоже должен быть символ (counter>1) } else { // counter = 1; } dwReturnBytes+= counter; // увеличиваю предположительную длинну получающейся строки // while( counter-- ) // converting // преобразуем аналогично целой части { pBuffer [ counter ] = (temp % 10) + '0'; // аналогично, как для целой части temp /= 10; } // ================================================================ pBuffer [ dwReturnBytes ] = 0; // ---------------------------------------------------------------- return dwReturnBytes; } */ unsigned int temperature_convert ( char * pBufferOut, unsigned short wBufferLen, signed short int dwTempEntry ) { float temp; float temp2; // --------------------------------------------------------------------------------------------------- // dwTempEntry - усредненная температура в формате B15 B14 .... B0, где B15-B6 биты содержат температуру // с точностью до 0,25град, а биты B5-B0 содержат поправку (усреднение) // // датчик измеряет с точностью 0,25*С. возвращает регистр формата REG16[ B15.....B6, B5....B0 ] // где биты B5...B0 равны нулю. то есть количество дискрет. Эти значения усредняются экспоненциальным // окном шириной 24, а значит теперь биты B5...B0 содержат поправку. Если с датчика мы бы просто // сдвинули на 6 битов вправо и получили колич дискрет по 0,25, то тут так делать не следует: // все биты содержат инф о температуре: надо рассматривать это значения не как количество дискрет // по 0,25*С, а как количество дискрет по 0,25/(2^6) !!! // // ------------------------------- // -- check sign -- проверка знака, если минус, то перевод из дополнительного кода temp = 1.000; if( dwTempEntry & (1<<15) ) // check sign bit { dwTempEntry ^= 0xffffffff; // converting from additional code dwTempEntry += 0x00000001; // converting from additional code temp = -1.000; } /* ----- способ 1 ----- */ //temp *= ((float)dwTempEntry) / ((float)(64*4)); // на 4 делим чтобы привести из дискрет по 0,25 к градусу. на 64 естественно делим чтобы сдвинуть значение вправо // // если просто сдвинуть в право на 6 разрядов и поделить на 4 мы потеряем усреднение! /* -------------------- */ /* ----- способ 2 ----- */ temp2 = ((dwTempEntry & 0xFF00)>>8) + (((dwTempEntry & 0xFF)/256.000)); temp*=temp2; /* -------------------- */ return GPIB_Float2Str( temp, pBufferOut, wBufferLen, Format_Float2Str_Ndot3 ); //return snprintf( pBufferOut,wBufferLen,"%.3f", temp); /*Float2Str( &temp, pBufferOut, wBufferLen);*/ } #endif