Разработка алгоритмов работы и программного обеспечения микропроцессорных вычислительных устройств

Тип работы:
Контрольная
Предмет:
Программирование


Узнать стоимость

Детальная информация о работе

Выдержка из работы

Задание

программный обеспечение макрос регистр

Написать программное обеспечение на языке ассемблер для 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.

ПоказатьСвернуть
Заполнить форму текущей работой