ПРОГРАММИРУЕМ МИКРОКОНТРОЛЛЕРЫ Z8 М.Гладштейн г.Рыбинск Часть 8. Арифметические операции В этой статье даются примеры использования арифметических и сдвиговых команд для выполнения преобразования кодов, операций двоично-десятичной арифметики, умножения и деления [1]. 8.1. Преобразование двоичного кода в шестнадцатеричный Ниже приведенная подпрограмма показывает использование команд ADD и SWAP для преобразования 16-битного двоичного числа в шестнадцатеричное, представленное в коде ASCII. 16-битное двоич¬ное число рассматривается как строка из четырех тетрад и обрабатывается потетрадно слева направо, начиная со старшей тетрады байта, имеющего младший адрес. Число 30Н прибавляется к каждой тетраде, если она содержит код с десятичным значением от 0 до 9, иначе прибавляется 37Н. По этому способу 00Н преобразуется в 30Н, 01Н - в 31Н,...,0АН - в 41Н,...,0FH - в 46H. Рис.1 показывает форматы и адреса операндов и результата. Двоичный код пусть находится в регистровой паре R0 в регистровом файле, а шестнадцатеричный код в виде четырех символов в коде ASCII следует разместить во внешней памяти данных по адресу, записанному в регистровой паре RR4. Регистр R6 используется как счетчик тетрад. ;Подпрограмма преобразования двоичного кода в шестнадцатеричный BINASC: LD R6,#04H ;Загрузить счетчик тетрад again: SWAP R0 ;Выделить следующую тетраду LD R2,R0 AND R2,#0FH ;Отделить тетраду ADD R2,#30H ;Преобразовать CP R2,#3AH JR ult,skip ADD R2,#07H skip: LDE @RR4,R2 ;Сохранить символ INCW RR4 ;Инкрементировать указатель CP R6,#03H ;Уже второй байт? JR ne,same_byte ;Если нет, продолжить LD R0,R1 same_byte: DJNZ R6,again ;Если не все тетрады, ;то повторить опять RET .END Параметры подпрограммы: 16 команд; 34 байта; 120.5мкс (в среднем). 8.2. Двоично-десятичное сложение Следующая подпрограмма иллюстрирует использование команд сложения с переносом ADC и десятичной коррекции DA для сложения двух беззнаковых BCD-чисел одинаковой длины. Каждая тетрада такого числа представляет собой двоичный код десятичной цифры (0 - 9). Две таких цифры упакованы в байт, где старшей цифре соответствуют биты D7 - D4. Байты BCD-чисел образуют в регистровой памяти массив, причем старшие цифры запоминаются в регистре с меньшим адресом. В приведенной ниже подпрограмме R0 и R1 используются как указатели массивов операнда-приемника (dst) и операнда-источника (src) соответственно. R2 - счетчик байтов BCD-числа. Результат - сумма BCD-чисел размещается по адресу, указываемому R0. Если имело место переполнение, то устанавливается флаг С. ;Подпрограмма сложения двоично-десятичных чисел BCD_SRC .EQU R1 BCD_DST .EQU R0 BCD_LEN .EQU R2 BCDADD: add BCD_SRC,BCD_LEN ;Начать с младшего байта чисел add BCD_DST,BCD_LEN rcf ;Очистить перенос add_again: dec BCD_SRC ;Выбрать очередной байт числа dec BCD_DST ld R3,@BCD_SRC ;Взять пару цифр источника ADC R3,@BCD_DST ;Сложить с парой цифр приемника DA R3 ;Выполнить коррекцию ld @BCD_DST,R3 ;Запомнить в массиве приемника djnz BCD_LEN,add_again ;Если не все байты ;обработаны, то повторить ret .END Параметры подпрограммы: 11 команд; 20 байтов; 20 + 12.5(n - 1)мкс время выполнения (n - число байтов). 8.3. Умножение Пусть необходимо выполнить умножение двух беззнаковых 8-битных чисел, которое дает 16-битное произведение. Эффективный алгоритм такого умножения заключается в повторяющемся сдвиге множителя вправо ( с использованием команды RRC ) с выдвижением младшего значащего бита во флаг переноса С. Если выдвинутая цифра множителя равна 1, то множимое прибавляется к старшему байту суммы час-тичных произведений. Поскольку биты множителя выдвигаются из регистра, то младшие цифры суммы частичных произведений могут замещать их, вдвигаясь в регистр. Поэтому их можно хранить в одном регистре, что сэкономит регистровое пространство, объем программного кода и время выполнения. Пусть множимое размещено в R1, множитель в R3, а произведение помещается в регистровой паре RR2. Регистр R0 - счетчик цикла. ; Подпрограмма умножения байтов MULTIPLIER .EQU R1 ; Множимое PRODUCT_LO .EQU R3 ; Произведение, младший байт PRODUCT_HI .EQU R2 ; Произведение, старший байт COUNT .EQU R0 ; Счетчик цикла MULT: ld COUNT,#09H ; Загрузить в счетчик 8+1 clr PRODUCT_HI ; Очистить старший байт ; произведения RCF ; Очистить перенос LOOP: RRC PRODUCT_HI ; Сдвинуть сумму RRC PRODUCT_LO ; частичных произведений jr NC, NEXT ADD PRODUCT_HI, MULTIPLIER NEXT: djnz COUNT, LOOP ret .END Параметры подпрограммы : 9 команд; 16 байтов; 92,5 мкс (в среднем). 8.4. Деление Следующая подпрограмма демонстрирует эффективный алгоритм деления 16-битного беззнакового числа на 8-битный делитель с получением 8-битного частного. Алгоритм основан на последовательном сдвиге делимого влево ( с помощью команды RLC ). Если выдвигаемый при этом бит равен 1 или старший байт делимого больше или равен делителю, то делитель вычитается из старшего байта делимого. Поскольку младшие разряды делимого сдвигаются влево, биты получаемого частного могут замещать их. Так, частное и младший байт делимого могут занимать один регистр, что сэкономит регистровое пространство, объем программного кода и время выполнения. Пусть делимое размещается в R2 (старший байт) и в R3 (младший байт), а делитель - в R1. Регистр R0 - счетчик цикла. Если при делении имеет место переполнение, то устанавливается флаг переноса С. ; Подпрограмма деления COUNT .EQU R0 ; Счетчик цикла DIVISOR .EQU R1 ; Делитель DIVIDEND_HI .EQU R2 ; Старший байт делимого и остаток DIVIDEND_LO .EQU R3 ; Младший байт делимого и частное DIVIDE : ld COUNT,#08H ; Установить счетчик цикла cp DIVISOR,DIVIDEND_HI ; Проверить переполнение jr UGT,LOOP ; Если нет, выполнять деление SCF ; Иначе, установить флаг С ret ; и закончить LOOP : RLC DIVIDEND_LO ; Сдвиг делимого RLC DIVIDEND_HI ; и частного jr C, subt cp DIVISOR, DIVIDEND_HI jr UGT, next ; Перенос С=0 subt : SUB DIVIDEND_HI, DDIVISOR SCF ; Установить C=1 next : djnz COUNT, LOOP RLC DIVIDEND_LO ret .END Параметры подпрограммы: 15 команд; 26 байтов; 124,5 мкс (в среднем). Рассмотренные примеры показывают возможность использования МК для решения самых различных прикладных задач. ЛИТЕРАТУРА 1. Z8 Microcontrollers. User's Manual. - Zilog Inc., 1995.
Все ссылки на книги и журналы, представлены на этом сайте, исключительно для ознакомления, авторские права на эти публикации принадлежат авторам книг и издательствам журналов!
Подробно тут!