Заметки на полях

Традиционная область использования команд двоично-десятичной коррекции, в том числе и в процессорах х86 — манипуляции со значением времени, полученным из микросхем RTC, в которых часы, минуты и секунды всегда хранятся в упакованном BCD-формате. Как вы увидите далее, такой формат хранения довольно удобен на практике. Однако область применения микроконтроллерных систем далеко не исчерпывается подсчетом и демонстрацией времени, потому нам придется выйти за рамки однобайтовых кодов, для которых, собственно, инструкция коррекции и создавалась. Уже для двухбайтовых чисел ее применение вызывает только лишние сложности.

В области BCD-преобразований есть три основные задачи:

• Преобразование двоичного/шестнадцатеричного числа в упакованный BCD-формат.

• Распаковка упакованного BCD-формата для непосредственного представления десятичных чисел с целью их вывода на дисплей.

• Обратное преобразование упакованного BCD-формата в двоичный/шестнадцатеричный для выполнения над ним, например, арифметических действий.

Некоторые процедуры для этой цели приведены в фирменной Application notes 204. При их использовании нужно учесть ряд моментов. Так, процедура bin2BCD8 для преобразования однобайтового числа в BCD работает только для чисел от 0 до 99 (для больших чисел нужен еще один байт, точнее, тетрада — в ней будет храниться старший разряд). В «аппноте» процедура представлена в универсальном виде, пригодном (при небольшой модификации) и для получения упакованного BCD, и для изначально распакованного (результат в двух отдельных байтах). Чтобы не путаться, приведу здесь ее вариант (листинг 15.3), который заодно более экономичный по количеству используемых регистров. Исходное hex-число содержится в регистре temp, распакованный результат — в temp1: temp. Как и в предыдущих случаях, комментарии сохранены из исходного текста.

Листинг 15.3

;преобразование 8-разрядного hex в неупакованный BCD

;вход hex= temp, выход BCD temp1-старший; temp — младший

;эта процедура работает только для исходного hex от 0 до 99

bin2bcd8:

       clr temp1  ;clear result MSD

bBCD8_1: subi temp,10  ;input = input — 10

       brcs bBCD8_2  ;abort if carry set

       inc temp1  ;inc MSD

       rjmp bBCD8_1  ;loop again

bBCD8_2:subi temp, — 10  ;compensate extra subtraction

ret

В листинге 15.4 приведено одно из решений обратной задачи — преобразования упакованного BCD (например, тех же значений часов, минут и секунд из RTC) в hex-число, после чего с ним можно производить арифметические действия. По сравнению с «фирменной» BCD2bin8 эта процедура хоть и немного длиннее, но понятнее и более предсказуема по времени выполнения («фирменная» может занимать от 3 до 48 тактов).

Листинг 15.4

;на входе в temp упакованное BCD-значение

;на выходе в temp hex-значение

;temp1 — вспомогательный регистр для промежуточного хранения temp

;действительна только для семейства Меgа

HEX_BCD:

         mov temp1, temp

         andi temp, 0b11110000  ; распаковываем — старший

         swap temp  ;старший в младшей тетраде

         mul temp,mult10  ;умножаем на 10, в r0 результат умножения

         mov temp,temp1  ;возвращаемся к исходному

         andi temp,0b00001111  ;младший

         add temp,r0  ;получили hex

ret

Перейти на страницу:

Поиск

Похожие книги