Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вывод числа на ЖК экран
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Freeze Anti
Здравствуйте.
Я вот тут дорабатываю программу, написанную в IAR Embedded Workbench, для одного устройства. Мне необходимо, чтобы датчик регистрировал значения до 1000 не важно чего. В предыдущей версии достигались значения только 500, поэтому ниже описанная мной проблема не стояла.
В программе используются дробные значения. По каким-то неведомым мне причинам разработчики программы решили использовать целочисленные переменные, только в выводе на экран перед двумя последними цифрами ставить точку.
Для хранения данной переменной переменной используется тип unsigned short. Как известно, тип unsigned short может хранить максимальное значение 65535. Если мы теперь поделим его на 100, у нас получится всего лишь 655.35. А мне необходимо записывать значения до 1000 (ну, если быть точным - до 1050).
Если я просто изменяю тип переменной на unsigned long, то программа успешно выполняется (компилится), только ЖК экран при выполнении функции вывода заполнется полностью символами "/".
Хотелось бы узнать, из-за чего может происходить данная ошибка и как ее можно решить, не слишком сильно меняя код всей программы.
Вот код функции, выполняющей вывод на экран псевдодробного числа.

Код
void WriteFloatValue(unsigned short Value, unsigned char intDigits,
                     unsigned char fraqDigits)
{ unsigned short Divisor = INIT_DEC_MASK_VALUE;
  unsigned short tmpValue;
  unsigned char i,chDigit;

  tmpValue = Value;                     // tmpValue - рабочия копия числа

  // Рассматриваем целую часть числа Value
  for (i=MAX_INT_POSITIONS; i>0; i--)
  { chDigit = tmpValue / Divisor;       // Цифра i-го разряда числа
    tmpValue -= chDigit * Divisor;      // Устранение i-го разряда из числа

    if (i <= intDigits)                 // Добрались до отображаемых разрядов
    { chDigit += 0x30;                  // Формируем код символа
      lcdWriteData(chDigit);            // Вывод цифры на индикатор
    }
    
    Divisor /= 10;
  }

  lcdWriteData(0x2E);                   // Ставим десятичную точку

  // Рассматриваем дробную часть числа Value
  for (i=fraqDigits; i>0; i--)
  { chDigit = tmpValue / Divisor;       // Цифра i-го разряда числа
    tmpValue -= chDigit * Divisor;      // Устранение i-го разряда из числа

    chDigit += 0x30;                    // Формируем код символа
    lcdWriteData(chDigit);              // Вывод цифры на индикатор
    
    Divisor /= 10;
  }
}
Alex11
Работать будет, если не забыть правильно поменять типы и константы. Value, tmpValue и Divisor должны быть unsigned long, константа INIT_DEC_MASK_VALUE должна быть степенью десятки, большей максимального числа, которе может быть на входе.
shasik
Правильно Вам говорят, нужно еще соответствующим образом переорпеделить значения констант. Кстати, в этой программе запросто может деление на 0 выскочить (при несогласованном выборе значений MAX_INT_POSITIONS и INIT_DEC_MASK_VALUE).

Пример: после замены на unsigned long, чтобы из числа 105024 получить 1050,24 необходимо чтобы
MAX_INT_POSITIONS = 4
INIT_DEC_MASK_VALUE = 100000
и вызов функции WriteFloatValue(105024, 4, 2)
GDI
Цитата
По каким-то неведомым мне причинам разработчики программы решили использовать целочисленные переменные, только в выводе на экран перед двумя последними цифрами ставить точку.

И правильно сделали, ибо нефиг флоатами без сильной нужды пользоваться на 8-битных платформах. Потому как поставить точку в нужном месте при выводе числа на индикатор требует значительно меньше вычислительных ресурсов нежели работа с полноценным float. В общем возьмите этот опыт себе на вооружение и будут ваши программы быстры и компактны.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.