Вы находитесь на странице: 1из 22

ЛАБОРАТОРНАЯ РАБОТА №2

ВЫПОЛНЕНИЕ АРИФМЕТИЧЕСКИХ
И ЛОГИЧЕСКИХ ОПЕРАЦИЙ
Цель: познакомиться с архитектурой микроконтроллера и основными понятиями,
изучить ассемблер для микроконтроллеров семейства AVR.

Задание: разработать и отладить программу в среде программирования AVR Studio.

Архитектура микроконтроллеров семейства Tiny

Общие сведения

Микроконтроллеры AVR семейства Tiny являются 8-разрядными микроконтроллерами с


RISC-архитектурой. Они имеют электрически стираемую FLASH-память программ (ряд
моделей имеет также энергонезависимую EEPROM-память данных), а также
разнообразные периферийные устройства.

Reduced Instruction Set Computing (technology) – вычисления с сокращённым набором


команд. Архитектура процессоров, построенная на основе сокращённого набора команд.
Характеризуется наличием команд фиксированной длины, большого количества
регистров, операций типа регистр-регистр, а также отсутствием косвенной адресации.

Концепция RISC разработана Джоном Коком (John Cocke) из IBM Research, название
придумано Дэвидом Паттерсоном (David Patterson). Довольно известная реализация
данной архитектуры — процессоры MIPS-серии.

MIPS (англ. Million Instruction Per Second) – величина, которая показывает, сколько
миллионов инструкций в секунду выполняет процессор в некотором синтетическом тесте.

Возможности микроконтроллера:
• высокоэффективный, малопотребляющий 8-битный микроконтроллер AVR;
• современная RISC архитектура:
ƒ 90 мощных инструкций (большинство выполняется за 1 цикл);
ƒ 32 × 8-битных регистра общего назначения;
• надежная память программ и данных:
ƒ 1К перепрограммируемой памяти программ (выдерживает 1 000 циклов
стирания/записи);
ƒ 64 байта EEPROM (выдерживает 100 000 циклов стирания/записи);
ƒ защита программы зашитой в микроконтроллер;
• встроенная периферия:
ƒ прерывание и запуск после ожидания при изменении состояния вывода;
ƒ два 8-битных таймера/счетчика с раздельными делителями;
ƒ 8-битный высокоскоростной (150 кГц) ШИМ;
ƒ 4-канальный 10-битный АЦП (один дифференциальный вход с
опциональным коэффициентом умножения 20x);
ƒ аналоговый компаратор;
ƒ программируемый сторожевой таймер (с отдельным генератором);
• специальные возможности:
ƒ внутрисистемное программирование через SPI порт;
ƒ улучшенная схема сброса по включению питания;
ƒ программируемая схема обнаружения пропадания питания;
ƒ внутренний калиброванный подстраиваемый осциллятор (1,6 МГц);
ƒ внутренний генератор частоты для таймера/счетчика (25,6 МГц);
ƒ внутренние и внешние источники прерывания;
ƒ холостой режим и режим пониженного потребления;
• потребление на частоте 1,6 МГц, 3В, 25°С:
ƒ активный режим: 3 мА;
ƒ холостой режим: 1 мА;
ƒ режим пониженного потребления: < 1 μА;
• напряжение питания:
ƒ 2,7 В … 5,5 В.

Общая структура микроконтроллера Tiny15L приведена на следующем рисунке.


Организация памяти

Организация памяти микроконтроллеров AVR семейства Tiny выполнена по схеме


Гарвардского типа, в которой разделены не только адресные пространства памяти
программ и памяти данных, а также и шины доступа к ним. Память данных состоит из
двух областей: регистровая память и память на основе EEPROM. Каждая область
расположена в своем адресном пространстве.

Память программ

Память программ – электрически стираемое программируемое постоянное


запоминающее устройство (FLASH).

Флэш-память – разновидность твердотельной полупроводниковой энергонезависимой


перезаписываемой памяти. Преимуществом флэш-памяти над обычной является её
энергонезависимость – при выключении энергии содержимое памяти сохраняется.

Память программ предназначена для хранения команд, управляющих функционированием


микроконтроллера (программы). В памяти программ также хранятся константы, не
меняющиеся во время работы программы. Все команды занимают в памяти по 16 бит (2
байта – 1 слово), поэтому память программ имеет 16-разрадную организацию. Для
адресации памяти программ используется счетчик команд (PC – Program Counter). ПЗУ,
используемое в микроконтроллерах AVR, рассчитано как минимум на 1000 циклов
стирания/записи.

Программный счетчик (счетчик команд) – регистр содержащий адрес инструкции,


которая будет извлечена и выполнена следующей.

При нормальном выполнении программы содержимое счетчика команд автоматически


увеличивается на 1 или 2 (в зависимости от выполняемой команды) в каждом машинном
цикле. Этот порядок нарушается при выполнении команд перехода, вызова и возврата из
подпрограмм, а также при возникновении прерываний. Напрямую (как регистр) счетчик
команд из программы недоступен.
После включения питания, а также после сброса микроконтроллера в счетчик программ
автоматически загружается значение $000. Как правило, по этому адресу располагается
команда относительного перехода (RJMP) к инициализационной части программы.

При возникновении прерывания в счетчик команд загружается адрес соответствующего


вектора прерывания ($000…$009). Если прерывания используются в программе, то по
этим адресам должны размещаться команды относительного перехода к подпрограммам
обработки прерываний.

Начиная с адреса $000 располагается таблица векторов прерываний.

Прерывание (англ. interrupt) – сигнал, сообщающий процессору о совершении какого-


либо асинхронного события. При этом выполнение текущей последовательности команд
приостанавливается, и управление передаётся обработчику прерывания, который
выполняет работу по обработке события и возвращает управление в прерванный код.

Виды прерываний:
• аппаратные – события от периферийных устройств (например, нажатия
клавиш клавиатуры, движение мыши, сигнал от таймера, сетевой карты или
дискового накопителя) – внешние прерывания, или события в
микропроцессоре – (например, деление на ноль) – внутренние прерывания;
• программные – инициируются самой программой.

Обработчики прерываний обычно пишутся таким образом, чтобы время их обработки


было как можно меньшим. До окончания обработки прерывания обычно устанавливается
запрет на вызов прерываний. Некоторые процессоры поддерживают иерархию
прерываний, позволяющую прерываниям более высокого приоритета вызываться при
обработке менее важных прерываний.

Вектор прерывания — ячейка памяти, содержащая адрес обработчика прерывания.

Вектора прерываний объединяются в таблицу векторов прерываний.

№ Адрес Источник
Условия возникновения прерывания
вектора в памяти прерывания
1 $000 RESET Внешний сброс, сброс при включении питания,
сброс при «проседании» напряжения питания и
сброс по сторожевому таймеру
2 $001 INT0 Внешний запрос на прерывание 0
3 $002 I/O Pins Изменение напряжения на выводах
микроконтроллера
4 $003 TIMER1, COMPA Таймер/счетчик1 (при совпадении)
5 $004 TIMER1, OVF Таймер/счетчик1 (при переполнении)
6 $005 TIMER0, OVF Таймер/счетчик0 (при переполнении)
7 $006 EE_RDY EEPROM готово
8 $007 ANA_COMP Аналоговый компаратор
9 $008 ADC АЦП преобразование закончено

По адресу $000 памяти программ находится вектор сброса. После инициализации (сброса)
микроконтроллера выполнение программы начинается с этого адреса (по этому адресу
рекомендуется размещать команду относительного перехода к инициализационной части
программы).

Если прерывания в программе не используются, то программа может начинаться


непосредственно с первого адреса ($000).

Пример, программы в которой используется таймер/счетчик1 (настроенный на


прерывание по переполнению) и АЦП приведен в Приложении 1.

Память данных

Память данных микроконтроллеров семейства Tiny разделена на две части:


• регистровая память включает:
ƒ 32 регистра общего назначения;
ƒ регистры ввода/вывода;
• электрически-стираемое программируемое ПЗУ (EEPROM).
Внутреннее статическое ОЗУ в микроконтроллерах семейства Tiny отсутствует.

Регистровая память включает 32 регистра общего назначения, объединенных в т.н. «файл»


и служебные регистры ввода/вывода. Размер регистровой памяти фиксирован и для всех
моделей составляет 96 байт, т.е. 32 байта отводится под регистры общего назначения, а 64
байта – под регистры ввода/вывода.

В области регистров ввода/вывода расположены различные служебные регистры (регистр


состояния, регистр управления микроконтроллером и т.п.), а также регистры управления
периферийными устройствами, входящими в состав микроконтроллера. Общее
количество регистров ввода/вывода зависит от конкретной модели микроконтроллера.

EEPROM (англ. Electrically Erasable Programmable Read-Only Memory) – электронно-


перепрограммируемая постоянная память (электрически-стираемое программируемое
ПЗУ).

Регистры общего назначения

Все регистры общего назначения объединены в файл. В микроконтроллерах AVR все 32


регистра общего назначения непосредственно доступны арифметико-логическому
устройству (АЛУ) – благодаря этому любой из регистров общего назначения может
использоваться во всех командах как операнд-источник и как операнд-приемник.
Исключение составляют лишь ряд инструкций выполняющих действия между регистром
и константой (а именно – SBCI, SUBI, CPI, ANDI, ORI, LDI). Эти команды могут
обращаться только ко второй половине регистров (R16…R31).

Арифметико-логическое устройство (АЛУ) (англ. arithmetic and logic unit, ALU) – блок
процессора, который служит для выполнения арифметических и логических
преобразований над операндами.

Два старших регистра общего назначения (R30, R31) формируют 16-разрядный


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

Регистры ввода/вывода располагаются в так называемом пространстве ввода/вывода


размером 64 байта. Все регистры ввода/вывода можно разделить на 2 группы:
• служебные регистры микроконтроллера;
• регистры, относящиеся к периферийным устройствам.

Разные модели микроконтроллеров имеют различный состав периферийных устройств и,


соответственно, разное количество регистров.

Таблица 1. Список регистров ввода/вывода микроконтроллера Tiny15L


Название Адрес Функция
Служебные регистры
SREG $3F Регистр состояния
GIMSK $3B Общий регистр маски прерываний
GIFR $3A Общий регистр флагов прерываний
TIMSK $39 Регистр маски прерываний от таймера/счетчика
TIFR $38 Регистр флагов прерываний от таймера/счетчика
MCUCR $35 Общий регистр управления микроконтроллером
MCUSR $34 Регистр состояния микроконтроллера
Регистры управления таймером/счетчиком0
TCCR0 $33 Регистр управления таймером/счетчиком0
TCNT0 $32 Счетный регистр таймера/счетчика0

OSCCAL $31 Регистр калибровки тактового генератора


Регистры управления таймером/счетчиком1
TCCR1 $30 Регистр управления таймером/счетчиком1
TCNT1 $2F Счетный регистр таймера/счетчика1
OCR1A $2E Регистр совпадения A таймера/счетчика1
OCR1B $2D Регистр совпадения B таймера/счетчика1

SFIOR $2C Регистр специальных функций

WDTCR $21 Регистр управления сторожевым таймером


Регистры управления EEPROM
EEAR $1E Регистр адреса EEPROM
EEDR $1D Регистр данных EEPROM
EECR $1C Регистр управления EEPROM
Регистры управления портом B
PORTB $18 Регистр данных порта B
DDRB $17 Регистр направления данных порта B
PINB $16 Выводы порта B

ACSR $08 Регистр управления и состояния аналогового компаратора


Регистры управления аналого-цифровым преобразователем (АЦП)
ADMUX $07 Регистр управления мультиплексором АЦП
ADCSR $06 Регистр управления и состояния АЦП
ADCH $05 Регистр данных АЦП (старший байт)
ADCL $04 Регистр данных АЦП (младший байт)

К любому регистру ввода/вывода можно обратиться с помощью команд IN и OUT,


выполняющих пересылку данных между одним из 32-х регистров общего назначения и
пространством ввода/вывода. Также имеются 4 команды побитного доступа к регистрам
ввода/вывода (SBI, CBI, SBIS, SBIC). Однако последние 4 команды могут обращаться
только к 1-й половине регистров ввода/вывода (т.е. $00…$1F).

Регистр состояния

SREG (Status REGister) – регистр состояния. Этот регистр является набором флагов,
показывающих текущее состояние микроконтроллера. Эти флаги автоматически
устанавливаются в «1» или «0» в соответствии с результатом выполнения команд. Все
разряды этого регистра доступны для чтения и записи (после сброса микроконтроллера
все разряды устанавливаются в «0»). Общий вид этого регистра представлен на
следующем рисунке.
Символ
Разряд
Описание

7 I Общее разрешение прерываний (Interrupt). Для разрешения прерываний


этот разряд должен быть установлен («1»). Данный флаг сбрасывается («0»)
аппаратно при входе в прерывание и восстанавливается («1») при выходе.
6 T Хранение копируемого бита (Temporary). Данный разряд регистра
используется в качестве источника или приемника командами копирования
битов BLD, BST. Указанный разряд любого регистра общего назначения
может быть скопирован в данный бит (BST) или установлен/сброшен (BLD)
в соответствии с содержимым данного бита.
5 H Флаг половинного переноса (Half). Этот флаг устанавливается в «1», если
имел место перенос из младшей половины байта (биты 0…3) в старшую
(биты 4…7) или заем из старшей половины в младшую.
4 S Флаг знака (Sign). Этот флаг равен результату операции «Исключающее
ИЛИ» между флагами N и V (S = N ⊕ V). Этот флаг устанавливается в «1»,
если результат арифметической операции меньше нуля.
3 V Флаг переполнения дополнительного кода (Overflow). Этот флаг
устанавливается в «1» при переполнении разрядной сетки знакового
результата. Используется при работе со знаковыми числами
(представленными в дополнительном коде).
2 N Флаг отрицательного значения (Negative). Этот флаг устанавливается в
«1», если старший (7-й) разряд результата операции равен «1». В противном
случае – «0».
1 Z Флаг нуля (Zero). Флаг устанавливается в «1», если результат выполнения
операции равен нулю.
0 C Флаг переноса (Carry). Этот флаг устанавливается в «1», если в результате
выполнения операции произошел выход за границы байта.

EEPROM

EEPROM-память может быть использована для долговременного хранения различной


информации, которая может изменяться в процессе функционирования готовой системы
(устройства). К такой информации можно отнести серийные номера, калибровочные
константы, ключи и т.д..

Эта память расположена в отдельном адресном пространстве, а доступ к ней


осуществляется с помощью определенных регистров ввода/вывода. Ее объем составляет
64 байта.
Ассемблер для микроконтроллеров семейства AVR
Язык ассемблера – язык программирования низкого уровня (близкий к
программированию непосредственно в машинных командах).

Машинный код, машинный язык (англ. machine code, machine language) – система
кодов (команд), непосредственно понятных процессору, т.е. таких, которые могут быть
выполнены им непосредственно, без перевода.

«Слова» машинного языка называются машинными инструкциями. Каждая из них


описывает элементарное действие, выполняемое процессором, такое как «переслать байт
из памяти в регистр». Инструкции могут содержать операнды.

Операнд – аргумент инструкции (команды, операции, оператора).

Программа – это просто длинный список инструкций, выполняемых процессором.

Компилятор транслирует исходные коды с языка ассемблера в объектный код.


Полученный объектный код можно использовать в симуляторе Atmel AVR Studio или в
эмуляторе AVR In-Circuit Emulator. Компилятор также генерирует код, который может
быть непосредственно запрограммирован в микроконтроллер. Также компилятор (по
желанию пользователя) генерирует файл листинга программы.

Файл листинга полезно использовать, когда вы хотите точно видеть, что генерирует
Ассемблер при ассемблировании каждой инструкции или директивы. Основу этого файла
составляет исходный файл, в который включен большой объем сопровождающей
информации о результатах ассемблирования. Ассемблер выводит для каждой инструкции
полученный машинный код, а также смещение в текущем сегменте (на каждой строке с
машинным кодом). Кроме того, Ассемблер выводит в таблицах информацию о метках и
сегментах, используемых в программе.
Директивы ассемблера

Директивы ассемблера – параметры (ключевые слова) в тексте программы на языке


ассемблера, влияющие на процесс ассемблирования или свойства выходного файла.

Компилятор поддерживает ряд директив. Директивы не транслируются непосредственно в


код. Вместо этого они используются для указания положения в программной памяти,
определения макросов, инициализации памяти и т.д.

Зарезервировать байты в ОЗУ


Директива Описание
.BYTE Директива BYTE резервирует байты в ОЗУ. Если Вы хотите иметь
возможность ссылаться на выделенную область памяти, то директива BYTE
должна быть предварена меткой. Директива принимает один обязательный
параметр, который указывает количество выделяемых байт. Эта директива
может использоваться только в сегменте данных.

Пример

.dseg
var1: .byte 1 ; резервирует 1 байт для var1
table: .byte tab_size ; резервирует tab_size байт

.cseg
ldi r30,low(var1) ; Загружает младший байт регистра Z
ldi r31,high(var1) ; Загружает старший байт регистра Z
ld r1,Z ; Загружает VAR1 в регистр 1

Программный сегмент
Директива Описание
.CSEG Определяет начало программного сегмента. Исходный файл может состоять
из нескольких программных сегментов, которые объединяются в один
программный сегмент при компиляции. Программный сегмент является
сегментом по умолчанию.

Пример

.cseg ; Начало кодового сегмента


const: .dw 2 ; Разместить константу 0x0002 в памяти программ
mov r1,r0 ; Выполнить действия

Определить байты в FLASH или EEPROM


Директива Описание
.DB Директива DB резервирует необходимое количество байт в памяти
программ или в EEPROM. Если Вы хотите иметь возможность ссылаться на
выделенную область памяти, то директива DB должна быть предварена
меткой. Директива DB должна иметь хотя бы один параметр. Данная
директива может быть размещена только в сегменте программ (CSEG) или в
сегменте EEPROM (ESEG). Параметры передаваемые директиве – это
последовательность выражений разделённых запятыми. Каждое выражение
должно быть или числом в диапазоне (-128..255), или в результате
вычисления должно давать результат в этом же диапазоне, в противном
случае число усекается до байта без выдачи предупреждений.
Пример

.cseg ; Память программ


consts: .db 0, 255, 0b01010101, -128, 0xaa ; Размещены 5 байт

.eseg ; Память EEPROM


const2: .db 1, 2, 3 ; Размещены 3 байта

Назначить регистру символическое имя


Директива Описание
.DEF Директива DEF позволяет ссылаться на регистр через некоторое
символическое имя. Назначенное имя может использоваться во всей
нижеследующей части программы для обращений к данному регистру.
Регистр может иметь несколько различных имен. Символическое имя
может быть переназначено позднее в программе.

Пример

.def temp = R16


.def ior = R0

.cseg
ldi temp, 0xf0 ; Загрузить 0xf0 в регистр temp (R16)
in ior, 0x3f ; Прочитать SREG в регистр ior (R0)
eor temp, ior ; Регистры temp и ior складываются
; по исключающему или

Определить устройство для которого компилируется программа


Директива Описание
.DEVICE Директива DEVICE позволяет указать, для какого устройства
компилируется программа. При использовании данной директивы
компилятор выдаст предупреждение, если будет найдена инструкция,
которую не поддерживает данный микроконтроллер. Также будет выдано
предупреждение, если программный сегмент, либо сегмент EEPROM
превысят размер, допускаемый устройством. Если же директива не
используется то все инструкции считаются допустимыми, и отсутствуют
ограничения на размер сегментов.

Пример

.device AT90S1200 ; Используется AT90S1200

.cseg
push r30 ; Эта инструкция вызовет предупреждение
; поскольку AT90S1200 её не имеет

Сегмент данных
Директива Описание
.DSEG Директива DSEG определяет начало сегмента данных. Исходный файл
может состоять из нескольких сегментов данных, которые объединяются в
один сегмент при компиляции. Сегмент данных обычно состоит только из
директив BYTE и меток. Директива ORG может быть использована для
размещения переменных в необходимом месте ОЗУ.

Пример
.dseg ; Начало сегмента данных
var1: .byte 1 ; зарезервировать 1 байт для var1
table: .byte tab_size ; зарезервировать tab_size байт.

.cseg
ldi r30,low(var1) ; Загрузить младший байт регистра Z
ldi r31,high(var1) ; Загрузить старший байт регистра Z
ld r1,Z ; Загрузить var1 в регистр r1

Определить слова в FLASH или EEPROM


Директива Описание
.DW Директива DW резервирует необходимое количество слов в памяти
программ или в EEPROM. Если Вы хотите иметь возможность ссылаться на
выделенную область памяти, то директива DW должна быть предварена
меткой. Директива DW должна иметь хотя бы один параметр. Данная
директива может быть размещена только в сегменте программ (CSEG) или в
сегменте EEPROM (ESEG).

Пример

.cseg ; Слова располагаются в сегменте кода


varlist: .dw 0, 0xffff, 0b1001110001010101, -32768, 65535

.eseg ; Слова располагаются в сегменте EEPROM


eevarlst: .dw 0,0xffff,10

Установить постоянное выражение


Директива Описание
.EQU Директива EQU присваивает метке значение. Эта метка может позднее
использоваться в выражениях. Метка, которой присвоено значение данной
директивой не может быть переназначена и её значение не может быть
изменено.

Пример

.equ io_offset = 0x23


.equ porta = io_offset + 2
.cseg ; Начало сегмента данных
clr r2 ; Очистить регистр r2
out porta,r2 ; Записать в порт A

Сегмент EEPROM
Директива Описание
.ESEG Директива ESEG определяет начало сегмента EEPROM. Исходный файл
может состоять из нескольких сегментов EEPROM, которые объединяются
в один сегмент при компиляции. Сегмент EEPROM обычно состоит только
из директив DB, DW и меток. Директива ORG может быть использована для
размещения переменных в необходимом месте EEPROM.

Пример

.dseg ; Начало сегмента данных


var1: .byte 1 ; зарезервировать 1 байт для var1
table: .byte tab_size ; зарезервировать tab_size байт.

.eseg
eevar1: .dw 0xffff ; проинициализировать 1 слово в EEPROM
Выйти из файла
Директива Описание
.EXIT Встретив директиву INCLUDE компилятор открывает указанный в ней
файл, компилирует его пока файл не закончится или не встретится
директива EXIT, после этого продолжает компиляцию начального файла со
строки следующей за директивой INCLUDE. Вложенный файл может также
содержать директивы INCLUDE.

Пример

.exit ; Выйти из данного файла

Вложить другой файл


Директива Описание
.INCLUDE Встретив директиву INCLUDE компилятор открывает указанный в ней
файл, компилирует его пока файл не закончится или не встретится
директива EXIT, после этого продолжает компиляцию начального файла со
строки следующей за директивой INCLUDE. Вложенный файл может также
содержать директивы INCLUDE.

Пример

.include “tn15def.inc” ; Вложить файл tn15def.inc


.include “abc.asm” ; Вложить файл abc.asm

Включить генерацию листинга


Директива Описание
.LIST Директива LIST указывает компилятору на необходимость создания
листинга. Листинг представляет из себя комбинацию ассемблерного кода,
адресов и кодов операций. По умолчанию генерация листинга включена,
однако данная директива используется совместно с директивой NOLIST для
получения листингов отдельных частей исходных файлов.

Пример

.nolist ; Отключить генерацию листинга


.include "macro.inc" ; Вложенные файлы не будут
.include "const.def" ; отображены в листинге
.list ; Включить генерацию листинга

Выключить генерацию листинга


Директива Описание
.NOLIST Директива NOLIST указывает компилятору на необходимость прекращения
генерации листинга. Листинг представляет из себя комбинацию
ассемблерного кода, адресов и кодов операций. По умолчанию генерация
листинга включена, однако может быть отключена данной директивой.
Кроме того данная директива может быть использована совместно с
директивой LIST для получения листингов отдельных частей исходных
файлов.

Пример

.nolist ; Отключить генерацию листинга


.include "macro.inc" ; Вложенные файлы не будут
.include "const.def" ; отображены в листинге
.list ; Включить генерацию листинга

Установить положение в сегменте


Директива Описание
.ORG Директива ORG устанавливает счётчик положения равным заданной
величине, которая передаётся как параметр. Для сегмента данных она
устанавливает счётчик положения в SRAM (ОЗУ), для сегмента программ
это программный счётчик, а для сегмента EEPROM это положение в
EEPROM. Если директиве предшествует метка (в той же строке), то метка
размещается по адресу указанному в параметре директивы. Перед началом
компиляции программный счётчик и счётчик EEPROM равны нулю, а
счётчик ОЗУ равен 32 (поскольку адреса 0-31 заняты регистрами). Для ОЗУ
и EEPROM используются побайтные счётчики а для программного сегмента
– пословный.

Пример

.dseg ; Начало сегмента данных


.org 0x37 ; Установить адрес SRAM равным 0x37
variable: .byte 1 ; Зарезервировать байт по адресу 0x37H

.cseg
.org 0x10 ; Установить программный счётчик равным 0x10
mov r0,r1 ; Данная команда будет размещена
; по адресу 0x10

Установить переменный символический эквивалент выражения


Директива Описание
.SET Директива SET присваивает имени некоторое значение. Это имя позднее
может быть использовано в выражениях. Причем в отличии от директивы
EQU значение имени может быть изменено другой директивой SET.

Пример

.set io_offset = 0x23


.set porta = io_offset + 2

.cseg ; Начало кодового сегмента


clr r2 ; Очистить регистр 2
out porta,r2 ; Записать в порт A
Инструкции микроконтроллеров AVR

Арифметические и логические инструкции


Инструкции ветвления
Инструкции передачи данных
Инструкции работы с битами

В данный момент не реализовано, так как бы мне этого хотелось, поэтому читаем
Справка по Ассемблеру для AVR.pdf (прилагается).
Заметки к лабораторной работе
О выполнении арифметических операций…

Сложение слов

Байт – 8 бит.

7 6 5 4 3 2 1 0

Диапазон значений: 0…255 ($00…$FF).

Слово – 16 бит.

Старший байт Младший байт


15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Диапазон значений: 0…65535 ($0000…$FFFF).

Разбиваем слово на 2 байта

Вариант 1.

48 452

СТАРШИЙ БАЙТ: Округляем до меньшего целого (48 452 / 256) = 189


МЛАДШИЙ БАЙТ: 48 452 – СТАРШИЙ БАЙТ × 256 = 68

Вариант 2.

48 452 переводим в шестнадцатеричную систему – $BD44,


где $BD = 189 – СТАРШИЙ БАЙТ;
$44 = 68 – МЛАДШИЙ БАЙТ.

Вариант 3 (утопический!).

48 452 переводим в двоичную систему – 0b1011 1101 0100 0100,


где 0b1011 1101 = 189 – СТАРШИЙ БАЙТ
0b0100 0100 = 68 – МЛАДШИЙ БАЙТ

Вариант 4 (самый простой).

Используем встроенные функции языка ассемблер

High(48 452) = 189 – возвращает СТАРШИЙ БАЙТ слова


Low(48 452) = 68 – возвращает МЛАДШИЙ БАЙТ слова

Т.е. после выполнения следующих инструкций в R16 будет содержаться младший байт
слова, а в R17 – старший.
Складываем слова

1. Складываются младшие байты.


2. Складываются старшие байты с переносом, который мог возникнуть
(переполнение регистра) при сложении младших.
Для проверки результата сложения:
СТАРШИЙ БАЙТ × 256 + МЛАДШИЙ БАЙТ = 191 × 256 + 62 = 48 958

Вычитание слов производится аналогично сложению

Умножение

Любую операцию умножения можно заменить операцией сложения.

Т.е.
4 × 20 =
=20 + 20 + 20 + 20 =
=4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4=
= 80

Реализуется это при помощи цикла

Операция сложения будет выполнятся до тех пор, пока регистр R16 не станет равным
нулю.

Умножение/Деление на 2n

Операция умножения на 2n может быть выполнена при помощи сдвига регистра влево
(←), а операция деления – вправо (→), n раз.

Рассмотрим пример…
54 × 4 = 216

Переведем 54 в двоичную систему счисления: 0011 0110


Для умножения на 4 – два раза сдвинем регистр влево – получим: 1101 1000
Переведем полученное число обратно в десятичную систему: 1101 1000 = 216.

Для работы с словами разбитыми на байты используем инструкции сдвига через флаг
переноса (см. текст программы и Справочник по инструкциям).

Для проверки переведем полученное число $165B = 5723.


Контрольные вопросы
1. Что такое RISC-архитектура.
2. Что характеризует MIPS.
3. Состав периферии Tiny15L.
4. Схема распределения памяти.
5. Программный счетчик.
6. Что такое прерывание. Какие виды прерываний бывают.
7. Что такое таблица векторов прерываний.
8. Различие флэш-памяти микроконтроллера и EEPROM.
9. Что такое АЛУ.
10. Зачем предназначены регистры ввода/вывода.
11. Регистр состояния (SREG). Его использование в арифметических операциях.
12. Ассемблер – это…
13. Машинный язык – это…
14. Что такое программа.
15. Работа, выполняемая компилятором.
16. Директивы ассемблера и их отличие от инструкций.
Приложение 1
; Программа в которой используется:
; - таймер/счетчик1 (настроенный на прерывание по переполнению);
; - АЦП.

.org 0
;
; Таблица векторов прерываний
rjmp Reset ; Вектор прерывания по сбросу
; Расположен по адресу $000
; Содержит команду относительного перехода
; на инициирующую часть программы

nop ; Внешний запрос на прерывание 0


; Расположен по адресу $001
; (В программе не используется)

nop ; Изменение напряжения на выводах микроконтроллера


; Расположен по адресу $002
; (В программе не используется)

nop ; Таймер/счетчик1 (при совпадении)


; Расположен по адресу $003
; (В программе не используется)

rjmp T1_OVF ; Таймер/счетчик1 (при переполнении)


; Расположен по адресу $004
; Содержит команду относительного перехода
; на обработчик прерывания

nop ; Таймер/счетчик0 (при переполнении)


; Расположен по адресу $005
; (В программе не используется)

nop ; EEPROM готово


; Расположен по адресу $006
; (В программе не используется)

nop ; Аналоговый компаратор


; Расположен по адресу $007
; (В программе не используется)

rjmp ADC_Ready ; АЦП преобразование закончено


; Расположен по адресу $008
; Содержит команду относительного перехода
; на обработчик прерывания
;
; Инициирующая часть
Reset: nop ; Здесь располагаются инструкции настройки
; портов В/В, таймера, АЦП и др.

Loop: nop ; Вечный цикл основной программы


rjmp Loop

;
; Таймер/счетчик1 (при переполнении)
T1_OVF: nop ; Подпрограмма обработки прерывания
; при переполнении счетчика1
;
reti ; Возврат из прерывания

;
; АЦП преобразование закончено
ADC_Ready: ; Подпрограмма обработки прерывания
nop ; при окончании аналого-цифрового преобразования
;
reti ; Возврат из прерывания
Приложение 2
Задания для программирования

Вариант 1

(45 + 68) × 14 − 1582 + 1

Вариант 2

62345 / 16 + 104 + 2

Вариант 3

3056 × 4 − 456 − 5

Вариант 4

45 2 + 40000 − 1

Вам также может понравиться