utilits.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #include "lpc176x.h"
  2. #include "utils.h"
  3. #include "usb_hardware.h"
  4. #include "options.h"
  5. #include <stdio.h>
  6. #ifdef USBTMC // #endif в конце файла
  7. #include <math.h>
  8. #include <../usbtmc/gpib_parser.h>
  9. #include "../common/hal.h"
  10. #include "utilits.h"
  11. #include <stdlib.h>
  12. #include "gpib_parser_numutils.h"
  13. //----------------------------------------------------------------------------
  14. //----------------------------------------------------------------------------
  15. //----------------------------------------------------------------------------
  16. //---------------------------------------------------------------------------- >>> на начало числа
  17. unsigned int StrToInt( const char * str, unsigned int NumberLength, int * pReturn )
  18. {
  19. char buffer[11];
  20. unsigned int result;
  21. BOOL rc = FALSE;
  22. if( NumberLength > 10 ) return -1; // слишком длинное число или неверная длинна ( если принятое отриц число в unsigned, оно больше 0x7FFFFFFF
  23. s_memcpy( buffer, str, NumberLength );
  24. buffer[NumberLength] = 0; // null terminator
  25. result = atoi( buffer );
  26. if(result==0) // проверка на валидность результата, если ноль, проверяем валидность числа
  27. for(int m=0; buffer[m]; m++) // бежим по массиву до нультерминатора
  28. {
  29. if( IsDemicalChar( buffer[m]) ) // если это цифра
  30. ; // ничего не делаем
  31. else
  32. {
  33. if(buffer[m]==' ') // если это пробел
  34. ; // ничего не делаем
  35. else
  36. { // если это не цифра и не пробел, занчи число неверно задано и результат 0
  37. // означает что число не распознано
  38. pReturn = NULL; // результат неверен
  39. break;
  40. }
  41. }
  42. }
  43. if( result != 0 || (result==0 && *buffer == '0' ) ) // число опознано или число нуль ( atoi нуль вернет если число не распознано !)
  44. if( pReturn != NULL )
  45. { *pReturn = result; rc = TRUE; }
  46. return rc;
  47. }
  48. /*
  49. unsigned int Float2Str( float * pFloat, unsigned char * pBuffer, unsigned short wBufferLength )
  50. {
  51. return Float2StrEx( pFloat, pBuffer, wBufferLength, 1000 );
  52. }
  53. */
  54. /*
  55. unsigned int Float2StrEx( float * pFloat, unsigned char * pBuffer, unsigned short wBufferLength, unsigned int accuracy )
  56. {
  57. int FractAccuracy; // -- хранит точность числа после запятой, 10-один знак, 100-два
  58. int dwReturnBytes; // -- хранит длинну получаемой строки
  59. long int Integer; // -- хранит целочисленное представление целой и дробной части
  60. int counter; // -- хранит количество позиций ( символов ) целой и дробной частей числа
  61. int temp; // -- временное целое число
  62. float Float; // -- хранит 10-ый логарифм целочисленного представления дробной и целой частей числа
  63. // -----------------------------------------------------
  64. unsigned int value = accuracy;
  65. FractAccuracy = 10; while(FractAccuracy<value) FractAccuracy*=10;
  66. // -----------------------------------------------------
  67. dwReturnBytes = 0;
  68. // ================ Converting integer part ==================
  69. Integer = (int) *pFloat; // получаем целую часть числа
  70. temp = Integer; if( temp <0 ) temp=-temp; // сохраняем во временную переменную
  71. // get symbol count // ... и проверям знак временной переменной для вычисления log
  72. if(temp>0) {
  73. Float = log10( temp ); // вычисляю логарифм части (целой) для подсчета длинны части числа в символах
  74. counter = (unsigned int)Float; // получаю длинну части числа в символах ( 0 == один символ )
  75. counter++; // увеличиваю длинну в символах, так как имеем десятичный логарифм. для числа 0-9 тоже должен быть символ (counter>1)
  76. } else {
  77. counter = 1;
  78. } //
  79. if( *pFloat < 0 ) *(pBuffer++) ='-'; // если число отрицательное, двигаю временно указатель вперед, чтобы сохранить знак '-'
  80. dwReturnBytes+=counter; // увеличиваю предположительную длинну получающейся строки
  81. // таким образом, в цикле он не затрется
  82. while( counter-- ) // converting // начинаем преобразование
  83. { // counter уменьшился на 1 в заголовке цикла и указывает на позицию символа в массиве
  84. pBuffer [ counter ] = (temp % 10) + '0'; // берем остаток от деления на 10 числа, прибавляем к нему ASCII код символа '0', ложим в массив
  85. temp /= 10; // делим число на 10, передвигаясь к следующей цифре в числе, справа на лево
  86. } // дойдем до нуля заголовке, значит часть числа преобразована
  87. //
  88. if( *pFloat < 0 ) { dwReturnBytes++; pBuffer--; } // двигаем обратно указатель, если сохраняли знак '-' и увеличиваем длинну строки с этим учетом
  89. // ===============================================================
  90. pBuffer+=dwReturnBytes; // оставляем позади преобразованную часть числа
  91. *(pBuffer++) ='.'; dwReturnBytes++;
  92. // ================ Converting fractional part ==================
  93. Float = (float)(*pFloat - (int) *pFloat); //
  94. Float = (FractAccuracy) * (Float); // берем дробную часть числа с заданной точностью.
  95. Integer = (int)Float;
  96. if( Float - (int)Float > 0.5 ) Integer++; // 0.15 = 0.14999 -> не должно выводиться 0,14 !
  97. // 0,14999 * FractAccuracy --> 14.9 - 14 = 0.9; 0.9>0 => Integer++
  98. temp = Integer; if( temp <0 ) temp=-temp; // сохраняем во временную переменную
  99. // get symbol count // ... и проверям знак временной переменной для вычисления log
  100. if(temp>0) {
  101. Float = log10( temp ); // вычисляю логарифм части (целой) для подсчета длинны части числа в символах
  102. counter = (unsigned int)Float; // получаю длинну части числа в символах ( 0 == один символ )
  103. counter++; // увеличиваю длинну в символах, так как имеем десятичный логарифм. для числа 0-9 тоже должен быть символ (counter>1)
  104. } else { //
  105. counter = 1;
  106. }
  107. dwReturnBytes+= counter; // увеличиваю предположительную длинну получающейся строки
  108. //
  109. while( counter-- ) // converting // преобразуем аналогично целой части
  110. {
  111. pBuffer [ counter ] = (temp % 10) + '0'; // аналогично, как для целой части
  112. temp /= 10;
  113. }
  114. // ================================================================
  115. pBuffer [ dwReturnBytes ] = 0;
  116. // ----------------------------------------------------------------
  117. return dwReturnBytes;
  118. }
  119. */
  120. unsigned int temperature_convert ( char * pBufferOut, unsigned short wBufferLen, signed short int dwTempEntry )
  121. {
  122. float temp;
  123. float temp2;
  124. // ---------------------------------------------------------------------------------------------------
  125. // dwTempEntry - усредненная температура в формате B15 B14 .... B0, где B15-B6 биты содержат температуру
  126. // с точностью до 0,25град, а биты B5-B0 содержат поправку (усреднение)
  127. //
  128. // датчик измеряет с точностью 0,25*С. возвращает регистр формата REG16[ B15.....B6, B5....B0 ]
  129. // где биты B5...B0 равны нулю. то есть количество дискрет. Эти значения усредняются экспоненциальным
  130. // окном шириной 24, а значит теперь биты B5...B0 содержат поправку. Если с датчика мы бы просто
  131. // сдвинули на 6 битов вправо и получили колич дискрет по 0,25, то тут так делать не следует:
  132. // все биты содержат инф о температуре: надо рассматривать это значения не как количество дискрет
  133. // по 0,25*С, а как количество дискрет по 0,25/(2^6) !!!
  134. //
  135. // -------------------------------
  136. // -- check sign -- проверка знака, если минус, то перевод из дополнительного кода
  137. temp = 1.000;
  138. if( dwTempEntry & (1<<15) ) // check sign bit
  139. {
  140. dwTempEntry ^= 0xffffffff; // converting from additional code
  141. dwTempEntry += 0x00000001; // converting from additional code
  142. temp = -1.000;
  143. }
  144. /* ----- способ 1 ----- */
  145. //temp *= ((float)dwTempEntry) / ((float)(64*4)); // на 4 делим чтобы привести из дискрет по 0,25 к градусу. на 64 естественно делим чтобы сдвинуть значение вправо
  146. // // если просто сдвинуть в право на 6 разрядов и поделить на 4 мы потеряем усреднение!
  147. /* -------------------- */
  148. /* ----- способ 2 ----- */
  149. temp2 = ((dwTempEntry & 0xFF00)>>8) + (((dwTempEntry & 0xFF)/256.000));
  150. temp*=temp2;
  151. /* -------------------- */
  152. return GPIB_Float2Str( temp, pBufferOut, wBufferLen, Format_Float2Str_Ndot3 );
  153. //return snprintf( pBufferOut,wBufferLen,"%.3f", temp); /*Float2Str( &temp, pBufferOut, wBufferLen);*/
  154. }
  155. #endif