Пятница, 01 июля 2011 21:54

Особенности преобразования двоичного числа в двоично-десятичный код методом левого сдвига Featured

Written by
Rate this item
(0 votes)

Двоично-десятичный код используется, как правило, в устройствах ввода-вывода для организации удобного для пользователя способа обмена информации с цифровым устройством, и в первую очередь, в узлах (модулях) индикации.

Один весьма известный, в узком кругу, специалист написал в учебных целях статью с 42 подобными подпрограммами (ПП). Все эти подпрограммы, и статья в целом, отвечают только на один из двух основных вопросов, которые интересуют начинающих осваивать МК (и не только их), а именно на вопрос: «Как?».

 

 

А вот на второй, не менее важный, вопрос («Почему именно так?») в этой статье ответа нет. Вообще, складывается впечатление, что этот писатель и сам не имеет четкого ответа на сей вопрос.

Надеюсь, что заинтересованный читатель найдет ответ на него в настоящей статье.

Для того, чтобы разобраться в этом вопросе надо понимать следующие смежные с программированием темы: системы счисления, основы двоичной арифметики и алгебры логики.

Напомню, что в большинстве МК используется двоичный код 8-4-2-1. Он сведен в таблицу 1. Все двоичные числа этой таблицы четырех разрядные, т.е. представляют собой тетрады.

Таблица 1. Двоичный код 8-4-2-1

 

 

 

С помощью кода 8-4-2-1 можно закодировать как 10 цифр десятичной системы счисления, так и все 16 шестнадцатеричной.

Обратите внимание на тетрады, выделенные серой заливкой. Эти тетрады для двоично-десятичного кода явно лишние. Их иногда называют запрещенными тетрадами или псевдотетрадами. При преобразовании двоичного кода в двоично-десятичный от них (псевдотетрад) надо грамотно избавляться. Это одна из проблем этого преобразования.

Ещё необходимо представлять, что сдвиг двоичного числа на один разряд (бит) влево эквивалентен умножению его на два.

Пример: 1010 0111 = 167
Сдвинем это двоичное число на бит влево и получим вдвое большее число: 1 0100 1110 = 334.

Вспомнив все это, мы готовы к дальнейшему изучению преобразования двоичного кода в двоично-десятичный методом левого сдвига.

При этом будем помнить, что двоично-десятичный код не должен содержать псевдотетрад (см. табл. 1), и то, что при этом преобразовании возникают проблемы с переносом 1 между тетрадами, каждая из которых – это один десятичный разряд.

Так, при переносе 1 из младшего двоично-десятичного разряда (тетрады) в следующий более старший (следующую тетраду), число «теряет» 6 единиц, т.к. весовой коэффициент этого разряда 10, а в двоичной и системе счисления (и шестнадцатеричной тоже) он равен 16. Следовательно, сдвигая число влево надо производить соответствующую коррекцию, чтобы получить правильный результат.

Возьмем произвольное восьмиразрядное двоичное число. Например: 11101101 (в десятичной системе оно равно 237, а шестнадцатеричной – EDh). Затем будем «вдвигать» это двоичное число справа налево, в так называемую, двоично-десятичную разрядную сетку, производя необходимую для преобразования коррекцию.

 

 

 

Первые три сдвига для этого числа можно сделать «безболезненно», без всякой коррекции. В младшие разряды двоично-десятичной сетки записалось число 7.
Следующий четвертый сдвиг его удвоит (вспомним, что левый сдвиг – это умножение на два): 1110 = 14
Получили запрещенную тетраду (псевдотетраду). Чтобы от псевдотетрады «избавиться», к ней надо добавить число 6 (110 в двоичной системе).
Проделаем эту операцию: 1110 + 110 = 10100. Вспомним, что полученное число – это не простое двоичное число, а двоично-десятичое число. Весовой коэффициент его старшего разряда не 16, а 10. Значит, двоично-десятичное число 10100 будет равно десятичному числу 14. Коррекция произведена.
На практике используется более удобный и универсальный способ коррекции. Суть его в том, коррекция осуществляется до четвертого сдвига, и то только тогда, когда это необходимо. Дело в том, что уже после третьего сдвига можно однозначно судить получится при следующем сдвиге псевдотетрада или нет. Напомню, что псевдотетрады возникают для чисел больших девяти. Это значит, если после третьего сдвига в трех младших разрядах будет двоичное число не больше чем 4 (100), то после следующего сдвига псевдотетрада не появится. Псевдотетрады возникнут тогда, когда перед четвертым сдвигом (т.е. перед очередным умножением на 2) в двоично-десятичной сетке будет любое число ≥5 (101), как в нашем случае было 7. Для осуществления коррекции перед четвертым сдвигом надо:

  1. Проверить число в трех младших разрядах двоично-десятичной сетки.
  2. Если оно меньше 5, то коррекцию не производить.
  3. Если оно ≥5 (101), то к нему надо добавить 3 (011).

Этот третий случай мы как раз и наблюдаем.
Продолжим, добавим тройку, и сделаем 4-й сдвиг.

 

 

 

Обратите внимание, в двоично-десятичной сетке после 4-го сдвига у нас появилось число 10100, т.е. тоже число 14, что и при добавлении 6 после четвертого сдвига при рассмотренном ранее способе коррекции.
Почему так происходит?
Ответ прост. При левом сдвиге происходит удвоение как корректируемого, так и корректирующего числа (3 × 2 = 6). С математической точки зрения способы равнозначны.
Производим 5-й сдвиг.

 

 

 

Обратите внимание, младшая тетрада двоично-десятичного числа равна 1001 = 9, что вполне допустимо. Само двоично-десятичное число 101001 = 29. При  следующем сдвиге без коррекции получится число  1010011 = 53, а должно быть 29 × 2 = 58. Откорректировать возникшую погрешность можно, если перед сдвигом добавить к сдвигаемому числу «волшебное число» 3.

 

Возникла новая ситуация. В младшей тетраде двоично-десятичного числа «расположилось» число 9 (1001), а в средней 5 (101), точнее 50 (см. весовые коэффициенты разрядов этой декады).
Это значит, перед следующим сдвигом надо делать коррекцию не только младшей тетрады, но и следующей средней. Для коррекции младшей тетрады к ней надо добавить 3, а для коррекции средней – 30, что и сделано ниже.

 

 

 

Теперь в младшей тетраде находится число 8 (1000), а, значит, при следующем (последнем) сдвиге и при отсутствии коррекции 1 перейдет в следующую тетраду в разряд с весовым коэффициентом 10, а не 16, как это было бы у обычного двоичного числа. Следовательно, перед 8-м сдвигом к младшей тетраде надо добавить 3.

 

 

 

 

Преобразование двоичного числа в двоично-десятичное закончено. Слева получен ожидаемый нами двоично-десятичный код десятичного трехразрядного числа 237
(10 0011 0111), но это на бумаге, в теории. В реальном микроконтроллере все выглядит похоже, но несколько иначе. Хотя бы потому, что четырехразрядных (четырехбитовых) регистров не существует и для каждого двоично-десятичного разряда выделяется полный регистр. Для МК PIC среднего семейства (и не только) он восьмиразрядный. В старшей тетраде этого регистра всегда должны быть нули (0000). Это несколько усложняет алгоритм преобразования.

Понимая все это, заметно проще разобраться в любой подпрограмме преобразования двоичного числа в двоично-десятичное методом левого сдвига.
Одна из лучших, на мой взгляд, таких подпрограмм – это универсальная подпрограмма Алексея Черепанова, которую можно найти здесь.

Read 11775 times Last modified on Вторник, 02 сентября 2014 14:50

Все права принадлежат ChipMK.ru. При копировании материала ссылка обязательна. 2011-2017 © ChipMK.ru

ChipMk.ru Яндекс.Метрика
PRCY.ru