--PAGE_BREAK--Пример 1.8. Умножить однобайтные целые числа без знака. В регистре R1 размещен множитель, в регистре R2 – множимое. Двухбайтный результат умножения будет размещен в аккумуляторе (старший байт) и в R1 (младший байт) вместо множителя. В регистр R3, выполняющий функции счетчика программных циклов, загружается число 8 (число бит множителя). Умножение выполняется младшими битами вперед со сдвигом вправо частичного произведения. Последовательность действий при этом методе умножения следующая:
– Содержимое аккумулятора и регистра-расширителя R1 сдвигается вправо на один бит так, что младший бит множителя, выдвигаемый из регистра R1, помещается в триггер флага C.
– Если C= 1, то множимое добавляется к содержимому аккумулятора, в противном случае никаких операций не производится.
– Декрементируется счетчик циклов R3, и если его содержимое не равно нулю, то все действия повторяются.
– Перед выходом из подпрограммы формируется окончательный результат сдвигом частичного результата на один бит вправо:
MPL: MOV R3,#8 ; загрузка счетчика циклов
CLR A ; очистка аккумулятора
CLR C ; очистка признака переноса
SHIFT: RRC A ; сдвиг аккумулятора вправо
XCH A,R1 ; обмен аккумулятора и R1
RRC A ; сдвиг множителя с занесением
; выдвигаемого бита в C
XCH A,R1 ; обмен аккумулятора и R1
JNC RESULT ; если C= 1, то суммирование
ADD A,R2 ; прибавление множимого
RESULT: DJNZR3,SHIFT ; декремент счетчика и проверка
; окончания операции (R3 = 0)
RRC A ; сдвиг аккумулятора
XCH A,R1 ; обмен
RRC A ; сдвиг содержимого R1
XCH A,R1 ; обмен
Пример 1.9. Умножить аккумулятор на число 2 в степени X, где X– число (не более 8), хранящееся в R2. Умножение на 2 заменяется арифметическим сдвигом влево аккумулятора и расширителя R1:
MOV R1,#0 ; сброс R1
CLR С ; сброс флага переноса
LOOP: RLC A ; арифметический сдвиг влево объединенного
XCH A,R1 ; 16-битного результата в
RLC A ; регистровой паре (R1) (A)
XCH A,R1 ;
DJNZ R2,LOOP ; цикл
3.4.2. Изучение команд манипуляции флажками и передачи управления
1) Изучить организацию стека микроконтроллера ВЕ48;
2) Рассмотреть систему команд манипуляции флажками, условных и безусловных переходов, вызова подпрограмм;
3) Ознакомиться с приведенными ниже примерами программ на языке ассемблера;
4) Произвести ввод, отладку и трансляцию в объектный код этих программ;
5) Выполнить программы по шагам с просмотром результатов выполнения в регистрах и оперативной памяти.
Пример 2.1. Определить четность числа единиц в аккумуляторе. После выполнения программы аккумулятор сохранит свое значение, флаг 0 будет установлен, если число единиц в аккумуляторе было нечетно. Флаг F0 входит в состав PSWи в данном примере специфицирован пользователем для выполнения функций флага паритета.
CLR F0 ; сброс F
MOV R7,#8 ; число повторов
LOOP: RRC A ; пересылка бита A.0 в перенос
JNC NEXT ; пропустить, если бит равен 0
CPL F0 ; подсчет паритета
NEXT: DJNZ R7,LOOP ; повторить 8 раз
Пример 2.2. Передать управление по метке LL, если переключатель банка регистров (бит PSW.4) установлен:
JBSET: MOV A,PSW ; передача PSWв аккумулятор
JB4 LL ; переход, если A.4 = 1
LL: … ;
Пример 2.3. Осуществить переход из нулевого банка памяти программ к программе с именем ROUT, расположенной в первом банке памяти программ:
SEL MB1 ; установка флага MB
JMP ROUT ; переход к программе ROUT
Пример 2.4. Множественное ветвление программы. Допустим, что результатом работы некоторой программы является число X(в пределах от 0 до 15). Необходимо организовать передачу управления 16 различным программам с именами ROUT0–ROUTFв зависимости от вычисленного значения X:
ORG 0 ; задание начального адреса программы
ANL A,0F ; сброс старшей тетрады A
; во избежание ошибки перехода
JMPP @A ; обращение к таблице векторов переходов
; таблица векторов переходов
DB ROUT0; начальный адрес программы ROUT
DB ROUT1; начальный адрес программы ROUT1
…
…
…
DB ROUTF; начальный адрес программы ROUTF
Преобразование чисел из одной системы счисления в другую. Перевод шестнадцатеричных чисел в двоичную систему счисления достигается представлением цифр шестнадцатеричного числа четырехразрядными двоичными числами. Например,
A7B= 1010 0111 1011
A 7 B
Перевод в десятичную систему счисления. Так как перевести числа из двоичной системы в шестнадцатеричную и обратно нетрудно, то для простоты выкладок рассмотрим перевод чисел из шестнадцатеричной системы и обратно.
В качестве примера перевода числа из шестнадцатеричной системы в десятичную систему выберем число 9A5F:
9A5F16= (9∙163 + 10∙162 + 5∙161 + 15∙160)=(((9∙16+10)∙16+5)∙16+15) = 3951910
9 A 5 F
Здесь путем группировки членов вычисление полиномов представлено в форме так называемой схемы Горнера, обеспечивающей минимальное число выполняемых операций умножения.
Покажем действия по переводу чисел из десятичной системы счисления в шестнадцатеричную на примере преобразования десятичного числа 3951910 в шестнадцатеричную систему счисления
39519 |16
39504 2469 |16
15 2464 154 |16
F 5 144 9
10
A
Отсюда 3951910 = 9A5F16. Таким образом, последовательно деля на 16 целую часть десятичного числа и образующиеся частные, получаем в последнем частном и остатках цифры всех разрядов шестнадцатеричного представления числа.
Пример 2.5. Преобразование кодов из одной системы счисления в другую. Преобразование кода из одной позиционной системы счисления в другую осуществляется делением исходного числа на основание новой системы счисления. При этом деление должно выполняться по правилам исходной системы счисления. Например, для преобразования двоичного числа в двоично-десятичное исходное двоичное число должно быть поделено на 10 (10102). Деление должно осуществляться по правилам двоичной арифметики.
Пусть требуется выполнить преобразование 8-битного двоичного числа в двоично-десятичное. Исходный двоичный код хранится в аккумуляторе. Результат преобразования состоит из 12 бит: младшие 4 бита – единицы, представляют собой остаток от деления исходного числа на 10; следующие 4 бита – десятки, представляют собой остаток от деления на 10 полученного частного; старшие 4 бита – сотни, являются частным от второго деления:
BBD: CALL DIV10 ; деление исходного кода на 10
MOV R7,A ; сохранение остатка в R7
MOV A,R1 ; загрузка в аккумулятор частного
CALL DIV10 ; деление частного на 10
SWAP A ; передача остатка в старшую тетраду A
ORL A,R7 ; передача R7 в младшую тетраду A
JMP EXIT ; выход из процедуры
; подпрограмма деления на 10
; исходный двоичный код в аккумуляторе
; результат: в R1 – частное, в аккумуляторе – остаток
DIV10: MOV R1,#0 ; сброс R1
SUB10: ADD A,#(NOT(10)+1) ; вычитание 10 из делимого
INC R1 ; инкремент частного
JC SUB10 ; цикл, если остаток >= 0
DEC R1 ; восстановление частного
ADD A,#10 ; восстановление остатка
RET ; возврат
EXIT: … ;
В результате выполнения процедуры в младшей тетраде R1 хранятся сотни, в аккумуляторе – десятки и единицы двоично-десятичного эквивалента исходного двоичного числа.
3.4.3. Изучение аппаратных и программных средств ввода/вывода информации микроконтроллера ВЕ48
1) Изучить организацию каналов ввода/вывода информации микроконтроллера ВЕ48, интерфейс расширения ввода/вывода;
2) Рассмотреть команды, которые обслуживают пространство ввода/вывода;
3) Ознакомиться с приведенными ниже примерами программ на языке ассемблера;
4) Произвести ввод, отладку и трансляцию в объектный код этих программ;
5) Выполнить программы по шагам с просмотром результатов выполнения в регистрах и оперативной памяти.
Пример 3.1. Ввести байт из порта 1 и передать его в порт 2:
TRAN: MOV A,#0FF ; настройка порта 1 на ввод
OUTL P1,A ;
IN A,P1 ; ввод байта из порта 1
OUTL P2,A ; вывод байта в порт 2
Пример 3.2. Ввести данные из порта P7:
INPUT:MOVD A,P7 ; пересылка четырех битов из порта 7
; в младшую тетраду аккумулятора
Пример 3.3. Маскирование при вводе. Ввести в регистр R7 информацию из линий 0, 1, 3, 4 и 7 порта 1:
IN A,P1 ; ввод байта из порта 1
ANL A,#10011011B ; маскирование
MOV R7,A ; передача
Пример 3.4. Ввести в аккумулятор данные из порта 2 и выделить требуемые биты по маске, находящейся в R0:
IN A,P2 ; ввод байта из порта 2
ANL A,R0 ; маскирование
Пример 3.5. Выдать содержимое аккумулятора в последовательном коде через нулевую линию порта 1, оставляя без изменения остальные биты порта. Передачу вести, начиная с младшего бита:
MOV R1,#8 ; счетчик бит
LOOP: JB0 ONE ; переход, если бит A.0 = 1
ANL P1,#(NOT 1); сбросP1.0
JMP NEXT ;
ONE: ORL P1,#1 ; установкаP1.0
JMP NEXT ; избыточная команда для выравнивания
; времени передачи 0 и 1
NEXT: RR A ; сдвиг аккумулятора вправо (подготовка к
DJNZ R1,LOOP ; передаче очередного бита)
Пример 3.6. Настроить биты 0–3 порта 1 на ввод:
ORL P1,#0F ; установка битов P1.0… P1.3
Пример 3.7. Очистить биты 4–7 порта 2:
ANL P2,#0F ; сброс битов P2.4… P2.7
Пример 3.8. Организовать ожидание появления нулевого уровня на входе T0:
WAIT: JT0 WAIT ; переход на WAIT, если на входе T0 единица
Пример 3.9. Организовать ожидание появление единичного уровня на входе в предположении, что внешние прерывания запрещены:
DIS I ; запрет прерываний по INT
WAIT: JNI WAIT ; переход на WAIT, если на входе INTнуль
3.4.4. Изучение средств реального времени микроконтроллера ВЕ48
1) Изучить организацию таймера/счетчика и системы прерываний микроконтроллера ВЕ48;
2) Рассмотреть команды управления средствами реального времени;
3) Ознакомиться с приведенными ниже примерами программ на языке ассемблера;
4) Произвести ввод, отладку и трансляцию в объектный код этих программ;
5) Выполнить программы по шагам с просмотром результатов выполнения в регистрах и оперативной памяти.
продолжение
--PAGE_BREAK--