Разработка алгоритмов работы и программного обеспечения микропроцессорных вычислительных устройств
Копии экранов с окнами среды AVR Studio, отображающими размещение исходных данных и полученных результатов в ОЗУ, привести в пояснительной записке. Вычисление функции оформить в виде макроса. Входными параметрами макроса должны быть числа,, и адрес ОЗУ для сохранения значения функции. Написать программное обеспечение на языке ассемблер для AVR-МК ATmega16, которое бы позволяло осуществлять… Читать ещё >
Разработка алгоритмов работы и программного обеспечения микропроцессорных вычислительных устройств (реферат, курсовая, диплом, контрольная)
Задание
программный обеспечение макрос регистр
Написать программное обеспечение на языке ассемблер для AVR-МК ATmega16, которое бы позволяло осуществлять вычисление функции:
где — число из множества целых чисел в диапазоне [0, 250];
— число из множества целых чисел в диапазоне [0, 100];
— число из множества целых чисел в диапазоне [0, 40 000];
Значение функции после вычисления должно сохраняться в любых ячейках пользовательского ОЗУ.
Вычисление функции оформить в виде макроса. Входными параметрами макроса должны быть числа, , и адрес ОЗУ для сохранения значения функции.
В программе поочередно вызвать макрос для вычисления значений функции для входных аргументов:
1) ;
2) ;
3) .
Адреса ячеек ОЗУ для задать самостоятельно и указать в пояснительной записке.
Копии экранов с окнами среды AVR Studio, отображающими размещение исходных данных и полученных результатов в ОЗУ, привести в пояснительной записке.
Вычисление «вручную»
1.;; ;
Перевод целой части числа заключается в последовательном делении на основание системы на которую осуществляется перевод, до тех пор, пока результат частного деления не станет меньше основания системы с записью в обратном порядке частных остатков от делений.
100/2 (0) = 50/2 (0) = 25/2 (1) = 12/2 (0) = 6/2 (0) = 3/2 (1) = ½ (1);
.
250/2 (0) = 125/2 (1) = 62/2 (0) = 31/ 2 (1) = 15/2 (1) = 7/2 (1) = 3/2 (1) = ½ (1);
Перемножим
Проверка условия ;
Вычисление = .
2.;; ;
10/2 (0) = 5/2 (1) = 2/2 (0) = Ѕ (1);
Перемножим
Проверка условия ;
Вычисление = .
Воспользовались правилом переноса со старших разрядов, правилом вычитания 10 — 1 = 1.
3.;; ;
70/2 (0) = 35/2 (1) = 17/2 (1) = 8/2 (0) = 4/2 (0) = 2/2 (0) = Ѕ (1);
50/2 (0) = 25/2 (1) = 12/2 (0) = 6/2 (0) = 3/2 (1) = Ѕ (1);
Перемножим
Проверка условия ;
Вычисление = .
Исходный код программы
;******************************************************************
;* Д/З *
;* Версия: 1.0 *
;* Дата: 17.05.2014 *
;* Автор: Момот О. А. *
;* МК: ATmega16 *
;* Fтакт: 10МГц *
;*****************************************************************
; // Псевдокоманды управления
.DEVICE ATmega16; // Выбор устройства
.NOLIST; // Выключение листинга
.INCLUDE «m16def.inc»; // Присоединение файла описаний
.LIST; // Включение листинга
.DEF temp = R21; // Определение главного рабочего регистра
.DEF valueK = R23; // Определение регистра для значения K
.DEF valueX = R24; // Определение регистра для значения X
.DEF valueBLow = R25; // Определение регистра для значения B (младшего б.)
.DEF valueBHigh = R26; // Определение регистра для значения B (старшего б.)
.DEF valueYLow = R27; // Определение регистра для значения Y (младшего б.)
.DEF valueYHigh = R28; // Определение регистра для значения Y (старшего б.)
.DEF valueYHighHigh = R29; // Определение регистра для значения Y (старшего б. R28)
; // Начало макроса operationY
.MACRO operationY;
mul valueK, valueX; // k*x
cp R1, valueBHigh; // Сравнение R1, valueBHigh
breq variantTwo; // Если k*x = b
cp R1, valueBHigh; // Сравнение R1, valueBHigh
brmi variantOne; // Если k*x < b
brpl variantTwoO; // Если k*x > b
; // Вариант k*x <= b
variantOne:
add valueBLow, R0; // Сложение valueBLow, R0
adc valueBHigh, R1; // Сложение valueBHigh, R1
mov valueYLow, valueBLow; // Копирование valueYLow = valueBLow
mov valueYHigh, valueBHigh; // Копирование valueYHigh = valueBHigh
rjmp outMacro; // Переход на метку outMacro
; // Вариант k*x > b
variantTwo:
cp R0, valueBLow; // Сравнение R0, valueBLow
brpl variantTwoO; // Если + переход
brmi variantOne; // Если — переход
variantTwoO: // Метка variantTwoO
sub R0, valueBlow; // Вычитание R0 — valueBLow
sbc R1, valueBHigh; // Вычитание R1 — valueBHigh
mov valueYLow, R0; // Копирование valueYLow = R0
mov valueYHigh, R1; // Копирование valueYHigh = R1
rjmp outMacro; // Переход на метку outMacro
; // Метка outMacro
outMacro:
; // Конец макроса operationY
.ENDMACRO;
; // Определим значения операторов макроса @0 — адрес ячейки ОЗУ для valueYLow,
; @1 — адрес ячейки ОЗУ для valueYHigh,
; @2 — адрес ячейки ОЗУ для valueYHighHigh.
; // Начало макроса outValues
.MACRO outValues;
sts @0, valueYLow; // Загрузка @0 = valueYLow
sts @1, valueYHigh; // Загрузка @1 = valueYHigh
clr valueYLow; // Очистка valueYLow
clr valueYHigh; // Очистка valueYHigh
; // Конец макроса
.ENDMACRO;
; // Определим значения операторов макроса @0 — значение для valueK,
; @1 — значение для valueX,
; @2 — значение для valueBLow,
; @3 — значение для valueBHigh.
; // Начало макроса ldiRegister
.MACRO ldiRegister
ldi valueK, @0; // Загрузка valueK = @0
ldi valueX, @1; // Загрузка valueX = @1
ldi valueBLow, Low (@2); // Загрузка valueBLow = @2
ldi valueBHigh, High (@2); // Загрузка valueBHigh = @3
; // Конец макроса
.ENDMACRO;
; // Начало программного сегмента
.CSEG; // Выбор сегмента программного кода
.ORG 0; // Установка текущего адреса в ноль
; // Инициализация стека
ldi temp, Low (RAMEND); // Установка младшего б. указателя стека
out SPL, temp; // Запись в SPL = temp
ldi temp, High (RAMEND); // Установка старшего б. указателя стека
out SPH, temp; // Запись в SPH = temp
; // Вызов макроса ldiRegister
ldiRegister 100, 10, 2500; // k = 1000, x = 10, b = 2500
; // Вызов макроса operationY
operationY;
; // Вызов макроса out Values
outValues $ 60, $ 61;
; // Холостая команда
nop;
; // Вызов макроса ldiRegister
ldiRegister 1, 100, 10; // k = 1, x = 100, b = 10
; // Вызов макроса operationY
operationY;
; // Вызов макроса out Values
outValues $ 63, $ 64;
; // Холостая команда
nop;
; // Вызов макроса ldiRegister
ldiRegister 70, 2, 50; // k = 70, x = 2, b = 50
; // Вызов макроса operationY
operationY;
; // Вызов макроса out Values
outValues $ 66, $ 67;
; // Холостая команда
nop;
; // Конец компиляции
.EXIT;
Результат
Вывод
В результате выполнения программы были получены правильные значения, которые были рассчитаны предварительно «вручную»:
1. 0xFA = 250 = 0b11111010;
2. 3. 0x5A = 90 = 0b1011010.
Входные данные вводились с помощью определенного макроса ldiRegister с командой загрузки значений в регистры ldi. Результаты вычислений сохранялись помощью макроса outValues в ячейки ОЗУ с адресами $ 60, $ 63, $ 66 (младший б. результата), $ 61, $ 64, $ 67 (старший б. результата) для соответственно.
Программа писалась в AVR Studio 6.