Операции с числами в формате BCD



О двоично‑десятичных числах или числах в формате BCD было подробно рассказано в главе 14. Как ясно из сказанного там, упакованные BCD‑числа удобны для хранения данных, но неудобны для отображения и для выполнения арифметических операций с ними. Поэтому перед отображением упакованные BCD‑числа распаковывают, перемещая старший разряд в отдельный байт и заменяя в обоих байтах старшие полубайты нулями. А перед проведением арифметических действий их переводят в обычный формат, после чего опять преобразуют в упакованный формат BCD. Вот этими операциями мы и займемся. Следует отметить, что в системе команд процессора 8051 (а также и знаменитого 8086) есть специальные команды десятичной коррекции, но в AVR их нет, и придется изобретать им замену самостоятельно.

В области двоично‑десятичных преобразований (BCD‑преобразований) есть три основные задачи:

□ преобразование двоичного/шестнадцатеричного числа в упакованный BCD‑формат;

□ распаковка упакованного BCD‑формата для непосредственного представления десятичных чисел с целью их вывода на дисплей;

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

Некоторые процедуры для преобразования в BCD‑формат содержатся в фирменной Application notes 204 . Приведем здесь вариант такой процедуры, более экономичный в части использования регистров. Исходное hex‑число находится в регистре temp , распакованный результат – в tempi: temp . Процедура довольно короткая:

 

 

Заодно приведем одно из решений обратной задачи – преобразование упакованного BCD в hex‑число, после чего с ним можно производить арифметические действия (хотя в программе далее это нам не понадобится). По сравнению с «фирменной» BCD2bin8 эта процедура хоть и немного длиннее, но понятнее и более предсказуема по времени выполнения:

 

 

Более громоздкая задача – преобразование многоразрядных чисел. Преобразовывать BCD‑числа, состоящие более чем из одного байта, обратно в hex‑формат приходится крайне редко, зато задача прямого преобразования возникает на каждом шагу. В программе далее нам понадобится преобразование 16‑разрядного hex‑числа в упакованный BCD. Реализацию этой задачи нет смысла рассматривать подробно – она во всем аналогична рассмотренному случаю, с готовой процедурой bin2BCD16 вы можете ознакомиться в исходном тексте программы TPjmeter (см. далее).

 

 

Хранение данных в ОЗУ

В проектируемом измерителе для всех операций переменных‑регистров не хватит, и часть данных придется хранить в ОЗУ (SRAM). Познакомимся с общими принципами обращения к ячейкам этой памяти.

Для чтения и записи SRAM предназначены регистры х, y и z – т. е. пары r27:r26, r29:r28 и r31:r30 , которые по отдельности еще именуют XH: XL, YH: YL, ZH: ZL – в том же порядке (т. е. старшим в каждой паре служит регистр с большим номером). Если обмен данными производится между памятью и другим регистром общего назначения, то достаточно задействовать только одну из этих пар (любую), если же между областями памяти – целесообразно задействовать две. Независимо от того, какую из пар мы используем, чтение и запись происходят по идентичным схемам, меняются только имена регистров.

Покажем основной порядок действий при чтении из памяти в случае использования регистра z (r31:r30 ). Чтение одной ячейки с заданным адресом Address , коррекция ее значения и обратная запись производятся так:

 

 

Режимы с преддекрементом и постинкрементом используются, когда нужно прочесть/записать целый фрагмент из памяти. Схема действий аналогичная, только команды выглядят так:

 

 

Абсолютно аналогично выглядят команды чтения:

 

 

А вот как можно в цикле записать одно и то же значение из temp в 16 идущих подряд ячеек памяти, начиная с нулевого адреса старших 256 байтов памяти:

 

 

Напомним, что область пользовательского ОЗУ начинается с адреса $60 (9610). При попытке записать что‑то по меньшему адресу вы обязательно попадаете в какой‑то регистр, и результат окажется непредсказуем. Также не следует забывать о том, что последние адреса ОЗУ заняты под стек, который обязательно задействуется, если в программе применяются прерывания. Так, в ATmega8535 имеется 512 байтов SRAM, потому последний адрес (RAMEND ) будет равен 96 + 512 – 1 = 607 ($25F), но не стоит занимать адреса ОЗУ выше примерно 592 ($250).

 

 


Дата добавления: 2019-02-12; просмотров: 239; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!