- •2. Програмне забезпечення
- •2.1. Мови програмування
- •2. 2 Компоненти мови Асемблер
- •3. Створення програми мовою Асемблер
- •3.1. Постановка задачі
- •3.2. Директиви
- •3.4. Алгоритм
- •3.5. Програма обчислення в одній точці
- •3.6. Застосування зсувів і масок
- •3.7. Запис масиву даних до озп і організація циклу
- •3.8. Завантаження масиву даних з озп до рзп
- •3.9. Зупин програми
- •4. Команди нашої програми
- •1) Арифметичні і логічні команди
- •2) Команди переходів (branch instructions)
- •3) Команди передачі даних (data transfer instructions)
- •4) Команди з бітами (bit and bit-test instructions)
- •5) Команди керування мк (mcu control instructions)
- •Лабораторна робота №1 Основи програмного пакету розробника avr Studio
- •3 Підготовка до налагодження проекту.
- •5 Виправлення помилок алгоритму.
- •5 Оформити звіт.
- •6 Завдання на самостійну роботу.
- •Лабораторна робота №2
- •3 Компіляція проекту.
- •4 Налагодження проекту.
- •Лабораторна робота №3
- •Лабораторна робота №4
- •Лабораторна робота №4
- •1 Підготовка проекту в avr Studio 4 для запису програми до пам'яті мікроконтролера.
- •2 Підготовка апаратних засобів стартового набору stk500.
- •3 Підготовка програмного інтерфейсу stk500.
- •4 Програмування мк та дослідження спроектованого виробу на платі стартового набору stk500.
- •5 Завдання на самостійну роботу
- •1 Налаштування основних модулів мікроконтролера.
- •2 Дослідження основних режимів функціонування мікроконтролера.
- •3 Програмування мк та дослідження цпп на платі стартового набору stk500.
- •4 Завдання на самостійну роботу.
3. Створення програми мовою Асемблер
3.1. Постановка задачі
Перед складанням програми потрібно передовсім чітко поставити задачу, у разі потреби скласти алгоритм її розв’язання і/або схему з'єднань МК із зовнішніми пристроями, переконатися в коректності подання даних, мати уяву про результати, що потрібно отримати (наприклад, контрольні точки розв'язку задачі, швидкодія тощо), вибрати тип МК та технічні вимоги (робоча частота, напруга живлення та ін.).
Р
озглянемо
для прикладу задачу обробки даних з
метою побудови графіка типової функції
y
похибки залежно від аргументу x,
що означає вимірювану величину (формула
на рис. 1,а), із заданими коефіцієнтами
(тут C
– адитивна похибка, B,
A
– коефіцієнти мультиплікативної та
нелінійної похибок відповідно), причому
результати обчислень потрібно зберегти
в ОЗП, а для їх використання передбачити
завантаження модулів чисел до регістрів
R0
… R7
та їх знаки – до регістра R8
(рис. 1,б). Таку початкову задачу обрано
для вивчення власне мікропроцесора у
складі ядра МК та створення проекту в
AVR
Studio,
бо для її розв’язання не потребується
використовувати порти та інші пристрої,
а також складати схему з'єднань МК із
зовнішніми пристроями.
Щодо коректності подання даних визначаємо довжину слова результату, тобто діапазон припустимих чисел. З огляду на те, що у розглядуваних МК AVR будь-яка комірка даних (регістр загального призначення або комірка ОЗП) є 8-розрядна, а для чисел зі знаком 1 біт приділяється знаку числа, то для його значущої частини залишається 7 розрядів, тобто комірка даних може вміщувати додатні числа 0…255 або числа зі знаком в діапазоні ±127 (з метою спрощення в нашій задачі обробку чисел більшого діапазону слів довжиною 2 байт і більше не розглядатимемо).
За формулою функції обчислюємо контрольні точки, наприклад при значенні аргументу i = x = 4 маємо y = - 26 = - 0b 0001 1010 = - 0x 1A. Проте операції чисел зі знаками МК виконує в доповняльному коді, тому в прикладі результат буде yдоп = 0b 1110 0110 = $E6, де одиниця в старшому розряді, як завжди, відповідає знаку мінус (у колонці N_$y таблиці на рис. 1,а подається також прапорець від'ємного значення N регістра стану SREG). Для наочності на рис. 1,б подано табличку змісту комірок ОЗП з модулями чисел, а їх знаки – у розрядах регістра R8, на підставі чого побудовано графік функції (рис. 1,в).
Розглянемо блоки програми, потрібні для розв’язання нашої задачі.
3.2. Директиви
Для зручності написання та розуміння програми надаємо робочим регістрам символічні імена за допомогою директиви DEF. У нашому прикладі згідно з формулою (див. рис. 1,а) в регістрах потрібно зберігати поточне значення аргументу xi (не можна застосовувати службовий символ "х" на позначення шістнадцяткової системи) та коефіцієнти А, В, С. Крім того, відведемо один регістр для зберігання знаків (sign) результатів, а також регістри для тимчасових (temporal) даних та маски знаків результату (її сенс буде зрозуміло нижче). При цьому тільки регістр знаків можна вибрати з молодшої половини РФ, бо всі інші беруть участь як операнди команд, застосовних лише до старшої половини РФ (ldi, ori та ін.).
;***** Регістрові змінні
.def sgn = r8 ;Регістр R8 - знаки (sign) результатів
.def tmp = r16 ;Регістр R16 - тимчасові (temporal) дані
.def xi = r17 ;Регістр R17 - поточне значення аргументу
.def A = r18 ;Регістр R18 - константа A
.def B = r19 ;Регістр R19 - константа В
.def C = r20 ;Регістр R20 - константа С
.def msk = r21 ;Регістр R21 - маска знаків результату
З метою зручності коригування і написання програми вводимо також ідентифікатори констант за допомогою директиви EQU.
;***** Ідентифікатори цифрових значень констант
.equ i = 7 ;Початкове значення аргументу
.equ a0 = 4 ;Константа A
.equ b0 = 7 ;Константа B
.equ c0 = 118 ;Константа C
3.3. Ініціалізація
Перед
основною частиною програми вставляють
блок
ініціалізації,
що містить операції початкового
налаштування. Передовсім у нас потрібно
завантажити до робочих регістрів
константи: старше значення аргументу
функції і
(див. рис. 1) та коефіцієнти А,
В, С, а
також встановити початкову маску знаків
з
одиницею (знак мінус) у старшому розряді.
У цьому блоці також завжди налаштовуються порти та інші модулі МК, з яких у нашій початковій програмі використовується тільки ОЗП. Аби записати результати обчислень до ОЗП, скористаємося початковою адресою її комірки SRAM_START з файлу включення (рис. 2). Дані займатимуть 8 комірок з $0060 по $0067 (див. рис. 1,б), а вносити їх почнемо зі старшого результату (при хі = 7) з попереднім зменшенням адреси на одиницю (переддекрементом), отже, до одного з індексних регістрів, наприклад, Z pointer потрібно завантажити адресу $0068, для чого з навчальною метою застосуємо до операнда арифметичний оператор додавання: SRAM_START + 8.
;***** Ініціалізація
ldi xi,i ; Load immediate - Завантажити безпосередньо: xi <= i, тобто R17 <= 7
ldi A,a0 ; A <= a0, тобто R18 <= 4
ldi B,b0 ; B <= b0, тобто R19 <= 7
l
di
C,c0
;
C <= c0, тобто R20 <= 118
ori msk,$80 ; Logical OR with immediate - Логічне АБО безпосередньо з
; константою: msk <= msk | $80 = 0b1000 0000
ldi ZL,SRAM_START+8 ; ZL <= SRAM_START+8 – налаштування індексного
; регістра Z pointer на початок даних в ОЗП: Z=R31:R30=$0060+$8 (R31=$00)
