Вывод чисел на дисплей |
Автор ARV | |||||||||||||||||||
14.02.2008 г. | |||||||||||||||||||
Начинающие самостоятельно писать программы на Си для микроконтроллеров рано или поздно приходят к необходимости вывода информации на какой-то дисплей. Конечно, если используется ЖКИ со встроенным контроллером, а так же готовые библиотеки для символьного ввода-вывода на этот дисплей - проблем нет. Но если используется дисплей на семисегментных индикаторах, или нет возможности использовать функции Си по форматированному выводу (например, из-за ограниченности размера кода) - возникают проблемы с преобразованием числа в его символьное представление. Решение этой проблемы элементарно - написать собственные функции преобразования чисел в символьное представление. Покажу, как это можно сделать. Прежде всего, надо определиться с системой счисления для преобразования. Наиболее ходовые - это двоичная, восьмеричная, десятичная и шестнадцатеричная. Давайте сделаем такие функции, которые будут работать с любой системой. Опишем следующие константы:
Главное, что вы должны помнить здесь и далее: в тексте программы я применяю символы, удобные для чтения на мониторе компьютера (пробел - это пробел, минус - это минус и т.д.), но в вашей практической программе символы будут совсем иными. Скорее всего это будут битовые представления светящихся сегментов, т.е. для символа "минус" вполне может использоваться значение 0b00010000, которое означает, что светится только один из 8-и сегментов индикатора (8-й сегмент - это точка). Теперь опишем глобальные переменные и массивы, которые необходимы нам в работе.
Массив SYMBOLS[] - это список символов, которые соответствуют цифрам чисел выбранной системы счисления. Для двоичной достаточно всего двух символов 0 и 1, а для шестнадцатиричной потребуются 16 символов. Массив out[] - это "экранная область" нашего индикатора, т.е. тот массив, содержимое которого непрерывно динамически отображатеся на индикаторе. Разумеется, можно использовать этот массив и для хранения промежуточных преобразований.
Теперь займемся собственно преобразованием.
Функция convert(NUM) заполнит массив out[] символьным представлением беззнакового числа NUM. В своей работе эта функция использует ранее описанные константы, в частности - размер массива out[]. Массив заполняется целиком и справа налево, при этом число, если цифр в нем меньше чем размер массива, выводится с выравниванием вправо и с заполнением свободного места нулями. То есть для нашего примера размер выходного массива равне 6 позициям (т.е. у нас 6 индикаторов), и число 5 будет выведено как 000005, а число 10237 будет выведено как 010237. Очевидно, что левые нули - лишние, и напрасно загромаждают индикатор. Если необъходимо избавиться от них, модифицируем нашу функцию:
Чтобы левые нули заменялись пустым местом, потребовалось всего-навсего добавить один оператор if. Теперь число 12 будет выглядеть на индикаторе как . . . . 12 (точками я условно обозначил "пустые" индикаторы). По-моему, это гораздо эстетичнее. Однако все наши функции работают только с числами без знака, а ведь иной раз необходимо выводить и отрицательные числа... Напишем функцию, которая будет преобразовывать любое число со знаком в символьный вид, при этом левых нулей так же не будет.
Хотя логика работы функции довольно проста, код ее получился более длинным и сложным, чем предыдущие. Сначала мы проверяем, отрицательное ли число надо преобразовать или нет. Отрицательное число берется по модулю и далее начинается вывод, как и раньше. Однако, теперь мы применяем оператор do вместо оператора for (исключительно для примера), и прерываем его работу в момент, когда все число будет преобразовано. В этом месте переменная i будет указывать на место левее числа, т.е. место, где должен быть знак (если он нужен). Если же знак не нужен, то от этого места и до начала массива все ячейки заполняются символом пустого места, избавляя нас от левых нулей и возможного мусора в этих позициях.
Благодаря тому, что в наших функциях мы использовали максимально универсальные алгоритмы, они смогут переводить числа в представление любой системы счисления. Например, если значение DIG_BASE сделать равным 8, а массив SYMBOLS "укоротить" до 8 элементов, наши функции будут показывать нам восьмеричные числа, т.е. число 12 отобразится как 14, а 236 как 354. Аналогично и для любых других оснований, только следует помнить, что чем меньше основание системы счисления, тем длиннее символьное представление числа: так, для двоичного представления всего однобайтного числа требуется 8 "знакомест". Еще требуется учесть, что отрицательные числа не всегда существуют во всех системах: в шестнадцатиричном представлении знак минус не применяется никогда, равно как и в двоичном. Вывод больших чисел, чем допускает int (например, long) реализуется простым переопределением типа входной переменной NUM для любой из наших функций. Часто требуется выводить дробные десятичные числа. Знаю, что многие начинающие сразу же применят тип float и спросят "а как его вывести?" Отвечу, что в 90% случаев применение типа float не требуется, но если все же без него никак, то воспользуйтесь следующим приемом:
Наша маленькая хитрость заключается в том, что выводим мы, как и ранее, целое число, а десятичную точку просто устанавливаем в такое место. чтобы выглядело все, как положено. Эта хитрость должна объяснить, почему я говорил об отсутствии в 90% необходимости применения типа float: если нам нужна точность расчетов всего 2 знака после запятой, то все наши числа мы заранее умножим на 100 и будем производить вычисления над ними, как целыми числами, а потом, когда вычисления будут завершены, просто "отделим" 2 разряда, превартив их в сотые и десяты доли. Отказ от типа float очень существенно уменьшает размер кода программы, и увеличивает скорость расчетов! Надеюсь, эти примеры, которые вполне можно использовать в своих программах, послужат прежде всего стартовой точкой для написания своих аналогов, ведь в реальности требуется порой гораздо более существенное форматирование чисел, нежели приведенные простые примеры. Не забудьте, что все рассмотренные примеры функций контролируют размер символьного представления числа, и для слишком больших чисел на маленьком дисплее выведут только младшие разряды! Добавить в любимые (1) | Просмотров: 42637
Только зарегистрированные пользователи могут оставлять коментарии. |
« Пред. | След. » |
---|