В результате, как вы можете легко проверить, старшие байты окажутся нулевыми, а в ddM: ddL окажется число 474 — тот же самый результат. Но и это еще не все — такая процедура приведена скорее для иллюстрации общего принципа. Ее можно еще больше упростить, если обратить внимание на то, что сдвиг на восемь разрядов есть просто перенос значения одного байта в соседний (в старший, если сдвиг влево, и в младший — если вправо). Итого получится, что для сдвига на 16 разрядов вправо нам надо всего-навсего отбросить два младших байта и взять из исходного числа два
Если степень знаменателя дроби, как в данном случае, кратна 8, то действительно никакого деления, даже в виде сдвига, не требуется, но чаще всего это не так. Однако и тогда приведенный принцип может помочь — например, при делении на 215
вместо пятнадцатикратного сдвига вправо результат можно сдвинуть на один разряд влево (умножив число на два), а потом уже выделить из него старшие два байта. В программе далее мы будем делить на 210 = 1024, отбрасывая младший байт (деление на 8) и еще дважды сдвигая результат вправо. Вот такая специальная арифметика в МК.О двоично-десятичных числах или числах в формате BCD было подробно рассказано в главе 14. Как ясно из сказанного там, упакованные BCD-числа удобны для хранения данных, но неудобны для отображения и для выполнения арифметических операций с ними. Поэтому перед отображением упакованные BCD-числа распаковывают, перемещая старший разряд в отдельный байт и заменяя в обоих байтах старшие полубайты нулями. А перед проведением арифметических действий их переводят в обычный формат, после чего опять преобразуют в упакованный формат BCD. Вот этими операциями мы и займемся. Следует отметить, что в системе команд процессора 8051 (а также и знаменитого 8086) есть специальные команды десятичной коррекции, но в AVR их нет, и придется изобретать им замену самостоятельно.
В области двоично-десятичных преобразований (BCD-преобразований) есть три основные задачи:
□ преобразование двоичного/шестнадцатеричного числа в упакованный BCD-формат;
□ распаковка упакованного BCD-формата для непосредственного представления десятичных чисел с целью их вывода на дисплей;
□ обратное преобразование упакованного BCD-формата в двоичный/шестнадцатеричный с целью, например, произведения арифметических действий над ним.
Некоторые процедуры для преобразования в BCD-формат содержатся в фирменной
Заодно приведем одно из решений обратной задачи — преобразование упакованного BCD в hex-число, после чего с ним можно производить арифметические действия (хотя в программе далее это нам не понадобится). По сравнению с «фирменной»
Более громоздкая задача — преобразование многоразрядных чисел. Преобразовывать BCD-числа, состоящие более чем из одного байта, обратно в hex-формат приходится крайне редко, зато задача прямого преобразования возникает на каждом шагу. В программе далее нам понадобится преобразование 16-разрядного hex-числа в упакованный BCD. Реализацию этой задачи нет смысла рассматривать подробно — она во всем аналогична рассмотренному случаю, с готовой процедурой
В проектируемом измерителе для всех операций переменных-регистров не хватит, и часть данных придется хранить в ОЗУ (SRAM). Познакомимся с общими принципами обращения к ячейкам этой памяти.
Для чтения и записи SRAM предназначены регистры
Покажем основной порядок действий при чтении из памяти в случае использования регистра
Режимы с преддекрементом и постинкрементом используются, когда нужно прочесть/записать целый фрагмент из памяти. Схема действий аналогичная, только команды выглядят так:
Абсолютно аналогично выглядят команды чтения: