Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Микропроцессорные системы. Средства разработки программного обеспечения для микроконтроллеров семейства AVR. Учебное пособие
.pdf
11
команд процессора работает с регистрами или памятью данных. Систе-
ма команд ядра AVR близка к идеологии RISC.
Процессор AVR имеет 32 8-битных регистра общего назначения
(РОН или General purpose registers), объединенных в регистровый файл.
Регистры обозначаются как R0-R31. В отличие от «идеального» RISCядра, регистры не равноправны (рис. 2).
Рис. 2. Карта регистров микроконтроллеров серии AVR
Некоторые машинные команды пересылки, арифметических и ло-
гических операций (ANDI/CBR, ORI/SBR, CPI, LDI, LDS, STS, SUBI,
SBCI, SER и MULS) работают только с регистрами R16…R31.
Четыре последние пары регистров (R24-R31) могут использоваться попарно для операций с 16-битными числами. В командах, работающих с 16-битными операндами, четные регистры (R24, R26, R28, R30)
хранят младшие 8 бит 16-битного числа, а нечетные регистры (R25,
R27, R29, R31) хранят старшие 8 бит 16-битного числа.
Последние три пары регистров (R26:R27, R28:R29 и R30:R31)
имеют специальные обозначения X, Y и Z. Регистр X представлен парой
РОН R26:R27, Y – парой РОН R28:R29 и Z – парой РОН R30:R31.

12
Команды сложения и вычитания 16-битного значения с непосред-
ственным операндом (ADIW, SBIW) работают только с одной из пар
R25:R24, R27:R26 (X), R29:R28 (Y) или R31:R30 (Z).
Команда копирования пары регистров работает только с соседни-
ми регистрами, начинающимися с нечетного (R1:R0, R3:R2, …,
R31:R30).
Результат команды умножения всегда помещается в R1:R0. Также
только эта пара используется в качестве операндов для команды самопрограммирования (для тех микроконтроллеров, где имеется функция
самопрограммирования).
Кроме РОН имеются также и регистры специального назначения.
Это регистр-счетчик команд PC (Program Counter); регистр-указатель
стека SP (Stack Pointer) и регистр состояния SREG (Status and Control
Register).
Регистр-счетчик команд PC содержит адрес следующей исполняе-
мой команды в памяти программ. Изменение этого регистра производится автоматически, при выполнении линейной последовательности
команд. Команды перехода или вызова подпрограмм могут изменять
значение регистра PC, вызывая тем самым условное ветвление про-
граммы или безусловный переход по новому адресу.
Регистр-указатель стека SP указывает на вершину стека в памяти
данных. Данный регистр изменяется при вызове подпрограммы или
процедуры обработки прерывания; при возврате из подпрограммы или
процедуры обработки прерывания; при помещении на стек или извлечении из стека значений регистров; при непосредственной установке зна-
чения SP.
Регистр SREG хранит биты-флаги последней арифметической или
логической операции; флаг глобального разрешения прерываний; битхранилище для специальных команд копирования битов.
Более подробное описание регистров специального назначения
PC, SP и SREG приводится ниже в других разделах настоящего издания.
4.1. Выполнение машинных команд
Кратко рассмотрим, как происходит выполнение программы на
уровне машинных инструкций на примере микроконтроллера с архитектурой AVR. В общем случае каждая инструкция ядра AVR имеет от трех
до пяти этапов выполнения (рис. 3).
Первый этап, обязательный – выборка команды. Начало вы-
полнения каждой машинной команды – выборка кода операции (КОП)
из памяти программ по адресу, который хранится в регистре-счетчике
команд PC. КОП микроконтроллера AVR представляет собой 16-битное

13
слово. Память программ микроконтроллеров AVR физически организо-
вана в виде 16-битных слов. Регистр-счетчик команд PC адресует память
программ в 16-битных словах и, следовательно, не может указывать на
нечетные байты.
Второй этап, обязательный – декодирование команды. После
считывания КОП из памяти программ ядро микроконтроллера AVR
производит увеличение значения регистра PC на единицу. Теперь ре-
гистр PC указывает на следующее слово.
Одновременно с увеличением значения регистра PC на единицу
происходит декодирование команды. После считывания из памяти программ, КОП подается на декодер инструкций. Декодер инструкций по
состоянию групп битов КОП определяет тип инструкции (арифметиче-
ская, логическая, команда перехода и т. п.); тип адресации; наличие или
отсутствие операндов и тип операндов (регистр, регистровая пара, ячей-
ка памяти и т. п.).
Рис. 3. Этапы выполнения машинной команды
Третий этап, необязательный – выборка операндов. После того
как произведено декодирование КОП, в зависимости от типа команды,
может потребоваться дополнительный цикл выборки операндов из памяти программ. В микроконтроллерах семейства AVR цикл выборки
операндов из памяти программ требуется только в командах вызова по
абсолютному адресу или перехода по абсолютному адресу. Заметим, что
операндом в таких командах является 16-битное слово.

14
Четвертый этап, обязательный – выполнение команды. Дей-
ствия, производимые во время выполнения команды, целиком и полностью зависят от того, что было закодировано в КОП. Обратим внимание,
что значение регистра PC на этом этапе может быть изменено, если в
КОП закодирована команда одного из типов: команда перехода; команда
вызова подпрограммы; команда возврата из подпрограммы; команда
возврата из процедуры обработки прерывания. Кроме того, команды вызова подпрограмм и возврата из подпрограмм изменяют содержимое
стека и регистра указателя стека SP.
Пятый этап, необязательный – запись результата. Если резуль-
тат выполнения команды требуется записать в память – то выполняется
еще один дополнительный этап выполнения команды – запись результа-
та в память.
После выполнения команды, значение в регистре PC указывает на
адрес следующей выполняемой команды, и вся последовательность обработки команды выполняется снова.
4.2. Выполнение команд ветвления и перехода
Команды перехода дают возможность передачи управления команде, расположенной по произвольному адресу памяти программ.
Команды ветвления дают возможность изменять ход выполнения
программы в зависимости от выполнения или невыполнения опреде-
ленных условий.
Рассмотрим, как выполняются команды перехода на примере микроконтроллеров семейства AVR (рис. 4).
Рис. 4. Пример выполнения команды перехода

15
Общий принцип выполнения команд уже описан, поэтому остано-
вимся только на особенностях команд ветвления и перехода.
В составе команд микроконтроллеров семейства AVR имеются
команды ветвления (или условного перехода) и команды безусловного
перехода.
Команды безусловного перехода всегда изменяют значение реги-
стра PC на заданное, начиная выполнение команды с указанного нового
адреса.
На рис. 4 приведен пример выполнения команды безусловного пе-
рехода JMP по адресу 6. Как видим, единственное отличие от уже описанного способа выполнения команд (см. рис. 3) состоит в том, что на
этапе выполнения команды изменяется значение регистра-счетчика команд PC.
Команды ветвления (или условного перехода, или условного про-
пуска команд) в зависимости от выполнения или невыполнения определенных условий могут продолжить выполнение со следующей команды
или изменить значение регистра PC, вызвав тем самым переход на другую ветвь исполнения программы. В общем случае в качестве условий,
проверяемых командами ветвления, выступают значения битов регистра
состояния процессора SREG или биты портов ввода-вывода.
Более подробно о командах ветвления микроконтроллеров семейства AVR можно узнать в [1, 2].
4.3. Выполнение команд вызова подпрограмм
Основным отличием команд вызова подпрограмм от команд без-
условного перехода является то, что после выполнения подпрограммы
необходимо продолжить выполнение программы с команды, следующей
за командой вызова подпрограммы.
Иными словами, при вызове подпрограммы необходимо запом-
нить адрес команды, следующей за командой вызова подпрограммы.
Этот адрес также называется адресом возврата из подпрограммы.
Для сохранения адресов возврата используется машинный стек, или
стек возвратов.
Стек – это структура памяти, работающая по принципу «послед-
ний пришел – первый ушел». Для организации стека возвратов исполь-
зуется регистр-указатель стека SP.
Имеются также специальные машинные команды работы со стеком – PUSH и POP.
Команда PUSH – поместить содержимое указанного регистра на
стек. В процессе выполнения данной команды значение регистра-
указателя стека SP уменьшается на единицу. Затем содержимое указан-

16
ного регистра помещается в память данных по адресу, значение которо-
го хранится в SP.
Команда POP – получить со стека значение и поместить его в ука-
занный регистр. В процессе выполнения данной команды из памяти
данных извлекается байт, расположенный по адресу, значение которого
хранится в SP. Значение этого байта данных помещается в указанный
регистр. Затем значение регистра-указателя стека SP увеличивается на
единицу.
Рассмотрим, как происходит вызов подпрограммы (команда
CALL) и возврат из подпрограммы (команда RET).
Команда CALL в качестве операнда использует абсолютный адрес
подпрограммы, имеющий размер 16 бит (2 байта). К началу этапа выполнения команды CALL регистр PC содержит адрес следующей вы-
полняемой команды, т. е. адрес возврата из вызываемой подпрограммы
(см. рис. 3). Команда CALL во время этапа выполнения производит сле-
дующие действия:
уменьшает значение регистра-указателя стека SP на 2, т. к. ре-
гистр PC имеет размер 2 байта;
помещает на стек содержимое регистра PC (адреса возврата
подпрограммы);
заносит в регистр PC адрес подпрограммы (полностью анало-
гично команде JMP).
Следующая команда, которая будет выполнена за командой вызова
подпрограммы, будет первая команда вызываемой подпрограммы.
Кроме команды CALL, в микроконтроллерах семейства AVR име-
ются и другие команды вызова подпрограмм – ICALL и RCALL.
Эти команды отличаются от команды CALL только способом вычисления адреса подпрограммы:
команда CALL использует в качестве адреса подпрограммы
константу, размером 2 байта. При этом размер команды CALL – 4 байта:
2 байта – КОП и 2 байта – адрес подпрограммы;
команда RCALL использует в качестве адреса подпрограммы
константу, размером 12 бит, входящую в КОП. Адрес вызова подпрограммы вычисляется путем сложения содержимого регистра PC с
12-битной константой, интерпретируемой как знаковое целое число. Та-
кая команда позволяет осуществить вызов подпрограмм в пределах от
+2047 до –2048 слов относительно адреса расположения команды вызо-
ва. При этом размер команды RCALL – 2 байта;
команда ICALL использует в качестве адреса подпрограммы со-
держимое регистра Z (т. е. пары регистров R30:R31). Данная команда

17
удобна при наличии таблицы подпрограмм, когда адрес вызываемой
подпрограммы вычисляется, а не задается константой.
Команда RET не имеет аргументов и, во время этапа выполнения,
производит следующие действия:
снимает со стека адрес возврата из подпрограммы (2 байта) и
заносит этот адрес в регистр PC;
увеличивает значение регистра-указателя стека SP на 2.
По сути, команда возврата из подпрограммы RET осуществляет
передачу управления по адресу, который хранился на вершине стека к
моменту выполнения команды RET.
Кроме команды RET, в микроконтроллерах семейства AVR имеет-
ся команда RETI, используемая для возврата из процедуры обработки
прерывания. Отличие команды RETI от команды RET состоит в том, что
команда RETI во время выполнения устанавливает глобальный флаг
разрешения прерываний. В остальном команды RET и RETI полностью
аналогичны. Подробнее о прерываниях рассказано в соответствующем
разделе.
Следует помнить, что если мы выполним команду RET, не вызвав
предварительно подпрограмму командой CALL, то произойдет переход
по произвольному адресу и программа может дать сбой.
Кроме того, если мы используем команды PUSH и POP для сохра-
нения на стеке или извлечения со стека данных – то непарное использование этих команд в подпрограмме может привести к неверной работе
команды RET.
Поэтому следует помнить несколько правил обращения к подпрограммам в машинном коде, помогающих избегать краха программы изза повреждения содержимого стека:
когда вы используете подпрограмму, то для ее вызова следует
использовать только команды CALL, ICALL или RCALL;
возврат из подпрограммы выполняется командой RET;
внутри подпрограммы (т. е. от точки входа в подпрограмму до
команды RET) количество команд PUSH должно быть равно количеству
команд POP;
во время выполнения подпрограммы количество команд PUSH
ни в какой момент времени не должно быть меньше количества команд
POP.

18
5. ОСОБЕННОСТИ РАЗРАБОТКИ ПО ДЛЯ МИКРОКОНТРОЛЛЕРА
Основной отличительной особенностью, с точки зрения разработ-
чика ПО, для микроконтроллеров семейства AVR, как и многих других
семейств микроконтроллеров, является отсутствие полноценной опера-
ционной системы.
Разработчик ПО сам определяет всю «жизнь» программного обес-
печения и способы взаимодействия с внешними устройствами. Эта осо-
бенность имеет как свои положительные, так и отрицательные стороны.
Положительной стороной отсутствия операционной системы яв-
ляется возможность организовать взаимодействие компонентов ПО и
аппаратного обеспечения самым оптимальным образом с точки зрения
решаемой задачи.
Отрицательные стороны также очевидны – большая трудоемкость
разработки ПО и повышенные требования к знанию особенностей аппа-
ратных средств микроконтроллера.
Другой отличительной особенностью разработки ПО для микро-
контроллеров семейства AVR является относительно небольшой размер
памяти программ (единицы – сотни килобайт) и памяти данных (десят-
ки байт – единицы килобайт).
Такие ограничения часто требуют от разработчика специальных
программных решений, некоторые из которых рассмотрены ниже.

19
6. СРЕДСТВА РАЗРАБОТКИ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
Современные средства разработки программного обеспечения для
микроконтроллеров семейства AVR представлены очень широким спектром программных продуктов. Наиболее распространенные из них
включают: ассемблер, компиляторы с языков С и С++, утилиты для про-
граммирования памяти программ микроконтроллеров.
В настоящем издании все примеры программ ориентированы на
использование свободных средств разработки GCC.
6.1. Компиляторы семейства GCC
GCC (GNU Compiler Collection) – набор компиляторов для раз-
личных языков программирования, разработанный в рамках проекта
GNU, являющийся свободным программным обеспечением.
GCC распространяется фондом свободного программного обеспе-
чения (FSF) на условиях GNU GPL и GNU LGPL и является ключевым
компонентом набора утилит GNU toolchain.
В настоящее время GCC поддерживает компиляцию исходных кодов на таких языках программирования, как C, C++, Objective-C, Java,
Фортран, Ada и Go.
В настоящем издании все примеры программ приведены на С++,
стандарта C++11 или ISO/IEC 14882:2011 по международной классификации. Для простоты описания язык С в настоящем пособии рассматри-
вается как подмножество языка С++, не включающее классов.
Использование коллекции компиляторов GCC позволяет создавать
различные программные модули и библиотеки на разных языках.
При этом модули совместимы между собой и могут линковаться в единый исполняемый файл.
6.2. Организация проекта на языках С и С++
Вопрос правильной организации проекта на языках С и С++ является одним из важнейших при разработке ПО.
Выделяется несколько уровней организации: процедурный уровень (или уровень классов), файловый уровень, уровень библиотек.
Рассматривая программу на уровне процедур или классов, необхо-
димо определить, какую задачу решает та или иная функция (класс), ка-
кие входные данные нужны для этого.
Для проекта даже небольшой сложности количество функций и
классов может измеряться десятками, поэтому обычно проект состоит
из нескольких файлов с исходным текстом.

20
Файловый уровень проекта определяет, как организованы файлы с
исходным текстом, данными и скриптами сборки.
Рассмотрим назначение различных файлов (табл. 1), участвующих
в проекте на языках С и С++, собираемых с помощью утилит make и
cmake [3–5].
Таблица 1
Назначение файлов с различными расширениями
№
п/п
Расширение
файла
Назначение
Примечание
1
*.c
Исходный текст на языке C
Текстовый файл
2
*.cxx
*.cpp
*.c++
Исходный текст на языке C++
Текстовый файл
3
*.h
*.hxx
*.hpp
Заголовочный файл
Текстовый файл
4
Makefile
makefile
Сборочный скрипт, обрабатываемый
утилитой make
Текстовый файл
5
CMakeLists.txt
Сборочный скрипт, обрабатываемый
утилитой cmake. Используется для ав-
томатической генерации Makefile
Текстовый файл
6
*.i
*.ii
Файл, обработанный препроцессором
Текстовый файл
7
*.s
*.S
*.asm
Файл на языке ассемблера
Текстовый файл
8
*.o
Несвязанный объектный код
Бинарный файл
9
*.*
Исполняемый файл. В UNIX-системах
не имеет специального расширения.
В виндовс – *.com или *.exe
Бинарный файл
10
*.bin
Образ памяти, например для программирования встроенного ПЗУ специаль-
ной утилитой
Бинарный файл
11
*.hex
Образ памяти, например для программирования встроенного ПЗУ специаль-
ной утилитой
Текстовый файл
Отметим, что в табл. 1 показаны общепринятые расширения фай-
лов, но проектировщик может использовать и другие, более удобные
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
