реклама на сайте
подробности

 
 
> Вывод числа на ЖК экран, Изменяю тип переменной, а вместо числа рисуется НЕЧТО
Freeze Anti
сообщение Jun 28 2007, 05:09
Сообщение #1


Частый гость
**

Группа: Новичок
Сообщений: 153
Регистрация: 29-03-07
Из: Саратов
Пользователь №: 26 613



Здравствуйте.
Я вот тут дорабатываю программу, написанную в 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;
  }
}


--------------------
!!! All you need is LOVE !!!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 3)
Alex11
сообщение Jun 28 2007, 06:16
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 106
Регистрация: 23-10-04
Из: С-Петербург
Пользователь №: 965



Работать будет, если не забыть правильно поменять типы и константы. Value, tmpValue и Divisor должны быть unsigned long, константа INIT_DEC_MASK_VALUE должна быть степенью десятки, большей максимального числа, которе может быть на входе.
Go to the top of the page
 
+Quote Post
shasik
сообщение Jun 28 2007, 06:27
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 319
Регистрация: 3-09-05
Из: Беларусь, Новополоцк
Пользователь №: 8 188



Правильно Вам говорят, нужно еще соответствующим образом переорпеделить значения констант. Кстати, в этой программе запросто может деление на 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)
Go to the top of the page
 
+Quote Post
GDI
сообщение Jun 28 2007, 07:00
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Цитата
По каким-то неведомым мне причинам разработчики программы решили использовать целочисленные переменные, только в выводе на экран перед двумя последними цифрами ставить точку.

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


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 16:41
Рейтинг@Mail.ru


Страница сгенерированна за 0.01355 секунд с 7
ELECTRONIX ©2004-2016