→ Atmel avr программирование на ассемблер. Ассемблер avr для начинающих (первый шаг). Электроника в греческом стиле

Atmel avr программирование на ассемблер. Ассемблер avr для начинающих (первый шаг). Электроника в греческом стиле


Итак, надеюсь добросовестный читатель уже собрал программатор, экспериментальную плату, а также установил и настроил требуемое программное обеспечение.

Сейчас, написав первую статью из цикла, я понимаю, что несколько погорячился и сделал ту же ошибку, что и мои предшественники, поставив словосочетание "для начинающих". Вернее было бы сформулировать тему "Для начинающих программировать на ассемблере", то есть я предполагаю, что читатель уже имеет хотя бы поверхностное представление о том, что такое микроконтроллер, иначе только на знакомство с этой темой у нас уйдет уйма времени. Для тех же, кто совсем не знаком с ними, могу порекомендовать совершенно замечательный на мой взгляд цикл статей С. Рюмика "Микроконтроллеры AVR", опубликованный в журнале Радиоаматор (№№ 1-11 за 2005 год). В этом цикле в качестве базового контроллера выбран ATmega8, однако общие функциональные узлы у вышеназванного контроллера и ATtiny13 практически не отличаются.

Для знакомства же непосредственно с микроконтроллером ATtiny13 я рекомендую книгу А.В. Евстифеева "Микроконтроллеры AVR семейства tiny. Руководство пользователя" (М.: Издательский дом "Додэка-XXI", 2007. - 432 с.). Она содержит переведенные и систематизированные даташиты на весь номенклатурный ряд контроллеров семейства tiny, и, на мой взгляд, должна являться настольной для тех, кто занимается программированием микроконтроллеров.

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

Но все это лирическое отступление. Вернемся непосредственно к повествованию.

Контроллер ATtiny13 несмотря на свой малый размер, имеет весьма неплохие функциональные характеристики. А небольшое количество выводов с лихвой компенсируется количеством функций, которые каждый из них выполняет. Цоколевка и описание выводов представлено ниже:

Таблица взята из вышеназванной книги А.В. Евстифеева.

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

Как видно из рисунка и таблицы, все выводы, за исключением выводов питания, имеет название РВ с последующим порядковым номером. Что же это означает? Все выводы контроллера объединены по 8 штук для удобства работы с ними, а на каждую группу из 8 выводов выделено по три специальных регистра ввода-вывода. Вообще понятие регистров является ключевым при работе в контроллерами, особенно на ассемблере. Рассмотрим более подробно каждый из трех вышеупомянутых регистров. Все они являются однобайтовыми ячейкам в памяти контроллера. Каждый бит их отвечает один из выводов контроллера, причем номер бита в регистре совпадает с номером вывода (например, 0-й бит отвечает за вывод РВ0, 1-й - за РВ1 и т.д.). Все регистры имеют свое имя, по которому к ним обращаются при написании программ. Что же это за имена?

1. Регистр DDRB отвечает за направление передачи информации каждого вывода контроллера. Если какой-либо бит этого регистра равен "0", то соответствующий ему вывод будет входом, а если "1" - то выходом. Причем каждый вывод конфигурируется индивидуально и в любом месте программы. Это значит, что при разных условиях или в разное время один и тот же вывод может быть сконфигурирован как вход либо как выход, причем независимо от остальных выводов.

2. Регистр PINB содержит в себе текущее состояние всех выводов: если на вывод подано напряжение, то в соответствующий бит записывается логическая "1", если напряжение отсутствует - логический "0". В основном этот регистр используется для считывания состояния вывода, находящегося в режиме входа.

3. Регистр PORTB выполняет двоякую функцию в зависимости направления передачи информации. Если вывод работает как цифровой выход, то запись "1" в какой-либо бит регистра PORTB приводит к появлению напряжения на соответствующем выводе, а запись "0" - к исчезновению напряжения. Таким образом, в режиме выхода именно этот регистр определяет состояние каждого вывода. В режиме цифрового входа запись логической "1" в какой-либо бит приводит к подключению встроенного подтягивающего резистора на соответствующем выводе, а запись "0" - к его отключению. Что же это за такая штука - "подтягивающий резистор", и для чего она предназначена? Если вывод работает как цифровой вход, то сопротивление входного буфера достаточно велико, а входной ток - весьма мал. Поэтому любые электрические наводки могут привести к самопроизвольному переключению вывода в произвольное состояние. Чтобы этого не происходило, между входом и источником питания включается резистор сопротивлением несколько десятков килоом, "подтягивающий" потенциал входа к напряжению питания (отсюда и название). Ток, протекающий через этот резистор достаточно мал, чтобы не мешать работе остальной схемы, но достаточно велик, чтобы воспрепятствовать случайным переключениям вывода. Мы часто будем использовать подтягивающие резисторы при работе с кнопками, поскольку когда они не нажаты, выводы, к которым они подключены, фактически "висят" в воздухе и подвержены наводкам.

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

Теперь, когда мы имеем хоть какое-то представление, ЧТО нужно для работы с вводами контроллера, пришла пора узнать, КАК с ними работать.

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

1. Заходим в папку asm, создаем в ней новую папку. Переименовываем в удобное для нас имя. Для определенности я буду называть их по номеру нашего шага. В данном случае "step2".

2. Правой кнопкой щелкаем на файле build.bat и изменяем путь к исходному файлу, указывая вновь созданную папку (step2). У меня после этого содержимое выглядит так:

"F:\Prog\AVR\asm\avrasm32 -fI %F:\Prog\AVR\asm\step2\main.asm
pause"

У вас оно может отличаться в зависимости от того, куда вы распаковали архив.

3. Заходим в папку Asmedit и запускаем программу ASM_Ed.exe

4. В открывшемся окне пишем текст программы. На этом пункте остановлюсь более подробно, поскольку он является основным в нашем сегодняшнем занятии, равно как и в последующих.

Что же собой представляет текст ассемблерной программы? Он может включать в себя несколько элементов, записываемых по определенным правилам:

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

Директивы, каждая из которых начинается с символа ".";

Метки, представляющие собой произвольно названные пользователем места программы, к которым может потребоваться переход. Каждая метка оканчивается символом ":";

Комментарии, начинающиеся с символа ";". Весь текст от начала комментария до конца строки игнорируется при создании hex-файла и может быть совершенно произвольным;

Пустые строки для лучшей структурированности и читабельности программы.

В каждой строке может быть не более одной команды. Однако одновременное присутствие в строке метки с последующей командой и комментарием допускается.

Используя эти правила, напишем программу, которая будет включать светодиод LED2, пока удерживается нажатой кнопка SB1, и выключать его, если кнопка отпущена. Текст программы представлен ниже:

.include "F:\Prog\AVR\asm\Appnotes\tn13def.inc"
sbi DDRB, 4 ;РВ4 - выход (светодиод LED2)
sbi PORTB, 2 ;Включение подтягивающего резистора на РВ2 (кнопка SB1)
sbic PINB, 2 ;Если РВ2=0 (кнопка нажата), пропустить след. строку
sbi PORTB, 4 ;Установка РВ4 в 1 (выключение светодиода)
sbis PINB, 2 ;Если РВ2=1 (кнопка отпущена), пропустить след. строку
cbi PORTB, 4 ;Установка РВ4 в 0 (включение светодиода)

Разберем его поподробнее. Первая строка содержит директиву "include", написанную по указанным выше правилам с точкой в начале. Назначение ее - включать в текст программы указанный за ней файл. Как я говорил еще в первом шаге, нам потребуется файл "tn13def.inc". В этой строке вам необходимо будет изменить путь, указав расположение папки Appnotes в своем компьютере. Зачем же нам нужно подключать этот файл? Любопытный читатель может заглянуть в него и почитать его содержимое, но, скорее всего, поначалу он мало что поймет там. Пока же скажу, что в нем содержится соответствие имен регистров, которые по умолчанию ассемблер не знает, с их физическими адресами в контроллере.

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

Команда sbi имеет два операнда: первый - имя регистра, второй - номер бита. В результате ее выполнения указанный бит в указанном регистре устанавливается в "1".

Команда cbi по синтаксису аналогична вышеприведенной и выполняет прямо противоположную функцию - сбрасывает указанный бит в указанном регистре в "0".

Команда sbis также аналогична по синтаксису вышеприведенным. Однако в отличие от них она не выполняет никаких операций с регистрами, а лишь проверяет состояние указанного бита в указанном регистре, и если тот равен "1", пропускает следующую за командой строку. В противном же случае следующая за ней строка выполняется, равно как и все остальные за ней.

Команда sbiс является противоположностью команды sbis. Она пропускает следующую строку, если указанный бит регистра равен "0".

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

1 строка. Директивой include подключается файл tn13def.inc, содержащий определения регистров.

2 строка. Командой sbi устанавливается "1" в бит 4 регистра DDRB, тем самым вывод РВ4 переключается на выход. Если посмотреть схему платы (рис. 1 предыдущего шага), можно видеть, что к этому выводу подключен светодиод LED2. После команды и знака ";" написан комментарий, кратко поясняющий смысл выполняемых в строке действий.

3 строка. Той же командой sbi устанавливается "1" в бит 2 регистра PORTB, подключая внутренний подтягивающий резистор к выводу РВ2, к которому подключена кнопка SB1. Поскольку мы не изменяли состояние бита 2 регистра DDRB, этот вывод так и останется входом, что нам, собственно, и нужно.

4 строка. Командой sbic проверяется наличие логического "0" на входе PB2, используя регистр PINB. Если внимательно посмотреть на схему, можно увидеть, что кнопки при нажатии, замыкают соответствующий вывод с общим проводом. Это стандартный прием, поскольку при отпущенной кнопке на выводе присутствует логическая "1" за счет подтягивающего резистора, а при нажатой появляется логический "0" благодаря подключению вывода к общему проводу. Итак, если на выводе РВ2 присутствует логический "0", то есть кнопка нажата, мы пропускаем следующую строку, а если кнопка отпущена, то выполняем ее.

5 строка. В ней командой sbi устанавливается логическая "1" в бит 4 регистра PORTB, тем самым выключая светодиод LED2. Въедливый читатель может поинтересоваться, почему же светодиод выключается, если мы подаем напряжение на выход. Ответ кроется в схеме. Светодиод анодом подключен к проводу питания, а катодом к выводу контроллера. Поэтому если подать на вывод напряжение, то потенциалы анода и катода сравняются, и светодиод погаснет. Если же на вывод выдать логический "0", то к светодиоду будет приложено напряжение, и он зажжется. Таким образом пара строк 4 и 5 выключает светодиод LED2 при отпущенной кнопке.

6 строка. Противоположна по смыслу 4-й. Командой sbis проверяется наличие логической "1" на входе РВ2, то есть проверяется, отпущена ли кнопка. Если кнопка отпущена, то следующая строка пропускается, и происходит переход к следующей за ней. Но поскольку 7-я строка последняя, то происходит переход ко 2-й строке. Если же кнопка нажата, то выполняется строка 7.

7 строка. Противоположна 5-й. Командой cbi бит 4 регистра PORTB сбрасывается в "0", тем самым включая светодиод LED2. Таким образом, пара строк 6 и 7 включает светодиод LED2 при нажатой кнопке SB1.

Как видите, ничего особо сложного мы не совершили. Используя знание всего 3-х регистров и 4-х команд, мы написали нашу первую программу. Что же делать с ней дальше. Если вы еще не забыли, мы продолжаем писать алгоритм создания программы.

5. Написав текст программы в окне редактора, выбираем пункт меню "File", и в открывшемся списке нажимаем "Save As...". В окне сохранения файла выбираем созданную нами папку step2 и указываем имя файла "main", поскольку именно это имя было задано нами в файле "build.bat"

После сохранения окно программы должно иметь следующий вид:

6. Создаем hex-файл. Для этого нажимаем кнопку "II" на панели инструментов. Должно появится окно следующего вида:

Оно извещает нас о том, что ассемблирование прошло без ошибок и создан файл прошивки "main.hex" объемом 6 слов, то есть 12 байт. Замечу, что аналогичная программа на языке Си имела бы как минимум в 5 раз больший объем.

7. Зайдя в папку step2, обнаруживаем в ней пополнение в виде вновь созданного файла main.hex, который теперь может быть зашит в контроллер любым программатором, что и необходимо выполнить, дабы увидеть результаты работы написанной нами программы. После прошивки контроллера, если схема собрана правильно, все должно работать по разработанному нами алгоритму: при отпущенных кнопках светодиод LED2 должен быть погашен, а во время удержания нажатой кнопки SB1 - зажжен.

До следующего шага предлагаю сделать такие задания:

1. Добавить к программе обработку нажатия кнопки SB2 с противоположным алгоритмом: при отпущенной кнопке SB2 светодиод LED1 должен быть зажжен, а при нажатой - погашен.

2. Написать программу управления светодиодом LED2 при помощи обеих кнопок. При нажатии на кнопку SB1 светодиод должен зажигаться и оставаться включенным до тех пор, пока не будет нажата кнопка SB2, которая выключает его до следующего нажатия SB1.

Мариуполец, старший преподаватель электроники ПГТУ, радиолюбитель, Сергей Петрович Сокол US9IFW, начальник университетской коллективки US8IWB. Он является не только специалистом по микроконтроллерам, но и пропаганидистом современных знаний по ним. Достаточно полистать журнал "Радио", в котором его статьи печатаются с завидным постоянством. Представляем материалы с его сайта.

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

В качестве базового контроллера для экспериментов я выбрал наиболее доступный и дешевый на данный момент ATtiny13. Он имеет всего восемь выводов и 1 кБайт Flash-памяти, но для изучения базовых операций его будет более чем достаточно.

Схема для экспериментов представлена на рисунке 1.


Рисунок 1 - Схема платы для экспериментов

Центральным элементом ее является, как уже было сказано, контроллер DD1 типа ATtiny13. Питание схемы и программирование контроллера осуществляется при помощи разъема XS1. Распиновка его зависит от применяемого программатора. В качестве такого программатора рекомендую использовать USBasp, описанный мною в предыдущих статьях.

Конденсаторы С1 и С2 - для фильтрации помех по питанию. Кнопки SB1 и SB2 - любые без фиксации. Резисторы R2-R5 - токоограничительные. Могут быть выбраны из диапазона 220-390 Ом. Резистор R1 - переменный сопротивлением 1-20 кОм. Он служит для изменения напряжения, подаваемого на вход АЦП контроллера. Светодиоды LED1 и LED2 любого цвета и диаметра. Все элементы подключены таким образом, чтобы задействовать альтернативные функции контроллера, поэтому нежелательно вносить изменения в схему.

Теперь, что касается программной части. Многие рекомендуют для программирования на ассемблере использовать пакет "AVR Studio", выпускаемый самой фирмой Atmel, и распространяемый бесплатно. Рекомендации эти обоснованы: подсветка ключевых слов, справка, отладочный механизм - все эти приятные мелочи имеются в наличии. В качестве альтернативы я использую максимально облегченный вариант, который предлагает Ю. Ревич в своей книге "Практическое программирование микроконтроллеров Atmel AVR на языке ассемблера" (СПб.: БХВ-Петербург, 2008 - 384 с.).

Не вдаваясь в подробности, что откуда взялось, выкладываю сюда архив с необходимым ПО. Скачать его можно . Объем его крайне невелик, хотя в век широкополосных каналов интернета это практически не имеет значения. Архив можно распаковать в любую папку.
Итак, что же найдет любопытный пользователь, заглянув в полученную папку "asm"? Рассмотрим все по-порядку. В папке "Appnotes" располагаются файлы двух типов: с расширениями "inc" и "asm". Файлы "inc" содержат в себе информацию о контроллерах Atmel, с которыми может работать используемый здесь транслятор языка ассемблер. Имя файла совпадает с названием контроллера. Например, для нашей платы понадобится "tn13def.inc", но об этом позже. Файлы "asm" содержат примеры кодов, написанных инженерами фирмы Atmel, и выполняющих различные типовые операции. Для разнообразия их можно просмотреть, но использовать будем только самостоятельно разработанные алгоритмы (иначе, какие ж мы программисты?).

В папке "asmedit" находится редактор для набора программ на ассемблере. В принципе, для этих целей можно использовать произвольный текстовый редактор, даже обычный блокнот, но предлагаемый здесь удобнее, поскольку имеет подсветку некоторых команд, а также кнопки, позволяющие производить ассемблирование прямо из окна программы.
Файл avrasm32.exe является транслятором языка ассемблера. Именно он преобразует написанную нами программу в hex-файл, который может быть зашит непосредственно в микроконтроллер.

Файл build.bat представляет собой пакетный файл, который указывает опции ассемблирования для программы avrasm32.exe. Рассмотрим его структуру подробнее. В приведенном примере, скачанном читателем с сайта, в нем написан следующий текст:

"F:\Prog\AVR\asm\avrasm32 -fI %F:\Prog\AVR\asm\Nokia3410\main.asm
pause"

В принципе, структура его понятна интуитивно, но на всякий случай поведаю поподробней. Итак, сначала указывается путь, по которому находится файл avrasm32. У меня он расположен по пути "F:\Prog\AVR\asm\". Вы же указывайте ту папку, куда распаковали архив. Далее идут опции ассемблирования "-fI". Их менять не стоит. В конце после знака "%" указывается исходный файл с расширением asm и полный путь к нему.

Вторая строка представляет собой команду pause, которая дает возможность просмотреть результат создания hex-файла, и закрыть окно командной строки по нажатию любой клавиши. О том, как это все выглядит на практике, будет рассказано и показано чуть позже.

А пока необходимо сделать единственную настройку в программе asm_ed.
Заходим в папку asmedit, запускаем файл Asm_Ed.exe. Появляется окно следующего вида:

Как видно на скриншоте, большую часть окна занимает поле для ввода текста, здесь мы и будем набирать свою программу. Сейчас же нам нужен пункт главного меню Service. В выпадающем списке выбираем "Properties...". Открывается окно следующего вида:

Переходим к вкладке "Project" и меняем во второй сверху строке путь к файлу build.bat, не трогая остального:

Все! Можем нажимать кнопочку "ОК" и радоваться - программа готова к работе. Теперь для запуска процесса асемблирования необходимо будет нажать всего лишь кнопку "II" на панели инструментов.

Итак, соберите приведенную на рисунке 1 схему, скачайте и настройте ПО, сделайте программатор, если у вас еще нет столь полезной вещи, и приступим к дальнейшей работе. Но это будет уже совсем другая история...

Что нужно для того, чтобы стать профессиональным разработчиком программ для микроконтроллеров и выйти на такой уровень мастерства, который позволит с лёгкостью найти и устроиться на работу с высокой зарплатой (средняя зарплата программиста микроконтроллеров по России на начало 2015 года составляет
80 000 рублей).

ADD

Синтаксис: ADD reg1, reg2 Эта команда складывает содержимое регистров reg1 и reg2, сохраняя результат в регистре reg1. Изменяет состояние флагов H, S, V, N, Z, C.

AND

Синтаксис: AND reg1, reg2 Эта команда выполняет операцию «Логическое И» между регистрами reg1 и reg2, сохраняя результат в регистре reg1. Изменяет состояние флагов S, V, N, Z.

ANDI

Синтаксис: ANDI hreg, number Эта команда выполняет операцию «Логическое И» между содержимым старшего регистра hreg и константой number (0…255), сохраняя результат в регистре. Изменяет состояние флагов S, V, N, Z.

BRBC

Синтаксис: BRBC bit, label Эта команда проверяет состояние бита регистра SREG ($3F) и переходит к метке label, если бит сброшен. Метка должна находиться в пределах 63 команд от команды brbc.

BRBS

Синтаксис: BRBS bit, label Эта команда проверяет состояние бита регистра SREG ($3F) и переходит к метке label, если бит установлен. Метка должна находиться в пределах 63 команд от команды brbs.

BRCC

Синтаксис: BRCC bit, label Эта команда проверяет флаг переноса (С) и переходит к метке label, если он сброшен.

BRCS

Синтаксис: BRCS bit, label Эта команда проверяет флаг переноса (С) и переходит к метке label, если он установлен.

BREQ

Синтаксис: BREQ bit, label Эта команда проверяет флаг нуля (Z) и переходит к метке label, если он установлен.

BRNE

Синтаксис: BRNE bit, label Эта команда проверяет флаг нуля (Z) и переходит к метке label, если он сброшен.

CBI

Синтаксис: CBI ioreg, bit Эта команда сбрасывает в 0 бит регистра ввода-вывода ioreg ($00…$1F). Номер бита определяет операнд bit.

CLR

Синтаксис: CLR reg Эта команда сбрасывает все биты регистра reg в 0. Изменяет состояние флагов S, V, N, Z.

CP

Синтаксис: CP reg1, reg2 Эта команда сравнивает содержимое регистров reg1 и reg2 путем вычитания reg2 из reg1. Содержимое регистров не изменяется. Изменяет состояние флагов H, S, V, N, Z, C.

CPI

Синтаксис: CPI hreg, number Эта команда сравнивает содержимое регистра hreg с константой number путем вычитания константы из регистра. Содержимое регистров не изменяется. Изменяет состояние флагов H, S, V, N, Z, C. Команда работает только с регистрами R16…R31.

DEC

Синтаксис: DEC reg Эта команда уменьшает на единицу содержимое регистра reg, записывая результат обратно в регистр. Изменяет состояние флагов S, V, N, Z.

IN

Синтаксис: IN reg, ioreg Эта команда пересылает содержимое регистра ввода-вывода ioreg в РОН reg.

INC

Синтаксис: INC reg Эта команда увеличивает на единицу содержимое регистра reg, записывая результат обратно в регистр. Изменяет состояние флагов S, V, N, Z.

LD

Синтаксис: LD reg, longreg Эта команда загружает один байт из памяти данных (адрес ячейки памяти содержится в регистре longer) в регистр reg (для модели 1200).

LDI

Синтаксис: LDI hreg, number Эта команда загружает непосредственное значение number в старший регистр hreg (команда может работать только с регистрами R16…R31). Число number должно находиться в пределах 0…255.

LSR

Синтаксис: LSR reg Эта команда выполняет логический сдвиг вправо содержимого регистра reg. При этом 0-й бит копируется в флаг C, 7-й бит сбрасывается в 0. Изменяет состояние флагов S, V, N, Z, C.

ORI

Синтаксис: ORI hreg, number Эта команда выполняет операцию «Логическое ИЛИ» между содержимым старшего регистра hreg и константой number (0…255), сохраняя результат в регистре. Изменяет состояние флагов S, V, N, Z.

OUT

Синтаксис: OUT ioreg, reg Эта команда пересылает содержимое регистра общего назначения reg в регистр ввода-вывода ioreg.

RCALL

Синтаксис: RCALL label Эта команда вызывает подпрограмму, обозначенную меткой label, которая должна находиться в пределах 2048 команд от команды rcall (относительный вызов).

RET

Синтаксис: RET Эта команда выполняет возврат из подпрограммы, переходя на команду, которая следует за исходной командой call.

RETI

Синтаксис: RETI Эта команда выполняет возврат из подпрограммы и устанавливает флаг общего разрешения прерываний.

RJMP

Синтаксис: RJMP label Относительный переход. Выполняет переход к участку программы, обозначенному меткой label, которая должна находиться в пределах 2048 от команды RJMP.

SBI

Синтаксис: SBI ioreg, bit Эта команда устанавливает в 1 бит регистра ввода-вывода ioreg ($00…$1F). Номер бита определяет операнд bit.

SBIC

Синтаксис: SBIC ioreg, bit Эта команда проверяет бит регистра ввода-вывода ioreg ($00…$1F) и пропускает следующую команду, если этот бит сброшен. Номер бита определяет операнд bit.

SBIS

Синтаксис: SBIS ioreg, bit Эта команда проверяет бит регистра ввода-вывода ioreg ($00…$1F) и пропускает следующую команду, если этот бит установлен. Номер бита определяет операнд bit.

SEI

Синтаксис: SEI Эта команда устанавливает флаг общего разрешения прерываний.

SER

Синтаксис: SER reg Эта команда устанавливает все биты регистра reg в 1. Изменяет состояние флагов S, V, N, Z. Команда может работать только с регистрами R16…R31.

ST

Синтаксис: ST reg, longreg Для модели 1200 эта команда сохраняет содержимое регистра reg в памяти данных (адрес ячейки памяти содержится в регистре longer), т.е. косвенно пересылает содержимое РОН reg по адресу, хранящемуся в регистре longer.

SUBI

Синтаксис: SUBI hreg, number Вычитает из старшего регистра hreg константу number. Результат сохраняется в этом же регистре. Изменяет состояние флагов H, S, V, N, Z, C. Команда может работать только с регистрами R16…R31.

Всем добрый вечер! Веду свою трансляцию из уютного мира, который называется «ассемблер». Сразу поясню что тема касается микроконтроллеров AVR - и я пока ещё не знаю, пригодится ли этот пост тем, кто хочет использовать ассемблер для любой другой задачи. Дело в том, что я буквально несколько дней назад начал учить ассемблер с нуля - нужно сделать одно устройство - и я решил сделать в нём всё самостоятельно. Так вот - в один прекрасный день понял, что учить ассемблер абсолютно бесполезно! Ассемблер можно только понять! То есть всем тем, кто хочет программировать на ассемблере я настоятельно рекомендую детально вникнуть в то, каким образом ФИЗИЧЕСКИ работает микроконтроллер, а затем уже изучать тонкости команд.
Так вот, я пожалуй начну небольшой цикл статей, в которых буду с самого начала рассказывать как именно я понял те или иные вещи в программировании на ассемблере - думаю для тех, кто вообще не понимает что такое асм я буду как раз таким «переводчиком» с языка тех, кто в этом деле очень хорошо шарит.

Сразу скажу, что я более-менее вкурил эту тему с подачи DIHALT - поэтому эти статейки будут являться неким переводом с супер-пупер-ассемблерно-микроконтроллерного языка на язык понятный большинству людей. Ну а гуру надеюсь будут меня поправлять по ходу пьесы и если вдруг я что то объясню неправильно - то они поправят меня.
Итак первые выводы об ассемблере, которые я сделал пару дней назад, меня потрясли до глубины души - и я просидел за статьями DI HALT"а с 11 вечера до 5 утра - после чего лёг спать довольным и счастливым. Я понял суть программирования на ассемблере для микроконтроллеров.
Как же это объяснить ещё проще? Думаю нужно начать с самой сути.
***
Изначально не будем вдаваться в технические подробности (о них мы поговорим в следующей статье) - просто представьте, что есть 3 персонажа :
1. Микроконтроллер - это англичанин Стив, который приехал к русскому. Он идеально знает английский язык, но по-русски он вообще не понимает - ни единого слова. Только английский. Он проиграл в споре и обязался делать бесприкословно всё то, о чём его попросит русский.
2. Ассемблер - это переводчик Вася у которого мама англичанка а папа русский. Он знает идеально и английский и русский язык.
3.Мы - это русский, к которому приехал англичанин. Ну то есть мы это мы=) При этом мы идеально знаем русский язык и (!!!) чуть-чуть английский - самую малость, со словариком.
***
Представьте такую ситуацию - англичанин сидит у Вас в комнате на стуле. А Вы сидите себе за компом и читаете этот пост, как вдруг у Вас внезапно открылась форточка! Вот ведь незадача! Ветер дует, занавеска превратилась в парус… Было бы неплохо закрыть! Но вот ведь как лень вставать со стула, снимать ноги с системника, запихивать их в тапочки, отставлять кружку с кофе(пивом) и идти бороться со стихией. И тут Вы внезапно осознаёте, что у нас то в комнате есть проспоривший англичанин, которого самое время погонять! И вы ему так мило говорите «Дружище! Закрой форточку пожалуйста, а потом можешь опять присесть на стул!» а он сидит, смотрит на вас с недоумением и ничего не делает! Можно конечно по щам надавать - но он же тогда всё равно вас не поймёт! Тогда Вы звоните своему другу-переводчику Василию - он приходит, и садится рядом с англичанином на стул. И вы говорите - Переведи: «Стив, пойди и закрой форточку, а потом обратно сядь на стул!» Переводчик переводит на английский - англичанин понимает и идёт закрывает форточку, а затем приходит и садится на стул.
В этом моменте нужно просто понять роль ассемблера в этой цепочке «Мы-Ассемблер-Контроллер»
То есть как бы что такое ассемблер все поняли? Тогда читаем дальше.
***

Так вот, представляем такую ситуацию. Васе говоришь - «Слушай, ну короче такое дело - я калькулятор дома забыл, раздели 56983 на 2 и скажи Стиву, чтобы он столько раз отжался на кулаках» и Вася на калькуляторе считает и говорит Стиву по-английски " Отожмись на кулаках 28491 раз" Это называется «ДИРЕКТИВА» - другими словами директива это задание для Васи, результат выполнения которой это действие Стива.

Есть другая ситуация - Вы говорите Васе «Скажи Стиву, чтобы он отжался 28491 раз» и Вася просто переводит Ваши слова на английский. Это называется ОПЕРАТОР

Всё просто - есть директива и есть оператор. Оператор - это Ваше прямое указание что делать Стиву - Вася тут только переводит Ваше требование на инглиш. А Директива - это задание для самого Васи - и Вася сначала делает то, что Вы ему сказали, а потом уже в зависимости от результата говорит Стиву что-либо.

Теперь мы будем мучать англичанина регулярно! Но предварительно нужно получше познакомиться с нашим переводчиком Васей. Нужно знать следующее - Вася всегда Вас слушается беспрекословно - что ему сказали, то он и делает. Васин калькулятор не имеет десятичных знаков - если вы глянете пример с отжиманиями то 56983 \ 2 = 28491.5 - но у Васи всё после запятой обрубается - и он видит только целое число - причём неважно там будет 28491.000001 или там будет 28491.9999999 - для Васи это один фиг будет 28491 в обоих случаях. Ничего не округляется. Ещё важная информация про Васю. Вася жесток - ему пофиг на то, что Стив затрахается отжиматься двадцать восемь тысяч раз. Ему сказали - Вася перевёл. Причём не только перевёл - но и заставил сделать то, что Вы попросили. Так что если Стив помрёт на двадцать три тысячи пятьсот тринадцатом отжимании - то это будет исключительно Ваша вина.

Собственно это пока что всё. В следующем посте будем копать глубже - пока же просто достаточно понять это. Просто представить эту ситуацию и понять что к чему, кто исполняет какую роль и чем директива отличается от оператора.
А дальше мы постараемся называть всё своими именами и примерно прикинуть как же ассемблер работает с микроконтроллером по взрослому.

Название: Практическое программирование микроконтроллеров Atmel AVR на языке ассемблера 2 издание

Издательство: «БХВ-Петербург»

Год издания: 2011

Страниц: 354

Язык: Русский

Формат: DjVu

Размер: 12,2 Мб

Наложены принципы функционирования, особенности архитектуры и приемы программирования микроконтроллеров Atmel AVR.

Приведены готовые рецепты для программирования основных функций современной микроэлектронной аппаратуры: от реакции на нажатие кнопки или построения динамической индикации до сложных протоколов записи данных во внешнюю память или особенностей подключения часов реального времени. Особое внимание уделяется обмену данными микроэлектронных устройств с персональным компьютером, приводятся примеры программ. В книге учтены особенности современных моделей AVR и сопутствующих микросхем последних лет выпуска.
Приложение содержит основные параметры микроконтроллеров AVR, перечень команд и тексты Приложения содержат основные параметры микроконтроллеров AVR, перечень команд и тексты программ для них, а также список используемых терминов и аббревиатур.
Для учащихся, инженерно-технических работников и радиолюбителей

7. Микроконтроллеры, их возникновение и применение
8. Предыстория микроконтроллеров
10. Электроника в греческом стиле
12. Почему AVR?
14. Что дальше?
17.ЧАСТЬ L ОБЩИЕ ПРИНЦИПЫ УСТРОЙСТВА И ФУНКЦИОНИРОВАНИЯ ATMEL AVR
19. Глава 1. Обзор микроконтроллеров Atmel AVR
21. Семейства AVR
23. Особенности практического использования МК AVR
23. О потреблении
25. Некоторые особенности применения AVR в схемах
27. Глава 2. Общее устройство, организация памяти, тактирование, сброс
27. Память программ
29. Память данных (ОЗУ, SRAM)
31. Энергонезависимая память данных (EEPROM)
32. Способы тактирования
34. Сброс
37. Глава 3. Знакомство с периферийными устройствами
38. Порты ввода-вывода
39. Таймеры-счетчики
41. Аналогово-цифровой преобразователь
42. Последовательные порты
43. UART
46. Интерфейс SPI
50. Интерфейс TWI (I2С)
50. Универсальный последовательный интерфейс USI
53. Глава 4. Прерывания и режимы энергосбережения
53. Прерывания
57. Разновидности прерываний
58. Режимы энергосбережения
61. ЧАСТЬ II. ПРОГРАММИРОВАНИЕ МИКРОКОНТРОЛЛЕРОВ ATMELAVR
63. Глава 5. Общие принципы программирования МК семейства AVR
63. Ассемблер или С?
67. Способы и средства программирования AVR
67. Редактор кода
68. Об AVR Studio
70. Обустройство ассемблера
71. Программаторы
75. О hex-файлах
78. Команды, инструкции и нотация AVR-ассемблера
79. Числа и выражения
80. Директивы и функции
84. Общая структура АVR-программы
85. Обработка прерываний
89. RESET
90. Простейшая программа
92. Задержка
94. Программа счетчика
96. Использование прерываний
97. Задержка по таймеру
98. Программа счетчика с использованием прерываний
101. О конфигурационных битах
105. Глава 6, Система команд AVR
105. Команды передачи управления и регистр SREG
111. Команды проверки-пропуска
113. Команды логических операций
114. Команды сдвига и операции с битами
116. Команды арифметических операций
118. Команды пересылки данных
122. Команды управления системой
123. Выполнение типовых процедур на ассемблере
125. О стеке, локальных и глобальных переменных
127. Глава 7. Арифметические операции
128. Стандартные арифметические операции
129. Умножение многоразрядных чисел
131. Деление многоразрядных чисел
134. Операции с дробными числами
136. Генератор случайных чисел
138. Операции с числами в формате BCD
143. Отрицательные числа в МК
147. Глава 8. Программирование таймеров
147. 8- и 16-разрядные таймеры
149. Формирование заданного значения частоты
153. Отсчет времени
158. Точная коррекция времени
160. Частотомер и периодомер
160. Частотомер
164. Периодомер
167. Управление динамической индикацией
168. LED-индикаторы и их подключение
171. Программирование динамической индикации
174. Таймеры в режиме PWM
179. Глава 9. Использование EEPROM
179. Еще раз о сохранности данных в EEPROM
181. Запись и чтение EEPROM
183. Хранение констант в EEPROM
187. Глава 10. Аналоговый компаратор и АЦП
187. Аналого-цифровые операции и их погрешности
190. Работа с аналоговым компаратором
193. Интегрирующий АЦП на компараторе
194. Принцип работы и расчетные формулы
198. Программа интегрирующего АЦП
201. Встроенный АЦП
204. Пример использования АЦП
206. Программа
215. Глава 11. Программирование SPI
215. Основные операции через SPI
216. Аппаратный вариант
218. Программный вариант
219. О разновидностях энергонезависимой памяти
221. Запись и чтение flash-памяти через SP!
224. Программа обмена с памятью 45DB011В по SPI
225. Запись и чтение flash-карт
225. Подключение карт ММС
228. Подача команд и инициализация ММС
232. Запись и чтение ММС
237. Глава 12. Интерфейс TW1 (I2С) и его практическое использование
237. Базовый протокол 1 2 С
240. Программная эмуляция протокола I 2 С
241. Запись данных во внешнюю энергонезависимую память
241. Режимы обмена с памятью АТ24
243. Программа
247. Часы с интерфейсом I 2 С
255. Запись данных
259. Чтение данных
261. Глава 13. Программирование UART/USART
262. Инициализация UART
263. Передача и прием данных
266. Пример установки часов DS1307 с помощью UART
271. Приемы защиты от сбоев при коммуникации
271. Проверка на четность
273. Как организовать корректный обмен
274. Дополнительные возможности USART
276. Реализация интерфейсов RS-232 и RS-485
280. Преобразователи уровня для RS-232
283. RS-485
285. Глава 14. Режимы энергосбережения и сторожевой таймер
286. Программирование режима энергосбережения
287. Пример прибора с батарейным питанием
289. Доработка программы
293. Использование сторожевого таймера
299. ПРИЛОЖЕНИЯ
301. Приложение 1. Основные параметры микроконтроллеров Atmel AVR
309. Приложение 2. Команды Atmel AVR
310. Арифметические и логические команды
311. Команды операций с битами
312. Команды сравнения
313. Команды передачи управления
313. Команды безусловного перехода и вызова подпрограмм
314. Команды проверки-пропуска и команды условного перехода
315. Команды переноса данных
316. Команды управления системой
317. Приложение 3. Тексты программ
317. Демонстрационная программа обмена данными с flash-памятью 45DB011В по интерфейсу SPI
321. Процедуры обмена по интерфейсу I2С
329. Приложение 4. Обмен данными с персональным компьютером и отладка программ через UART
329. Работа с СОМ-портом в Delphi
335. Установка линии RTS в DOS и Windows
337. Программа СОМ2000
339. Отладка программ с помощью эмулятора терминала
341. Приложение 5. Словарь часто встречающихся аббревиатур и терминов
347. Литература
349. Предметный указатель

 

 

Это интересно: