ВЫПОЛНЕНИЕ АРИФМЕТИЧЕСКИХ И ЛОГИЧЕСКИХ

реклама
ЛАБОРАТОРНАЯ РАБОТА №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
3
$001
$002
INT0
I/O Pins
4
5
6
7
8
9
$003
$004
$005
$006
$007
$008
TIMER1, COMPA
TIMER1, OVF
TIMER0, OVF
EE_RDY
ANA_COMP
ADC
Условия возникновения прерывания
Внешний сброс, сброс при включении питания,
сброс при «проседании» напряжения питания и
сброс по сторожевому таймеру
Внешний запрос на прерывание 0
Изменение
напряжения
на
выводах
микроконтроллера
Таймер/счетчик1 (при совпадении)
Таймер/счетчик1 (при переполнении)
Таймер/счетчик0 (при переполнении)
EEPROM готово
Аналоговый компаратор
АЦП преобразование закончено
По адресу $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
Название
Адрес
Функция
Служебные регистры
Регистр состояния
Общий регистр маски прерываний
Общий регистр флагов прерываний
Регистр маски прерываний от таймера/счетчика
Регистр флагов прерываний от таймера/счетчика
Общий регистр управления микроконтроллером
Регистр состояния микроконтроллера
Регистры управления таймером/счетчиком0
Регистр управления таймером/счетчиком0
Счетный регистр таймера/счетчика0
SREG
GIMSK
GIFR
TIMSK
TIFR
MCUCR
MCUSR
$3F
$3B
$3A
$39
$38
$35
$34
TCCR0
TCNT0
$33
$32
OSCCAL
$31
TCCR1
TCNT1
OCR1A
OCR1B
$30
$2F
$2E
$2D
Регистр калибровки тактового генератора
Регистры управления таймером/счетчиком1
Регистр управления таймером/счетчиком1
Счетный регистр таймера/счетчика1
Регистр совпадения A таймера/счетчика1
Регистр совпадения B таймера/счетчика1
SFIOR
$2C
Регистр специальных функций
WDTCR
$21
EEAR
EEDR
EECR
$1E
$1D
$1C
PORTB
$18
Регистр управления сторожевым таймером
Регистры управления EEPROM
Регистр адреса EEPROM
Регистр данных EEPROM
Регистр управления EEPROM
Регистры управления портом B
Регистр данных порта B
DDRB
PINB
ACSR
ADMUX
ADCSR
ADCH
ADCL
$17
$16
Регистр направления данных порта B
Выводы порта B
$08
Регистр управления и состояния аналогового компаратора
Регистры управления аналого-цифровым преобразователем (АЦП)
$07
Регистр управления мультиплексором АЦП
$06
Регистр управления и состояния АЦП
$05
Регистр данных АЦП (старший байт)
$04
Регистр данных АЦП (младший байт)
К любому регистру ввода/вывода можно обратиться с помощью команд IN и OUT,
выполняющих пересылку данных между одним из 32-х регистров общего назначения и
пространством ввода/вывода. Также имеются 4 команды побитного доступа к регистрам
ввода/вывода (SBI, CBI, SBIS, SBIC). Однако последние 4 команды могут обращаться
только к 1-й половине регистров ввода/вывода (т.е. $00…$1F).
Регистр состояния
SREG (Status REGister) – регистр состояния. Этот регистр является набором флагов,
показывающих текущее состояние микроконтроллера. Эти флаги автоматически
устанавливаются в «1» или «0» в соответствии с результатом выполнения команд. Все
разряды этого регистра доступны для чтения и записи (после сброса микроконтроллера
все разряды устанавливаются в «0»). Общий вид этого регистра представлен на
следующем рисунке.
Разряд
Символ
7
I
6
T
5
H
4
S
3
V
2
N
1
Z
0
C
Описание
Общее разрешение прерываний (Interrupt). Для разрешения прерываний
этот разряд должен быть установлен («1»). Данный флаг сбрасывается («0»)
аппаратно при входе в прерывание и восстанавливается («1») при выходе.
Хранение копируемого бита (Temporary). Данный разряд регистра
используется в качестве источника или приемника командами копирования
битов BLD, BST. Указанный разряд любого регистра общего назначения
может быть скопирован в данный бит (BST) или установлен/сброшен (BLD)
в соответствии с содержимым данного бита.
Флаг половинного переноса (Half). Этот флаг устанавливается в «1», если
имел место перенос из младшей половины байта (биты 0…3) в старшую
(биты 4…7) или заем из старшей половины в младшую.
Флаг знака (Sign). Этот флаг равен результату операции «Исключающее
ИЛИ» между флагами N и V (S = N ⊕ V). Этот флаг устанавливается в «1»,
если результат арифметической операции меньше нуля.
Флаг переполнения дополнительного кода (Overflow). Этот флаг
устанавливается в «1» при переполнении разрядной сетки знакового
результата. Используется
при
работе
со
знаковыми
числами
(представленными в дополнительном коде).
Флаг отрицательного значения (Negative). Этот флаг устанавливается в
«1», если старший (7-й) разряд результата операции равен «1». В противном
случае – «0».
Флаг нуля (Zero). Флаг устанавливается в «1», если результат выполнения
операции равен нулю.
Флаг переноса (Carry). Этот флаг устанавливается в «1», если в результате
выполнения операции произошел выход за границы байта.
EEPROM
EEPROM-память может быть использована для долговременного хранения различной
информации, которая может изменяться в процессе функционирования готовой системы
(устройства). К такой информации можно отнести серийные номера, калибровочные
константы, ключи и т.д..
Эта память расположена в отдельном адресном пространстве, а доступ к ней
осуществляется с помощью определенных регистров ввода/вывода. Ее объем составляет
64 байта.
Ассемблер для микроконтроллеров семейства AVR
Язык ассемблера – язык программирования низкого
программированию непосредственно в машинных командах).
уровня
(близкий
к
Машинный код, машинный язык (англ. machine code, machine language) – система
кодов (команд), непосредственно понятных процессору, т.е. таких, которые могут быть
выполнены им непосредственно, без перевода.
«Слова» машинного языка называются машинными инструкциями. Каждая из них
описывает элементарное действие, выполняемое процессором, такое как «переслать байт
из памяти в регистр». Инструкции могут содержать операнды.
Операнд – аргумент инструкции (команды, операции, оператора).
Программа – это просто длинный список инструкций, выполняемых процессором.
Компилятор транслирует исходные коды с языка ассемблера в объектный код.
Полученный объектный код можно использовать в симуляторе Atmel AVR Studio или в
эмуляторе AVR In-Circuit Emulator. Компилятор также генерирует код, который может
быть непосредственно запрограммирован в микроконтроллер. Также компилятор (по
желанию пользователя) генерирует файл листинга программы.
Файл листинга полезно использовать, когда вы хотите точно видеть, что генерирует
Ассемблер при ассемблировании каждой инструкции или директивы. Основу этого файла
составляет исходный файл, в который включен большой объем сопровождающей
информации о результатах ассемблирования. Ассемблер выводит для каждой инструкции
полученный машинный код, а также смещение в текущем сегменте (на каждой строке с
машинным кодом). Кроме того, Ассемблер выводит в таблицах информацию о метках и
сегментах, используемых в программе.
Директивы ассемблера
Директивы ассемблера – параметры (ключевые слова) в тексте программы на языке
ассемблера, влияющие на процесс ассемблирования или свойства выходного файла.
Компилятор поддерживает ряд директив. Директивы не транслируются непосредственно в
код. Вместо этого они используются для указания положения в программной памяти,
определения макросов, инициализации памяти и т.д.
Зарезервировать байты в ОЗУ
Директива
Описание
.BYTE
Директива BYTE резервирует байты в ОЗУ. Если Вы хотите иметь
возможность ссылаться на выделенную область памяти, то директива BYTE
должна быть предварена меткой. Директива принимает один обязательный
параметр, который указывает количество выделяемых байт. Эта директива
может использоваться только в сегменте данных.
Пример
.dseg
var1:
table:
.byte 1
.byte tab_size
; резервирует 1 байт для var1
; резервирует tab_size байт
ldi
ldi
ld
; Загружает младший байт регистра Z
; Загружает старший байт регистра Z
; Загружает VAR1 в регистр 1
.cseg
r30,low(var1)
r31,high(var1)
r1,Z
Программный сегмент
Директива
Описание
.CSEG
Определяет начало программного сегмента. Исходный файл может состоять
из нескольких программных сегментов, которые объединяются в один
программный сегмент при компиляции. Программный сегмент является
сегментом по умолчанию.
Пример
.cseg
const:
.dw
mov
2
r1,r0
; Начало кодового сегмента
; Разместить константу 0x0002 в памяти программ
; Выполнить действия
Определить байты в FLASH или EEPROM
Директива
Описание
.DB
Директива DB резервирует необходимое количество байт в памяти
программ или в EEPROM. Если Вы хотите иметь возможность ссылаться на
выделенную область памяти, то директива DB должна быть предварена
меткой. Директива DB должна иметь хотя бы один параметр. Данная
директива может быть размещена только в сегменте программ (CSEG) или в
сегменте EEPROM (ESEG). Параметры передаваемые директиве – это
последовательность выражений разделённых запятыми. Каждое выражение
должно быть или числом в диапазоне (-128..255), или в результате
вычисления должно давать результат в этом же диапазоне, в противном
случае число усекается до байта без выдачи предупреждений.
Пример
.cseg
consts:
.db
0, 255, 0b01010101, -128, 0xaa
; Память программ
; Размещены 5 байт
.eseg
const2:
.db
1, 2, 3
; Память EEPROM
; Размещены 3 байта
Назначить регистру символическое имя
Директива
Описание
.DEF
Директива DEF позволяет ссылаться на регистр через некоторое
символическое имя. Назначенное имя может использоваться во всей
нижеследующей части программы для обращений к данному регистру.
Регистр может иметь несколько различных имен. Символическое имя
может быть переназначено позднее в программе.
Пример
.def
.def
temp = R16
ior = R0
.cseg
ldi
in
eor
temp, 0xf0
ior, 0x3f
temp, ior
;
;
;
;
Загрузить 0xf0 в регистр temp (R16)
Прочитать SREG в регистр ior (R0)
Регистры temp и ior складываются
по исключающему или
Определить устройство для которого компилируется программа
Директива
Описание
.DEVICE Директива DEVICE позволяет указать, для какого устройства
компилируется программа. При использовании данной директивы
компилятор выдаст предупреждение, если будет найдена инструкция,
которую не поддерживает данный микроконтроллер. Также будет выдано
предупреждение, если программный сегмент, либо сегмент EEPROM
превысят размер, допускаемый устройством. Если же директива не
используется то все инструкции считаются допустимыми, и отсутствуют
ограничения на размер сегментов.
Пример
.device
AT90S1200
; Используется AT90S1200
push
; Эта инструкция вызовет предупреждение
; поскольку AT90S1200 её не имеет
.cseg
r30
Сегмент данных
Директива
Описание
.DSEG
Директива DSEG определяет начало сегмента данных. Исходный файл
может состоять из нескольких сегментов данных, которые объединяются в
один сегмент при компиляции. Сегмент данных обычно состоит только из
директив BYTE и меток. Директива ORG может быть использована для
размещения переменных в необходимом месте ОЗУ.
Пример
.dseg
var1:
table:
.byte 1
.byte tab_size
; Начало сегмента данных
; зарезервировать 1 байт для var1
; зарезервировать tab_size байт.
ldi
ldi
ld
; Загрузить младший байт регистра Z
; Загрузить старший байт регистра Z
; Загрузить var1 в регистр r1
.cseg
r30,low(var1)
r31,high(var1)
r1,Z
Определить слова в FLASH или EEPROM
Директива
Описание
.DW
Директива DW резервирует необходимое количество слов в памяти
программ или в EEPROM. Если Вы хотите иметь возможность ссылаться на
выделенную область памяти, то директива DW должна быть предварена
меткой. Директива DW должна иметь хотя бы один параметр. Данная
директива может быть размещена только в сегменте программ (CSEG) или в
сегменте EEPROM (ESEG).
Пример
.cseg
varlist:
.dw
; Слова располагаются в сегменте кода
0, 0xffff, 0b1001110001010101, -32768, 65535
.eseg
eevarlst:
.dw
0,0xffff,10
; Слова располагаются в сегменте EEPROM
Установить постоянное выражение
Директива
Описание
.EQU
Директива EQU присваивает метке значение. Эта метка может позднее
использоваться в выражениях. Метка, которой присвоено значение данной
директивой не может быть переназначена и её значение не может быть
изменено.
Пример
.equ
.equ
.cseg
io_offset = 0x23
porta = io_offset + 2
clr
out
r2
porta,r2
; Начало сегмента данных
; Очистить регистр r2
; Записать в порт A
Сегмент EEPROM
Директива
Описание
.ESEG
Директива ESEG определяет начало сегмента EEPROM. Исходный файл
может состоять из нескольких сегментов EEPROM, которые объединяются
в один сегмент при компиляции. Сегмент EEPROM обычно состоит только
из директив DB, DW и меток. Директива ORG может быть использована для
размещения переменных в необходимом месте EEPROM.
Пример
.dseg
var1:
table:
.byte 1
.byte tab_size
; Начало сегмента данных
; зарезервировать 1 байт для var1
; зарезервировать tab_size байт.
.eseg
eevar1:
.dw
; проинициализировать 1 слово в EEPROM
0xffff
Выйти из файла
Директива
Описание
.EXIT
Встретив директиву INCLUDE компилятор открывает указанный в ней
файл, компилирует его пока файл не закончится или не встретится
директива EXIT, после этого продолжает компиляцию начального файла со
строки следующей за директивой INCLUDE. Вложенный файл может также
содержать директивы INCLUDE.
Пример
.exit
; Выйти из данного файла
Вложить другой файл
Директива
Описание
.INCLUDE Встретив директиву INCLUDE компилятор открывает указанный в ней
файл, компилирует его пока файл не закончится или не встретится
директива EXIT, после этого продолжает компиляцию начального файла со
строки следующей за директивой INCLUDE. Вложенный файл может также
содержать директивы INCLUDE.
Пример
.include
.include
“tn15def.inc”
“abc.asm”
; Вложить файл tn15def.inc
; Вложить файл abc.asm
Включить генерацию листинга
Директива
Описание
.LIST
Директива LIST указывает компилятору на необходимость создания
листинга. Листинг представляет из себя комбинацию ассемблерного кода,
адресов и кодов операций. По умолчанию генерация листинга включена,
однако данная директива используется совместно с директивой NOLIST для
получения листингов отдельных частей исходных файлов.
Пример
.nolist
.include
.include
.list
"macro.inc"
"const.def"
;
;
;
;
Отключить генерацию листинга
Вложенные файлы не будут
отображены в листинге
Включить генерацию листинга
Выключить генерацию листинга
Директива
Описание
.NOLIST Директива NOLIST указывает компилятору на необходимость прекращения
генерации листинга. Листинг представляет из себя комбинацию
ассемблерного кода, адресов и кодов операций. По умолчанию генерация
листинга включена, однако может быть отключена данной директивой.
Кроме того данная директива может быть использована совместно с
директивой LIST для получения листингов отдельных частей исходных
файлов.
Пример
.nolist
.include
"macro.inc"
; Отключить генерацию листинга
; Вложенные файлы не будут
.include
.list
"const.def"
; отображены в листинге
; Включить генерацию листинга
Установить положение в сегменте
Директива
Описание
.ORG
Директива ORG устанавливает счётчик положения равным заданной
величине, которая передаётся как параметр. Для сегмента данных она
устанавливает счётчик положения в SRAM (ОЗУ), для сегмента программ
это программный счётчик, а для сегмента EEPROM это положение в
EEPROM. Если директиве предшествует метка (в той же строке), то метка
размещается по адресу указанному в параметре директивы. Перед началом
компиляции программный счётчик и счётчик EEPROM равны нулю, а
счётчик ОЗУ равен 32 (поскольку адреса 0-31 заняты регистрами). Для ОЗУ
и EEPROM используются побайтные счётчики а для программного сегмента
– пословный.
Пример
.dseg
variable:
.org
0x37
.byte 1
; Начало сегмента данных
; Установить адрес SRAM равным 0x37
; Зарезервировать байт по адресу 0x37H
.cseg
.org
mov
0x10
r0,r1
; Установить программный счётчик равным 0x10
; Данная команда будет размещена
; по адресу 0x10
Установить переменный символический эквивалент выражения
Директива
Описание
.SET
Директива SET присваивает имени некоторое значение. Это имя позднее
может быть использовано в выражениях. Причем в отличии от директивы
EQU значение имени может быть изменено другой директивой SET.
Пример
.set
.set
io_offset = 0x23
porta = io_offset + 2
.cseg
clr
out
r2
porta,r2
; Начало кодового сегмента
; Очистить регистр 2
; Записать в порт 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
nop
; Внешний запрос на прерывание 0
; Расположен по адресу $001
; (В программе не используется)
nop
; Изменение напряжения на выводах микроконтроллера
; Расположен по адресу $002
; (В программе не используется)
nop
; Таймер/счетчик1 (при совпадении)
; Расположен по адресу $003
; (В программе не используется)
rjmp
T1_OVF
; Таймер/счетчик1 (при переполнении)
; Расположен по адресу $004
; Содержит команду относительного перехода
;
на обработчик прерывания
nop
; Таймер/счетчик0 (при переполнении)
; Расположен по адресу $005
; (В программе не используется)
nop
; EEPROM готово
; Расположен по адресу $006
; (В программе не используется)
nop
; Аналоговый компаратор
; Расположен по адресу $007
; (В программе не используется)
rjmp
ADC_Ready
;
; Инициирующая часть
Reset:
nop
Loop:
; Вектор прерывания по сбросу
; Расположен по адресу $000
; Содержит команду относительного перехода
;
на инициирующую часть программы
nop
rjmp
; АЦП преобразование закончено
; Расположен по адресу $008
; Содержит команду относительного перехода
;
на обработчик прерывания
; Здесь располагаются инструкции настройки
;
портов В/В, таймера, АЦП и др.
; Вечный цикл основной программы
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
Скачать