В области 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
Более громоздкая задача — преобразование многоразрядных чисел. Преобразовывать BCD-числа, состоящие более чем из одного байта, обратно в НЕХ-формат приходится крайне редко, зато задача прямого преобразования возникает на каждом шагу. Я здесь приведу отсутствующую в «аппноте» 204 процедуру конвертации чисел, выходящих за рамки 16-разрядного диапазона. Например, такая задача может возникнуть при конструировании многоразрядных счетчиков. Ограничимся диапазоном в 7 десятичных знаков (9 999 999), тогда исходное число будет укладываться в 3 байта (24 разряда). В целях универсальности в процедуре, которая приводится далее в листинге 15.5, на выходе получается отдельно неупакованный (сразу для индикации) и упакованный десятичный формат. Сократить число необходимых регистров можно, если большую часть результатов сразу записывать в SRAM — в дальнейшем мы так и будем поступать, а здесь для наглядности работаем только с регистрами.
Отметим, что процедура bin2BCD24 сделана на основе «фирменной» bin2BCD16 и, как и последняя, использует хитрый прием с записью значений в регистры по адресам памяти: так можно производить над адресами разные манипуляции, меняя регистры (аналогично адресной арифметике в языке С). Как и в других случаях, сохранена часть оригинальных комментариев из исходной «фирменной» процедуры.
Листинг 15.5
;процедура преобразования 3-байтового hex в упакованный (4 регистра)
;и неупакованный (7 регистров) BCD
;исходное значение в регистрах
.def Count0 = r25
.def Count1 = r26
.def Count2 = r27
;на выходе упакованный BCD в регистрах
. def tBCD0 =r13 ;BCD value digits 1 and 0
.def tBCD1 =r14 ;BCD value digits 3 and 2
.def tBCD2 =r15 ;BCD value digit 4,5
.def tBCD3 =r16 ;BCD value digit 6
; на выходе неупакованный BCD в регистрах
.def N1 =r1 ;младший
. def N2 =r2
.def N3 =r3
.def N4 =r4
Читать дальше
Конец ознакомительного отрывка
Купить книгу