Оглавление:

Учебник по ассемблеру AVR, 1: 5 шагов
Учебник по ассемблеру AVR, 1: 5 шагов

Видео: Учебник по ассемблеру AVR, 1: 5 шагов

Видео: Учебник по ассемблеру AVR, 1: 5 шагов
Видео: AVR Ассемблер. Урок 1. Вводный. AVR Assembler. Lesson 1. Promo. 2024, Июль
Anonim
Учебное пособие по AVR Assembler 1
Учебное пособие по AVR Assembler 1

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

Я использую Arch linux и работаю над установкой atmega328p-pu на макетной плате. Вы можете сделать это так же, как я, или просто подключить Arduino к своему компьютеру и таким образом работать с микроконтроллером.

Мы будем писать программы для 328p, подобные той, которая есть в большинстве Arduino, но вы должны отметить, что эти же программы и методы будут работать с любым из микроконтроллеров Atmel, а позже (если есть интерес) мы будем работать с некоторыми из другие тоже. Подробную информацию о микроконтроллере можно найти в таблицах данных Atmel и в Руководстве по набору инструкций. Я прикрепляю их к этому наставлению.

Вот что вам понадобится:

1. Макет

2. Arduino или просто микроконтроллер.

3. Компьютер под управлением Linux.

4. Ассемблер avra, использующий git: git clone https://github.com/Ro5bert/avra.git, или если вы используете ubuntu или систему на основе debian, просто введите «sudo apt install avra», и вы получите как ассемблер avr и аврдуде. ОДНАКО, если вы получите последнюю версию с помощью github, вы также получите все необходимые включаемые файлы, другими словами, в нем уже есть файлы m328Pdef.inc и tn85def.inc.

5. avrdude

Полный набор моих руководств по ассемблеру AVR можно найти здесь:

Шаг 1. Создайте доску для тестирования

Создайте испытательную доску
Создайте испытательную доску

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

Для тех из вас, кто согласен, вы можете вытащить микроконтроллер из вашего Arduino, а затем начать с создания «макета Arduino», следуя инструкциям здесь:

На картинке я показываю свою установку, которая состоит из двух автономных Atmega328p на большой макетной плате (я хочу, чтобы предыдущее руководство было подключено и загружено на один микроконтроллер во время работы над следующим). У меня есть источник питания, настроенный так, чтобы на самой верхней шине было 9 В, а на всех остальных - 5 В от регулятора напряжения. Я также использую коммутационную плату FT232R для программирования микросхем. Я купил их и сам поставил на них загрузчики, но если вы просто вытащили один из Arduino, то это уже нормально.

Обратите внимание, что если вы пытаетесь это сделать с ATtiny85, вы можете просто получить Sparkfun Tiny Programmer здесь: https://www.sparkfun.com/products/11801#, а затем просто подключить его к USB-порту на вашем компьютере. Сначала вам нужно будет установить загрузчик на Attiny85, и самый простой способ - просто использовать Arduino IDE. Однако вам нужно будет щелкнуть файл и настройки, а затем добавить этот URL-адрес новой доски: https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json, который будет позволит вам установить загрузчик (если ваш ATtiny85 еще не поставлялся с ним).

Шаг 2: Установите Ассемблер и Avrdude

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

После того, как вы установили avra, вы заметите, что есть подкаталог, который идет с ним, который называется «sources», и внутри этого каталога находится куча включаемых файлов. Это все микроконтроллеры, которые можно программировать с помощью avra. Вы сразу заметите, что для 328p, который мы здесь используем, нет файла. Я прикрепил один. Файл должен называться m328Pdef.inc, и вы должны поместить его в каталог include или в любое другое место, которое вам нравится. Мы будем включать его в наши программы на ассемблере. Все это дает каждому из регистров в микроконтроллере имена из таблицы данных, так что нам не нужно использовать их шестнадцатеричные имена. Вышеупомянутый включаемый файл содержит «директивы pragma», поскольку он был разработан для программирования на C и C ++. Если вам надоело видеть, как ассемблер выкладывает жалобы на «игнорирование директивы pragma», просто зайдите в файл и удалите или закомментируйте все строки, начинающиеся с #pragma

Хорошо, теперь, когда у вас готов микроконтроллер, готов ассемблер и готов программист, мы можем написать нашу первую программу.

Примечание. Если вы используете ATtiny85 вместо ATmega328P, вам понадобится другой включаемый файл с именем tn85def.inc. Я также прикреплю его (обратите внимание, что мне пришлось назвать его tn85def.inc.txt, чтобы Instructables позволил мне загрузить его.) ОДНАКО, если вы получили ассемблер avra из github, то у вас уже есть оба этих файла. Поэтому рекомендую получить и скомпилировать самостоятельно: git clone

Шаг 3: Привет, мир

Цель этого первого руководства - создать стандартную первую программу, которую пишут при изучении любого нового языка или изучении любой новой электронной платформы. "Привет, мир!." В нашем случае мы просто хотим написать программу на языке ассемблера, собрать ее и загрузить в наш микроконтроллер. Программа вызовет включение светодиода. Заставить светодиод "мигать", как это происходит в обычной программе Arduino hello world, на самом деле является гораздо более сложной программой на языке ассемблера, поэтому мы пока не будем этого делать. Мы собираемся написать простейший «голый» код с минимумом ненужной ерунды.

Сначала подключите светодиод от PB5 (см. Схему выводов), который также называется Digital Out 13 на Arduino, к резистору 220 Ом, а затем к GND. Т.е.

PB5 - светодиод - R (220 Ом) - GND

Теперь напишем программу. Откройте ваш любимый текстовый редактор и создайте файл с именем "hello.asm".

; привет.asm

; включает светодиод, который подключен к PB5 (цифровой выход 13).include "./m328Pdef.inc" ldi r16, 0b00100000 out DDRB, r16 out PortB, r16 Start: rjmp Start

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

После того, как вы создали файл, вы собираете его в терминале следующим образом:

авра hello.asm

это соберет ваш код и создаст файл с именем hello.hex, который мы можем загрузить следующим образом:

avrdude -p m328p -c stk500v1 -b 57600 -P / dev / ttyUSB0 -U flash: w: hello.hex

Если вы используете макет Arduino, вам нужно будет нажать кнопку сброса на макете Arduino непосредственно перед выполнением указанной выше команды. Обратите внимание, что вам также может потребоваться добавить sudo впереди или выполнить его от имени пользователя root. Также обратите внимание, что на некоторых Arduino (например, Arduino UNO) вам, вероятно, придется изменить битрейт на -b 115200 и порт -P / dev / ttyACM0 (если вы получите сообщение от avrdude о недопустимой подписи устройства, просто добавьте - F к команде)

Если все работает, как должно, у вас загорится светодиод….. «Hello World!»

Если вы используете ATtiny85, то команда avrdude будет такой:

avrdude -p attiny85 -c usbtiny -U flash: w: hello.hex

Шаг 4: Hello.asm Построчно

Чтобы закончить это вводное руководство, мы последовательно рассмотрим программу hello.asm, чтобы увидеть, как она работает.

; привет.asm

; включает светодиод, который подключен к PB5 (цифровой выход 13)

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

.include "./m328Pdef.inc"

Эта строка указывает ассемблеру включить загруженный вами файл m328Pdef.inc. Вы можете поместить это в каталог с похожими включаемыми файлами, а затем изменить строку выше, чтобы она указывала на него там.

ldi r16, 0b00100000

ldi означает "немедленная загрузка" и сообщает ассемблеру взять рабочий регистр, в данном случае r16, и загрузить в него двоичное число, в данном случае 0b00100000. 0b впереди означает, что наше число в двоичном формате. Если бы мы хотели, мы могли бы выбрать другое основание, например шестнадцатеричное. В этом случае нашим числом было бы 0x20, что является шестнадцатеричным для 0b00100000. Или мы могли бы использовать 32, что является десятичным основанием 10 для того же числа.

Упражнение 1. Попробуйте изменить число в строке выше на шестнадцатеричное, а затем на десятичное в вашем коде и убедитесь, что оно по-прежнему работает в каждом случае.

Использовать двоичный код проще всего из-за того, как работают порты и регистры. Мы обсудим порты и регистры atmega328p более подробно в будущих руководствах, но пока я просто заявлю, что мы используем r16 как наш «рабочий регистр», что означает, что мы просто собираемся использовать его как переменную, которую мы храним. числа в. «Регистр» - это набор из 8 бит. Это означает 8 точек, которые могут быть 0 или 1 («выключено» или «включено»). Когда мы загружаем двоичное число 0b00100000 в регистр, используя указанную выше строку, мы просто сохраняем это число в регистре r16.

из DDRB, r16

Эта строка указывает компилятору скопировать содержимое регистра r16 в регистр DDRB. DDRB означает «регистр направления данных B» и устанавливает «контакты» на PortB. На схеме распиновки для 328p вы можете видеть, что есть 8 контактов с маркировкой PB0, PB1,…, PB7. Эти контакты представляют собой «биты» «PortB», и когда мы загружаем двоичное число 00100000 в регистр DDRB, мы говорим, что хотим, чтобы PB0, PB1, PB2, PB3, PB4, PB6 и PB7 были установлены как контакты INPUT, поскольку они имеют 0 в них, а PB5 установлен как вывод ВЫХОДА, поскольку мы поставили 1 в этом месте.

из PortB, r16

Теперь, когда мы зафиксировали направления контактов, мы можем установить на них напряжения. Вышеупомянутая строка копирует то же двоичное число из нашего регистра хранения r16 в PortB. Это устанавливает все контакты на 0 вольт, кроме контакта PB5 на HIGH, который составляет 5 вольт.

Упражнение 2: возьмите цифровой мультиметр, подключите черный провод к земле (GND), а затем проверьте каждый из контактов PB0 - PB7 красным проводом. Точно ли напряжение на каждом из контактов соответствует установке 0b00100000 в PortB? Если таких нет, как вы думаете, почему? (см. карту контактов)

Начинать:

rjmp Start

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

Упражнение 3. Удалите из кода две приведенные выше строки, чтобы программа упала с обрыва. Что происходит? Вы должны увидеть что-то похожее на традиционную программу «мигания», используемую Arduino в качестве «привет, мир!». Как вы думаете, почему это так? (Подумайте, что должно произойти, когда программа упадет со скалы…)

Шаг 5: Заключение

Если вы зашли так далеко, поздравляем! Теперь вы можете писать ассемблерный код, собирать его и загружать в свой микроконтроллер.

В этом руководстве вы узнали, как использовать следующие команды:

ldi hregister, number загружает число (0-255) в верхнюю половину регистра (16-31)

out ioregister, register копирует число из рабочего регистра в регистр ввода / вывода

Метка rjmp переходит к строке программы, помеченной меткой (которая не может быть дальше чем на 204 инструкции, т.е. относительный переход)

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

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

Рекомендуемые: