DevioLab CRYPTO TRADING AUTOMATION
LIVE
AUTOMATED CRYPTO TRADING • BINANCE
Автоматизуйте свій криптопортфель
Торгові боти DevioLab аналізують крипторинок, автоматично відкривають і закривають позиції та керують вашим портфелем на Binance 24/7.
CRYPTO 80 Bots
BINANCE Spot Trading
TRADING 24 / 7
Спробувати DevioLab
deviolab.com

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

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

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

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

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

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

ЗАНЯТТЯ № 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
Антиботан аватар за замовчуванням

2015

Коментарі

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

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

Нічого не вибрано
0%

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

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

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

Admin

26.02.2023 12:38

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