Написання простих програм на мові асемблер для мікроконтролера AT90S2313

Інформація про навчальний заклад

ВУЗ:
Інші
Інститут:
Не вказано
Факультет:
Не вказано
Кафедра:
Не вказано

Інформація про роботу

Рік:
2026
Тип роботи:
Інші
Предмет:
Інші

Частина тексту файла (без зображень, графіків і формул):

ЗАНЯТТЯ № 2 Написання простих програм на мові асемблер для мікроконтролера AT90S2313 1. Написати підпрограму додавання вмісту двох 8-розрядних комірок SRAM, що знаходяться за адресами Addr_1 = 90Н, Addr_2 = 91Н. Якщо результат не рівний нулю, помістити його в комірку пам’яті SRAM з адресою Addr_1, в протилежному випадку вивести результат в порт B. ; Заголовочний файл .include <2313def.inc> ; Адреса першого числа .equ Addr_1 = 0x90 ; Адреса другого числа .equ Addr_2 = 0x91 ; Початок сегменту коду .cseg ; Початкова адреса .org 0 ; Вектор скиду RESET: ldi r16, 0xDF out SPL, r16 ; Ініціалізація стеку rcall PP_1 ; Виклик підпрограми додавання Wait: rjmp Wait ; Вічний цикл PP_1: ; Початок підпрограми додавання lds r0, Addr_1 ; Завантажити в регістр r0 перше число lds r1, Addr_2 ; Завантажити в регістр r1 друге число add r0, r1 ; Додати два числа, результат занести в r0 breq L1 ; Якщо результат = 0, перейти на мітку L1 sts Addr_1, r0 ; Інакше зберегти результат за адресою Addr_1 rjmp L2 ; Перейти на мітку L2 L1: out PORTB, r0 ; Вивести результат в порт В L2: ret ; Повернення з підпрограми 2. Написати підпрограму переводу безнакового цілого числа розташованого в комірці пам’яті SRAM з адресою Addr = 80Н, в двійково-десятковий код. Результат розташувати в регістрах загального призначення. ; Заголовичний файл .include <2313def.inc> ; Адреса числа, яке потрібно перевести в двійково-десятковий код .equ Addr = 0x80 ; Робочі регістри .def temp1 = r16 .def temp2 = r17 ; Регістри сотень, десятків та одиниць .def LCD_100 = r20 .def LCD_10 = r21 .def LCD_1 = r22 ; Сегмент коду .cseg ; Початкова адреса 0 .org 0 ; Вектор скиду RESET: ldi temp1, RAMEND ; RAMEND = 0xDF (див. файл 2313def.inc) out SPL, temp1 ; Ініціалізація стеку ldi temp1, 125 ; Нехай потрібно перевести число 125 sts Addr, temp1 ; Зберегти 125 за адресою Addr rcall Bin_to_Dec ; Виклик підпрограми переводу Wait: rjmp Wait ; Вічний цикл Bin_to_Dec: lds temp1, Addr ; Занести число для переводу в temp1 ldi LCD_100, -1 ; Присвоїти LCD_100 = -1 B2: inc LCD_100 ; LCD_100 = LCD_100 + 1 subi temp1, 100 ; temp1 = temp1 - 100 brsh B2 ; Якщо temp1 >= 0 перейти на В2 ldi LCD_10, 100 ; Відновити temp1 add temp1, LCD_10 ; temp1 = temp1 + 100 ldi LCD_10, -1 ; Присвоїти LCD_10 = -1 B3: inc LCD_10 ; LCD_10 = LCD_10 + 1 subi temp1, 10 ; temp1 = temp1 - 10 brsh B3 ; Якщо temp1 >= 0 перейти на В3 ldi temp2, 10 ; Відновити temp1 add temp1, temp2 ; temp1 = temp1 + 10 mov LCD_1, temp1 ; Занести в LCD_1 кількість одиниць ret ; Повернення з підпрограми 3. Написати підпрограму переводу двійково-десяткового числа розташованого в комірці пам’яті SRAM з адресою Addr = С0Н в двійковий код. Результат розташувати в регістрі загального призначення. ; Заголовочний файл .include <2313def.inc> ; Адреса числа, яке потрібно перевести в двійковий код .equ Addr = 0xC0 ; Робочі регістри .def temp1 = r16 .def temp2 = r17 ; Регістр результату .def result = r18 ; Сегмент коду .cseg ; Початкова адреса .org 0 ; Вектор скиду RESET: ldi temp1, RAMEND out SPL, temp1 ; Ініціалізація стеку ldi temp1, 0b01010111 sts Addr, temp1 ; Занести в Addr число 57 (2-10) rcall BCD_BIN ; Виклик підпрограми переводу 2-10->2 Wait: rjmp Wait ; Вічний цикл ; Підпрограма переводу з 2-10 коду в двійковий BCD_BIN: ldi result, 0 ; Обнулити регістр результату (result = 0) lds temp1, Addr ; Завантажити в temp1 вміст Addr (temp1 = 0b01010111) mov result, temp1 ; Переслати 0b01010111 в result andi result, 0b00001111 ; Виділити одиниці: result = 0b00000111 swap temp1 ; Поміняти місцями тетради: temp1 = 0b01110101 andi temp1, 0b00001111 ; Виділити десятки: result = 0b00000101 ldi temp2, 10 ; temp2 = 10 L1: subi temp1, 1 ; temp1 = temp - 1 brlo L2 ; Якщо temp1 < 0 перейти на L2 add result, temp2 ; Інакше result = result + 10 rjmp L1 ; Перейти на початок циклу L1 L2: ret ; Повернення з підпрограми 4. Написати підпрограму формування часової затримки тривалістю 3 с. Тактова частота мікроконтролера 8 МГц. Підпрограма часової затримки будується так: А. Розраховується кількість тактів  необхідна для формування заданого часового інтервалу  при тактовій частоті : . Б. Складаємо рівняння з врахуванням того, що команда виклику підпрограми  виконується за 3 такти, повернення з підпрограми  – 4 такти, завантаження регістрів лічби  – 1 такт (всього 3 команди), а тіло циклу виконується  раз і складається з 5 тактів:  – 1 такт,  – 1 такт (2 команди),  – 2 такти (за винятком одного разу коли здійснюється вихід з циклу – тоді 1 такт). Отже будемо мати  В. Для того щоб рівняння мало цілий розв’язок необхідно в п/п затримки додати одну холосту команду  (no operation) тривалістю 1 такт. Тоді наше рівняння запишеться:  Таким чином в циклі, який починається міткою Delay відбувається віднімання від числа , розташованого в регістрах Delay1-Delay3 одиниці, поки воно не стане менше 0, після чого здійснюється вихід з циклу. Ознакою того, що число стало менше 0, є встановлення прапорця позики С в регістрі стану SREG (перевіряється командою ). ; Заголовочний файл .include <2313def.inc> ; Константа часової затримки: 4 + 3 + 3 + 5*(N + 1) - 1 + 1 = FCLK*T .equ T_3sec = (24000000 - 15)/5 ; 3 секунди ; Робочий регістр .def temp = r16 ; Регістри затримки .def Delay1 = r17 .def Delay2 = r18 .def Delay3 = r19 ; Сегмент коду .cseg ; Початкова адреса .org 0 ; Вектор скиду RESET: ldi temp, RAMEND out SPL, temp ; Ініціалізація стеку ldi Delay1, low(T_3sec) ; Занести в Delay1 1-й байт T_3sec ldi Delay2, high(T_3sec) ; Занести в Delay2 2-й байт T_3sec ldi Delay3, byte3(T_3sec) ; Занести в Delay3 3-й байт T_3sec rcall Delay ; Виклик підпрограми затримки Wait: rjmp Wait ; Вічний цикл Delay: ;Підпрограма часової затримки subi Delay1, 1 ; Відняти від T_3sec sbci Delay2, 0 sbci Delay3, 0 brcc Delay ; Якщо результат >= 0 перейти на Delay nop ; Холоста команда ret ; Повернення з підпрограми 5. Написати підпрограму додавання двох масивів з адресами Array1 та Array2, розміром 10 байт. Результат додавання записати на місце першого масиву. ; Заголовочний файл .include <2313def.inc> ; Константа - розмір масиву .equ Array_Size = 10 ; Лічильник .def Count = r16 ; Робочі регістри .def temp1 = r17 .def temp2 = r18 ; Сегмент коду .cseg ; Початкова адреса .org 0 ; Вектор скиду RESET: ldi temp1, RAMEND out SPL, temp1 ; Ініціалізація стеку ldi XL, low(Array1) ; Занести в індексний рег. Х адресу ldi XH, high(Array1) ; першого масиву ldi YL, low(Array2) ; Занести в індексний рег. Y адресу ldi YH, high(Array2) ; другого масиву ldi Count, Array_Size ; Занести в лічильник розмір масиву rcall Array_Sum ; Виклик підпрограми додавання масивів Wait: rjmp Wait ; Вічний цикл Array_Sum: ld temp1, X ; Занести в temp1 елемент масиву Array1 ld temp2, Y+ ; Занести в temp2 елемент масиву Array2 add temp1, temp2 ; Додати два елементи st X+, temp1 ; Зберегти суму в масиві Array1 dec Count ; Зменшити лічильник на 1 brne Array_Sum ; Поки Count не 0, перейти на Array_Sum .dseg Array1: .byte 10 ; Резервування пам'яті для масиву Array1 Array2: .byte 10 ; Резервування пам'яті для масиву Array1 6. Написати підпрограму знаходження максимального числа у масиві 8-розрядних беззнакових чисел в SRAM з адресою Array, розміром 10 байт. Максимальне число запам’ятати в комірці SRAM з адресою uMax, його адресу в комірках Max_Addr і Max_Addr + 1. ; Заголовочний файл .include <2313def.inc> ; Константа - розмір масиву .equ Array_Size = 10 ; Лічильник .def Count = r16 ; Робочі регістри .def temp1 = r17 .def temp2 = r18 ; Сегмент коду .cseg ; Початкова адреса .org 0 ; Вектор скиду RESET: ldi temp1, RAMEND out SPL, temp1 ; Ініціалізація стеку ldi XL, low(Array) ; Занести в індексний рег. Х ldi XH, high(Array) ; адресу масиву Array ; Ініціалізація масиву для тестування підпрограми ldi temp1, 3 st X+, temp1 ldi temp1, 5 st X+, temp1 ldi temp1, 7 st X+, temp1 ldi temp1, 8 st X+, temp1 ldi temp1, 129 st X+, temp1 ldi temp1, 200 st X+, temp1 ldi temp1, 220 st X+, temp1 ldi temp1, 110 st X+, temp1 ldi temp1, 77 st X+, temp1 ldi temp1, 34 st X+, temp1 ldi XL, low(Array) ; Занести в індексний рег. Х ldi XH, high(Array) ; адресу масиву Array ldi Count, Array_Size - 1 ; Занести в Count число 9 rcall Array_uMax ; Виклик підпрограми пошуку максимуму Wait: rjmp Wait ; Вічний цикл Array_uMax: ld temp1, X+ ; Занести перший елемент масиву в temp1 Loop: ld temp2, X ; Занести наступний елемент масиву в temp2 cp temp2, temp1 ; Порівняти: temp2 - temp1 brlo L1 ; Якщо temp2 < temp1 перейти на L1 mov temp1, temp2 ; Інакше занести в temp1 значення temp2 sts Max_Addr, XL ; Зберегти адресу temp2 sts Max_Addr+1, XH ; в комірках Max_Addr, Max_Addr+1 L1: adiw XL, 1 ; Вказати на наступний елемент dec Count ; Зменшити Count на 1 brne Loop ; Якщо Count не нуль, перейти на Loop sts uMax, temp1 ; Зберегти масимальне значення в uMax ret ; Повернення з підпрограми ; Сегмент даних .dseg Array: .byte 10 ; Виділення пам'яті для масиву uMax: .byte 1 ; Комірка для зберігання макс. значення Max_Addr: .byte 2 ; Адреса максимального значення 7. Написати підпрограму знаходження максимального числа у масиві 8-розрядних знакових чисел в SRAM з адресою Array, розміром 10 байт. Максимальне число запам’ятати в комірці SRAM з адресою sMax, його адресу в комірках Max_Addr і Max_Addr + 1. ; Заголовочний файл .include <2313def.inc> ; Константа - розмір масиву .equ Array_Size = 10 ; Лічильник .def Count = r16 ; Робочі регістри .def temp1 = r17 .def temp2 = r18 ; Сегмент коду .cseg ; Початкова адреса .org 0 ; Вектор скиду RESET: ldi temp1, RAMEND out SPL, temp1 ; Ініціалізація стеку ldi XL, low(Array) ; Занести в індексний рег. Х ldi XH, high(Array) ; адресу масиву Array ; Ініціалізація масиву для тестування підпрограми ldi temp1, 3 st X+, temp1 ldi temp1, 5 st X+, temp1 ldi temp1, 7 st X+, temp1 ldi temp1, 8 st X+, temp1 ldi temp1, 129 st X+, temp1 ldi temp1, 200 st X+, temp1 ldi temp1, 220 st X+, temp1 ldi temp1, 110 st X+, temp1 ldi temp1, 77 st X+, temp1 ldi temp1, 34 st X+, temp1 ldi XL, low(Array) ; Занести в індексний рег. Х ldi XH, high(Array) ; адресу масиву Array ldi Count, Array_Size - 1 ; Занести в Count число 9 rcall Array_sMax ; Виклик підпрограми пошуку максимуму Wait: rjmp Wait ; Вічний цикл Array_sMax: ld temp1, X+ ; Занести перший елемент масиву в temp1 Loop: ld temp2, X ; Занести наступний елемент масиву в temp2 cp temp2, temp1 ; Порівняти: temp2 - temp1 brlt L1 ; Якщо temp2 < temp1 перейти на L1 mov temp1, temp2 ; Інакше занести в temp1 значення temp2 sts Max_Addr, XL ; Зберегти адресу temp2 sts Max_Addr+1, XH ; в комірках Max_Addr, Max_Addr+1 L1: adiw XL, 1 ; Вказати на наступний елемент dec Count ; Зменшити Count на 1 brne Loop ; Якщо Count не нуль, перейти на Loop sts sMax, temp1 ; Зберегти масимальне значення в sMax ret ; Повернення з підпрограми ; Сегмент даних .dseg Array: .byte 10 ; Виділення пам'яті для масиву sMax: .byte 1 ; Комірка для зберігання макс. значення Max_Addr: .byte 2 ; Адреса максимального значення 8. Написати п/п кодування циклічним кодом з твірним поліномом  3-розрядної інформаційної послідовності. Продемонструвати роботу п/п для інформаційної послідовності 110. Побудуємо твірну матрицю  шляхом ділення одиниці з 5 нулями на твірний поліном:  Твірна матриця:  Контрольні розряди згідно твірної матриці:  Закодована комбінація має бути:  ; Заголовочний файл .include <2313def.inc> ; Закодована комбінація .def CRC = r16 ; Робочі регістри .def temp1 = r17 ; Сегмент коду .cseg ; Початкова адреса .org 0 ; Вектор скиду RESET: ldi temp1, RAMEND out SPL, temp1 ; Ініціалізація стеку ldi CRC, 0b00000110 ; Занести в рег. CRC дані для кодування rcall CRC_Calc ; Виклик підпрограми кодування циклічним кодом Wait: rjmp Wait ; Вічний цикл CRC_Calc: ldi ZL, low(CRC_Table*2) ; Занести в інд. рег. Z адресу ldi ZH, high(CRC_Table*2) ; таблиці CRC_Table в Flash-пам'яті програм lsl CRC ; Звільнити молодші 3 біти lsl CRC ; для контрольних розрядів lsl CRC ; CRC=0 0 0 I3 I2 I1 K3 K2 K1 mov temp1, CRC ; Занести в temp1 вміст CRC andi temp1, 0b00001000 ; Виділити біт I1 breq L1 ; Якщо I1 = 0 перейти на L1 lpm ; Інакше прочитати залишок з CRC_Table в r0 eor CRC, r0 ; Додати залишок до CRC L1: adiw Z, 1 ; Вказати на наступний залишок mov temp1, CRC ; Занести в temp1 вміст CRC andi temp1, 0b00010000 ; Виділити біт I2 breq L2 ; Якщо I2 = 0 перейти на L2 lpm ; Інакше прочитати залишок з CRC_Table в r0 eor CRC, r0 ; Додати залишок до CRC L2: adiw Z, 1 ; Вказати на наступний залишок mov temp1, CRC ; Занести в temp1 вміст CRC andi temp1, 0b00100000 ; Виділити біт I3 breq L3 ; Якщо I3 = 0 перейти на L3 lpm ; Інакше прочитати залишок з CRC_Table в r0 eor CRC, r0 ; Додати залишок до CRC L3: ret ; Поверення з підпрограми ; Твірна таблиця для поліному х^3 + x + 1 CRC_Table: .db 0b00000011, 0b00000110, 0b00000111
Антиботан аватар за замовчуванням

01.01.1970 03:01-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!