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

Рисунок 1. Схема тестового устройства
Логику работы устройства я сделаю следующей: при включении устройства светодиод будет моргать с периодом в одну секунду. Если замкнуть контакты выключателя, светодиод начнет моргать с периодом вдвое больше. При размыкании контактов выключателя период моргания светодиода вновь станет равным одной секунде.
Реализацию устройства начнем с написания прошивки. В качестве среды разработки будем использовать AVR Studio 4. Программа бесплатно предоставляется самой Atmel. В установке программы нет ничего необычного. Скачать можно здесь. Кроме самой среды разработки нам понадобится компилятор языка C для микроконтроллеров AVR. Называется WinAVR. Скачать можно здесь.
Итак, начнем. Запускаем AVR Studio 4. В меню выбираем Project->Project Wizard. Откроется диалог создания нового или открытия существующего проекта. Нажимаем на кнопку New Project. Теперь нам предлагают выбрать тип проекта. Так как мы будем писать прошивку на языке C, выбираем тип проекта AVR GCC. Здесь же выбираем имя проекта, имя файла, содержащего код (надо поставить галочку "Create initial file", если не стоит) и путь, где проект будет сохранен. Если установить флаг "Create folder", в выбранном каталоге будет создан подкаталог с именем, совпадающим с именем проекта. Пример введенных данных представлен на рисунке 2.

Рисунок 2. Создание нового проекта. Шаг первый. Выбор названия и путей
Вторым этапом мастер предлагает выбрать отладчик. Если у Вас нет аппаратного отладчика, выбирайте AVR Simulator. Это эмулятор микроконтроллера, позволяющий отладить Вашу прошивку, отложив сборку устройства. Кроме того, необходимо выбрать тип микроконтроллера, под который пишется прошивка. Пример введенных данных на этом этапе создания проекта представлен на рисунке 3.

Рисунок 3. Создание нового проекта. Шаг второй. Выбор отладчика
Нажимаем кнопку Finish. Проект создан. Осталось проверить некоторые параметры и можно писать прошивку. Необходимо учитывать, что компилятор GCC является оптимизирующим. То есть, компилятор делает все, чтобы ваша прошивка занимала как можно меньше места и работала как можно быстрее. По умолчанию в свойствах проекта установлена полная оптимизация. Все бы хорошо, но вот отлаживать такую прошивку весьма проблематично. Поэтому я рекомендую создать две конфигурации сборки прошивки. Для этого выполните следующие действия:

Рисунок 4. Результат редактирования конфигураций проектов
Поясню, для чего нужно было создавать две конфигурации и как ими пользоваться. Дело в том, что при отладке прошивки, собранной со включенной оптимизацией, отладчик ведет себя не совсем так, как нам бы хотелось. В связи с этим во время разработки и отладки прошивки надо установить конфигурацию Debug (без оптимизации).Когда же прошивка отлажена и готова для использования непосредственно в устройстве, выбираем конфигурацию Release и собираем прошивку заново.
Обратите внимание: прошивка, собранная в конфигурации Debug после компиляции будет находится в подкаталоге "Debug" каталога вашего проекта. Если же прошивка собиралась в конфигурации Release, то после компиляции прошивка будет находится в подкаталоге "Release" каталога вашего проекта. Не перепутайте их.
Приступим к написанию прошивки. Код программы представлен в листинге 1.
Листинг 1. Код программы
#include <avr/io.h> // Хотим использовать порты ввода/вывода
#include <util/delay.h> // Хотим использовать функции задержек
int main()
{
// Регистр DDRB отвечает за направление
// линий порта. Если какой либо бит равен
// лог. 1, соответствующая линия порта
// используется для вывода данных. Иначе для ввода.
// Мы указываем, что собираемся использовать
// линию 0 для вывода данных (устанавливаем бит 0
// в лог. 1).
DDRB = 0x01;
// Начинаем вечный цикл.
for (;;)
{
// Инициализируем переменную, характеризующую
// время задержки в миллисекундах для замкнутых контактов.
int SleepTime = 500;
// Если бит 1 порта B установлен в лог. 1, (контакты разомкнуты)
// увеличиваем вдвое время задержки.
if (PINB & _BV(PB1))
SleepTime = SleepTime * 2;
// Устанавливаем бит 0 порта B в лог. 1.
// (зажигаем светодиод).
PORTB |= _BV(PB0);
// Ждем указанное время.
_delay_ms(SleepTime);
// Устанавливаем бит 0 порта B в лог. 0.
// (гасим светодиод).
PORTB &= ~_BV(PB0);
// Ждем указанное время.
_delay_ms(SleepTime);
}
return 0;
}
Для сборки прошивки нажимаем клавишу F7 или выбираем пункт меню Buid->Build. Программа должна написать в окне Build о том, что сборка прошла успешно. Теперь можно запустить отладку прошивки. Для этого нажмите комбинацию клавиш Ctrl+Alt+Shift+F5 или выберите пункт меню Debug->Start debugging. Выполнение отладки сразу же остановится на первой комманде вашей программы. Ниже перечислены основные команды, которые могут понадобиться при отладке.
| Горячая клавиша | Команда | Описание команды |
|---|---|---|
| Ctrl+Alt+Shift+F5 | Start Debugging | Запуск процесса отладки |
| Ctrl+Shift+F5 | Stop Debugging | Прерывание процесса отладки |
| F10 | Step Over | Сделать шаг без захода в функцию |
| F11 | Step Into | Сделать шаг с заходом в функцию |
| Shift+F11 | Step Out | Выполнить программу до выхода из текущей функции |
| Ctrl+F10 | Run to Cursor | Выполнить программу до той строки кода, где установлен курсор |
По остальным командам можно найти информацию во встроенной в программу справочной системе. Выполняя программу по шагам вы видите в окне I/O View состояние всех регистров. В том числе и состояние порта B, с которым мы и работаем. Состояние выключателя можно сымитировать путем занесения вручную в порт B нужного значения. Указать значение на конкретной линии порта можно мышкой, выделив в окне I/O View нужный порт и щелкнув по нужному квадрату, символизирующему бит порта (смотри рисунок 5, эти квадраты подчеркнуты волнистой линией сиреневого цвета).

Рисунок 5. Программа AVR Studio в режиме отладки
Еще одно важное замечание. Эмулятор работает намного медленнее реального микроконтроллера. Поэтому на время отладки я рекомендую сильно занизить время задержки. Например, до одной миллисекунды. Или же вместо функции _delay_ms на время отладки использовать функцию _delay_us. В этом случае компилятор будет рассматривать переданное вами в функцию значение не как миллисекунды, а как микросекунды. Только перед сборкой финальной версии прошивки не забудьте вернуть все на место. Пользователи, изощренные в программировании, могут разрулить все это директивами предкомпилятора, сделав, например, так, чтобы в отладочной версии прошивки подставлялись функции _delay_us, а в финальной _delay_ms.
Пришло время собрать устройство. Я его собрал буквально на коленке за пять минут. Собирал на макетной плате. Результат моего "творчества" представлен на рисунке 6. Весьма неопрятно, но для эксперимента этого хватило.

Рисунок 6. Готовое устройство
Прошивку заливаем в микроконтроллер любым программатором. Схема простейшего программатора представлена здесь. Я использовал более сложный программатор с внутрисхемным отладчиком через интерфейс JTAG. Если схема собрана правильно и прошивка залита корректно (не пренебрегайте верификацией), все должно сразу же заработать.
Удачи Вам в освоении микроконтроллеров.
С уважением, Сергей.