ATmega16А - 16PI

  • AT - сделано в Atmel
  • Mega - вид семейства. Существует еще Tiny и Xmega (новая - фаршу жуть, полный вертолет). Вообще задумывалось, что Тини это, вроде как, малобюджетное с малым количеством фарша и вообще ущербная, а Мега наоборот - все и сразу. В реальности, разница между семействами Тини и Мега по фаршу сейчас минимальная, но в Тини меньше памяти и корпуса у нее бывают с числом выводов от 6 до 20.
  • 16 - количество памяти флеша в килобайтах. Вообще тут не все так просто. Числом памяти является степень двойки. Так что Mega162 это не контроллер со 162КБ флеша, а своеобразная Мега16 модификации2 с памятью 16кб. Или вот Мега88 - не 88кб, а 8кб флеша, а вторая 8 это вроде как намек на то, что это дальнейшее развитие Мега8. Аналогично и Мега48 или Мега168. Тоже самое и семейством Тини. Например, Тини2313 - 2килобайта флеша. А что такое 313? А хрен знает что они имели ввиду:) Или Тини12 - 1кб Флеша. В общем, фишку просек.
  • А - префикс энергопотребления (обычно). Этой буквы может и не быть, но в новых сериях она присутствует почти везде. Например, V и L серии - низковольтные, могут работать от 2,7 вольт. Правда за низковольтность приходится платить меньше частотой. Но оверклокинг возможен и тут, ничто человеческое нам не чуждо:) A и P имеют новые серии AVR с технологией PicoPower т.е. ультраэкономичные. Разницы по фаршу и внутренней структуре с их безиндексовыми моделями нет, тут все различие в работе всяких спящих режимов и энергопотреблении. Т.е. Mega16A легко меняется на Mega16 без А. И ничего больше менять не нужно.
  • 16 - Предельная тактовая частота в мегагерцах. В реальности можно разогнать и до 20;)
  • P - тип корпуса. Важная особенность. Дело в том, что далеко не всякий корпус можно запаять в домашних условиях без геморроя. Рекомендую пока обратить внимание на P - DIP корпус. Это громоздкий монстр, но его легко запаять, а, главное, он легко втыкается в специальную панельку и вынимается из нее обратно. Корпуса вида SOIC (индекс S) или TQFP (индекс A) пока лучше отложи в сторонку. Без хорошего опыта пайки и умения вытравить качественную печатную плату к ним лучше не соваться.
  • I — Тип лужения выводов. I - свинцовый припой. U - безсцвиновый. Для тебя никакой совершенно разницы. Бери тот что дешевле.

Рекоменую следующие модели:

  • ATMega16A-16PU - недорогой (около 100-150р), много выводов, много периферии. Доступен в разных корпусах. Прост, под него заточен мой учебный курс и все дальнейшие примеры.
  • ATTiny2313-20SU - идеальный вариант для изготовления всяких часов/будильников и прочей мелкой домашней автоматики. Дешев (рублей 40), компактен. Из минусов - нет АЦП.
  • ATmega48/88/168 любой из этих контроллеров. Компактен (в корпусе tqfp является самым тонким и мелким из AVR), дешев (рублей 100-150), фарширован донельзя.
  • ATmega128 для искушенных. Большой, мощный, дофига памяти. Дорогой (около 400р)

Если ты впервые столкнулся с микроконтроллерами, то наверняка у тебя стал выбор на чем писать.

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

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

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

C-
А вот с высокими языками, например с Си, ситуация уже куда хуже. Да, повторить какой нибудь пример из обучалки, вроде вывода строки на дисплей, Сях куда проще, подключил нужную библиотеку, набрал стандартную команду и вот тебе результат. Но это только так кажется. На самом деле, стоит чуть вильнуть в сторону, как начинается темный лес. Особенно когда дело начинает касаться адресации разных видов памяти,

Напомню, что у AVR, как и подавляющего числа МК, память разделена на код и данные и адреса у них в разных адресных пространствах о которых стандарт Си ничего не знает, ведь он расчитан на некий универсальный вычислитель. А тут приходится вводить всякие модификаторы, квалификаторы и без яростного курения мануалов разобраться в этих примочках бывает очень сложно. Особенно работа с памятью осложняется тем, что программа то работает в том и другом случае, но вот если неправильно указать тип памяти, то оперативка забьется константами и в дальнейшем программу скрючит в самый неподходящий момент. Вот и найди такой глюк

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

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

В таких случаях обычно открывают листинг и смотрят что там происходит в коде на уровне команд процессора, но вот засада — без знания ассемблера там делать нечего! Зато если понимаешь то как работает программа на уровне команд, то найти багу вроде срыва стека или нарушения атомарного доступа проще простого.

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

Кроме того существуют такие контроллеры как ATTiny 1x у которых либо вообще нет оперативки, либо она такая мизерная, что даже стек там сделан аппаратным. Так что на Си там ничего написать в принципе нельзя.

Assembler+
Представь, что ты прораб, а компилятор это банда джамшутов. И вот надо проделать дырку в стене. Даешь ты джамшутам отвертку и говоришь — ковыряйте. Проковряют они отверткой бетонную стену? Конечно проковыряют, вопрос лишь времени и прочности отвертки. Отвертка сточится (читай памяти процессора или быстродействия не хватит)? Не беда — дадим джамшутам отвертку побольше, благо разница в цене между большой отверткой и маленькой копеечная. В самом деле, зачем прорабу, руководителю, знать такие низкоуровневые тонкости, как прочность и толщина бетонной стены, типы инструмента. Главное дать задание и проконтроллировать выполнение, а джамшуты все сделают сами.
Задача решается? Да! Эффективно это решение? Совершенно нет! А почему? А потому что прораб не знал, что бетон твердый и отверткой его проковырять сложно. А будь прораб сам когда то рабочим, пусть даже не профи, но своими руками положил плитку, посверлил дырки, то впредь таких идиотских заданий бы не давал. Конечно, нашего прораба можно и в шараге выучить, дав ему всю теорию строения стен, инструмента, материалов. Но ты представь сколько это сухой теории придется перелопатить, чтобы чутье было интуитивным, на уровне спинного мозга? Проще дать в руки инструмент и отправить сверлить стены. Практика — лучший учитель.

Также и с ассемблером. Хочешь писать эффективные программы на высокоуровневом языке — изучи хотя бы один ассемблер, попиши на нем немного. Чтобы потом, глядя на любую Сишную строку, представлять себе во что это в итоге компилируется и как обрабатывается контроллером. Очень помогает в отладке и написании, а уж про ревесирование чужих программ я вообще не говорю.

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

С+
Си хорош за счет огромного числа готового кода, который можно очень легко и удобно подключать и использовать в своих нуждах. За большую читабельность алгоритмов. За возможность взять и перетащить код, например, с AVR на ARM без особых заморочек. Или с AVR на PIC. Разумеется для этого надо уметь ПРАВИЛЬНО писать на Си, выделяя все аппаратно зависимые части в HAL.

Общий расклад примерно таков, что использование высокоуровневого языка на контроллерах с обьемом памяти меньше 8 килобайт является избыточным. Тут эффективней писать все на Ассемблере. Особенно если проект подразумевает не просто мигание светодиодом.
8-16 килобайт тут уже зависит от задачи, а вот пытаться писать на ассемблере прошивку более 16 килобайт можно, но это напоминает прокладку тоннеля под Ла Маншем с помощью зубила.

В общем, знать надо и то и другое. Настоятельно тебе рекомендую начать изучать МК с ассемблера. А как только поймешь, что на асме можешь реализовать все что угодно, любой алгоритм. Когда досконально прочувствуешь работу стека, прерываний, организацию переходов и ветвлений. Когда разные трюки и хитрости, вроде игр с адресами возврата из прерываний и процедур, переходами и конечными автоматами на таблицах и всякие извраты будут вызывать лишь интерес, но никак не взрыв мозга из серии “Аааа как это работает??? Не понимаю?!!”
Вот тогда и можно изучать Си. Причем, изучать его с дебагером в руках. Не просто изучить синтаксис (там то как раз все элементарно), а понять ЧТО и КАК делает компилятор из твоего исходника. Поржать над его тупостью или наоборот поудивляться извратам искуственного интелекта. Понять как компилятор делает ветвления, как организует циклы, как идет работа с разными типами данных, как ведется оптимизация. Где ему лучше помочь, написав в ассемблерном стиле, а где не критично и можно во всю ширь использовать языковые возможности Си.

А вот начать изучение ассемблера после Си мало кому удается. Си расслабляет, становится лень и впадлу. Скомпилировалось? Работает? Ну и ладно. А то что там быдлокод, та пофигу… =)

А как же бейсик, паскаль и прочие языки? Они тоже есть на AVR?
Конечно есть, например BascomAVR или MicroPASCAL и во многих случаях там все проще и приятней. Не стоит прельщаться видимой простотой. Она же обернется тем, что потом все равно придется переходить на Си.

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

А вот на бейсик с паскалем, обычно, всем пофигу. Если на AVR и PIC эти компиляторы и сделали, то лишь потому, что процы эти стали особо популярны у любителей и там наверняка найдется тот, кто заинтересуется и бейсиками всякими. С другим семейством контроллеров далеко не факт, что будет также радужно. Например под STM8 или Cortex M3 я видел Pascal в лучшем случае только в виде кривых студенческих поделок. Никак не тянущих на нормальный компилятор.

Такой разный Си
С Си тоже не все гладко. Тут следует избегать компиляторов придумывающих свои диалектные фишки. Например, CodeVision AVR (CVAVR) позволяет обращаться к битам порта с помощью такого кода:

1 PORTB.7 = 1; // Выставить бит 7 порта B в 1

Удобно? Конечно удобно! Вот только в Си так делать нельзя, стандарт языка не позволяет. И ни один другой Си компилятор такой кусок кода не примет. Т.к. по стандарту корректней будет так:

1 PORTB |= 1<<7;

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

Приплюснутый
Некоторое время назад я считал, что С++ в программировании микроконтроллеров не место. Слишком большой overhead. C тех пор мое мнение несколько поменялось.
Мне показали очень красивый кусок кода на С++, который компилился вообще во что то феерическое. Компактней и быстрей я бы и на ассемблере не факт что написал. А уж про читабельность и конфигурируемость и говорить не приходится. Все из знакомых программистов, кто видел этот код, говорили что-то вроде “Черт, а я то думал, что я знаю С++”.

Так что писать на С++ можно! Но сделать компактный и быстрый код на С++ чертовски виртуозная задача, надо знать этот самый С++ в совершенстве. Судя по тому, что столь качественных примеров эффективности С++ при программировании под МК мне попадалось раз-два, то видимо пороговый уровень входа в эту область весьма и весьма велик.

В общем, как говорил Джон Кармак, “хороший С++ код лучше чем хороший С код. Но плохой С++ может быть намного ужасней чем плохой С код”.

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

Основой любого микроконтроллера является вычислительное ядро. Во всех моделях AVR оно практически одинаковое и это большой плюс. Именно единство архитектуры обеспечивает легкую переносимость кода.

Итак, что же у нас в основе микроконтроллера, взгляни на диаграмму:

Ядро состоит, в первую очередь, из памяти программ (Flash Programm Memory) и Арифметико-логического устройства (ALU), блока управления (на диаграмме не показан) и программного счетчик (Program Counter). Также есть тактовый генератор, задающий импульсы относительно которых работают блоки микроконтроллера. Тактовый генератор можно сравнить с маятником и собачкой в будильнике: маятник туда сюда, собачка тикает по одному зубчику — шестеренки крутятся. Встала собачка — встал весь будильник.

При старте микроконтроллера значение программного счетчика равно 0000 - это адрес первой команды в нашей flash ROM. Микроконтроллер хватает оттуда два байта (код команды и ее аргументы) и отдает на выполнение в декодер команд (Instruction Decoder).

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

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

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

Вся математика и обработка делается посредством ALU. Это, своего рода, калькулятор. Он может складывать, вычитать, сравнивать, сдвигать разными способами, иногда делить и умножать (это считается круто, встречается редко).

В качестве промежуточных операндов используются 32 ячейки - Оперативные регистры общего назначения РОН. Доступ к этим ячейкам самый быстрый, а число операций с их содержимым наиболее богатое. В ассемблере регистры эти называются просто R0,R1,R2 … R31. Причем делятся они на три группы:

Младшие R0..R15
Обычные регистры общего назначения, но какие то ущербные. С ними не работают многие команды, например, такие как загрузка непосредственного числа. Т.е. нельзя, например, взять и присвоить регистру число. Зато можно скопировать число из любого другого регистра.

Старшие R16..R31
Полноценные регистры, работающие со всеми командами без исключения.

Индексные R26…R31
Шесть последних регистров из старшей группы особенные. В принципе, их можно юзать и как обычные регистры общего назначения. Но, кроме этого, они могут образовывать регистровые пары X(R26:R27), Y(R28,R29), Z(R30:R31) которые используются как указатели при работе с памятью.

ОЗУ
Кроме 32 регистров в микроконтроллере есть оперативная память. Правда не везде — в младших семействах AVR Tiny12 и Tiny11 оперативной памяти нет, так что приходиться вертеться в 32 ячейках.

Оперативная память это несколько сотен ячеек памяти. От 64 байт до 4килобайт, в зависимости от модели. В этих ячейках могут храниться любые данные, а доступ к ним осуществляется через команды Load и Store.

То есть нельзя взять, например, и прибавить к ячейке в памяти, скажем, единицу. Нам сначала сделать операцию Load из ОЗУ в РОН, потом в регистре прибавить нашу единицу и операцией Store сохранить ее обратно в память. Только так.

EEPROM
Долговременная память. Память которая не пропадает после выключения питания. Если Flash может содержать только код и константы, а писать в нее при выполнении ничего нельзя (Это память Read Only), то в ЕЕПРОМ можно сколько угодно писать и читать. Но в качестве оперативки ее особо не поюзаешь. Дело в том, что цикл записи в EEPROM длится очень долго — миллисекунды. Чтение тоже не ахти какое быстрое. Да и число циклов перезаписи всего 100 000, что не очень много в масштабах работы оперативной памяти. ЕЕПРОМ используется для сохранения всяких настроек, предустановок, собранных данных и прочего барахла, что может потребоваться после включения питания и в основном на чтение. Эта память есть не во всех моделях AVR, но в подавляющем их большинстве.

Периферия
Периферия это внутренний фарш микроконтроллера. То что делает его таким универсальным. ALU, RAM, FLASH и Блок управления это как в компе Мать, Проц, Память, Винт — то без чего комп даже не запустится толком. То периферия это уже как сетевуха, видяха, звуковая карта и прочие прибамбасы. Они могут быть разными, разной степени крутости и навороченности, а также комбинироваться в разном порядке.

Именно по наличию на кристалле той или иной периферии происходит выбор микроконтроллера под задачу.

Периферии всякой придумано великое множество, всего я наверное даже не опишу. Но дам основной набор присутствующий почти во всех AVR, а также в других современных контроллерах.

  • Порты ввода вывода — то без чего невозможно взаимодействие контроллера с внешним миром. Именно порты обеспечивают то самое “ножкодрыгательство” управляющее другими элементами схемы. Захотели получить на выводе единичку, дали приказ соответствующему порту — получите, распишитесь. Захотели узнать какой там сигнал на входе? Спросили у соответствующего порта — получили. Почти все выводы микроконтроллера могут работать в режиме портов ввода-вывода.
  • UART/USART приемопередатчик — последовательный порт. Работает по тому же асинхронному протоколу что и древние диалапные модемы. Старый как мир, надежный и простой как кувалда. Подходит для связи с компьютером и другими контроллерами.
  • Таймеры/счетчики — задача таймеров отсчитывать тики. Сказал ему отсчитать 100 тактов процессора — он приступит и как досчитает подаст сигнал. Им же можно подсчитывать длительность входных сигналов, подсчитывать число входных импульсов. Да много чего умеет таймер, особенно в AVR. Подробное описание функций таймера занимает добрых три десятка страниц в даташите. При том, что таймеров самих существует несколько видов и фарш у них разный.
  • АЦП - аналоговый вход. Есть не у всех микроконтроллеров, но вещь полезная. Позволяет взять и замерить аналоговый сигнал. АЦП это своеобразный вольтметр.
  • I2C(TWI) интерфейс — последовательная шина IIC. Через нее осуществляется связь с другими устройствами. На IIC можно организовать своеобразную локальную сеть из микроконтроллеров в пределах одного устройства.
  • SPI — еще один последовательный протокол, похожа на IIC, но не позволяет организовывать сети. Работает только в режиме Мастер-Ведомый. Зато ОЧЕНЬ быстрая.
  • Аналоговый Компаратор — еще один аналоговый интерфейс. Но, в отличии от АЦП, он не замеряет, а сравнивает два аналоговых сигнала, выдавая результат А>B или A<B в двоичном виде.
  • JTAG/DebugWire — средство отладки, позволяет заглянуть в мозги контроллера с помощью специального адаптера, например такого, какой встроен в мою демоплату Pinboard. Иной раз без него как без рук.
  • PWM — ШИМ генератор. Вообще это не отдельный блок, а дополнительная функция таймера, но тоже полезная. С помощью ШИМ генератора легко задать аналоговый сигнал. Например, менять яркость свечения светодиода или скорость вращения двигателя. Да мало ли куда его применить можно. Число каналов ШИМ разное от контроллера к контроллеру.

Еще бывают встроенные USB, Ethernet интерфейсы, часы реального времени, контроллеры ЖКИ дисплеев. Да чего там только нет, моделей микроконтроллеров столько, что задолбаешься только перечислять.

Взаимодействие ядра с периферией
Ядро одно на всех, периферия разная. Общение между ними происходит через память. Т.е. у периферии есть свои ячейки памяти — регистры периферии. У каждого периферийного устройства их не по одной штуки. В этих регистрах находятся биты конфигурации. В зависимости от того как эти биты выставлены в таком режиме и работает периферийное устройство. В эти же регистры нужно записывать данные которые мы хотим выдать, например, по последовательному порту, или считывать данные которые обработал АЦП. Для работы с периферией есть специальные команды IN и OUT для чтения из периферии в регистр РОН и записи из регистра РОН в периферию соответственно.

Поскольку ядро одинаковое, а периферия разная, то при переносе кода на другую модель микроконтроллера надо только подправить эти обращения так как название периферийных регистров от модели к модели может чуток отличаться. Например, если в контроллере один приемопередатчик UART то регистр прием данных зовется UDR, а если два, то у нас есть уже UDR0 и UDR1. Но, в целом, все прозрачно и логично. И, как правило, портирование кода с одного МК на другой, даже если он написан на ассемблере, не составляет большого труда. Особенно если он правильно написан.

Как узнать что есть в конкретном микроконтроллере?
Для этого на каждый МК есть даташит - техническая документация. И вот там, прям на первой странице, написано что почем и как. Вот тебе пример, даташит на Мегу16 с моим закадровым переводом:) Жирным шрифтом помечены опции которые я гляжу в первую очередь, как наиболее интересные для меня, остальное, как правило, присутствует по дефолту.

Features (фичи!)
• High-performance, Low-power AVR® 8-bit Microcontroller
(понтовая экономичная архитектура AVR)

• Advanced RISC Architecture
(просто офигенная вещь для рисковых чуваков!)

– 131 Powerful Instructions – Most Single-clock Cycle Execution
(131 крутая и быстрая команда!)

– 32 x 8 General Purpose Working Registers
(32 восьми разрядных регистра - те самые R0…R31)

– Fully Static Operation
(Полностью статические операции, т.е. тактовая частота может быть хоть 1 импульс в год)

– Up to 16 MIPS Throughput at 16 MHz
(скорость выполнения до 16миллионов операций в секунду!)

– On-chip 2-cycle Multiplier
(а числа умеем множить за два такта! Это правда круто, народ!)

• High Endurance Non-volatile Memory segments
– 16K Bytes of In-System Self-programmable Flash program memory
(памяти хватит набыдлокодить на 16кб кода)

– 512 Bytes EEPROM 8-bit
(и нажрать на века 512 байт мусора в ЕЕПРОМ)

– 1K Byte Internal SRAM
(оперативки 1кб, кому там 2Гигабайт не хватает? Программировать не умеете! =) Тут и 64 байтов за глаза хватает. Помните Билла Гейтса и его “640кб хватит всем!” он знал о чем говорил:)

– Write/Erase Cycles: 10,000 Flash/100,000 EEPROM Microcontroller
(перешивать флеш можно 10тыщь раз, еепром 100тыщь раз. Так что можешь не бояться экспериментировать)

– Data retention: 20 years at 85°C/100 years at 25°C(1)
(Если законсервируешь свой будильник на AVR, то твоих правнуков он еще и через 100 лет порадует)

– Optional Boot Code Section with Independent Lock Bits
In-System Programming by On-chip Boot Program
True Read-While-Write Operation
(поддержка бутлоадеров. Удобная вещь, позволяет прошиваться без программаторов)

– Programming Lock for Software Security In-System
(если жадный и умный, то можешь закрыть от посторонних прошивку и фиг кто выкрадет твои секреты)

• JTAG (IEEE std. 1149.1 Compliant) Interface
– Boundary-scan Capabilities According to the JTAG Standard Programmable
– Extensive On-chip Debug Support
– Programming of Flash, EEPROM, Fuses, and Lock Bits through the JTAG Interface Flash
(Отладочный интерфейс JTAG и его фичи)

• Peripheral Features
(А вот, собственно и периферия пошла)

– Two 8-bit Timer/Counters with Separate Prescalers and Compare Modes
(два таймера 8ми разрядных, с кучей всяких режимов разных.

– One 16-bit Timer/Counter with Separate Prescaler, Compare Mode, and Capture Mode ATmega16
(один 16ти разрядный таймер счетчик, с кучей всяких примочек и фишек)

– Real Time Counter with Separate Oscillator
(таймер может тикать от отдельного генератора, удобно если хочешь сделать часы)

– Four PWM Channels ATmega16L
(Четыре ШИМ канала — на тех же таймерах)

– 8-channel, 10-bit ADC
(восьмиканальный 10ти разрядный АЦП. Фичи его ниже)

8 Single-ended Channels
(можно замерять по очереди сразу 8 разных напряжений)

7 Differential Channels in TQFP Package Only
(7 дифференциальных каналов. Правда только в корпусе TQFP т.к. ног у него больше)

2 Differential Channels with Programmable Gain at 1x, 10x, or 200x
(два дифференциальных канала с программируемым усилением)

– Byte-oriented Two-wire Serial Interface
(Поддержка IIC с аппаратным кодированием байтов)

– Programmable Serial USART
(Последовательный интерфейс. Удобен для связи с компом)

– Master/Slave SPI Serial Interface
(SPI интерфейс, пригодится)

– Programmable Watchdog Timer with Separate On-chip Oscillator
(Спец таймер защиты от зависаний)

– On-chip Analog Comparator
(Тот самый компаратор)

• Special Microcontroller Features
(полезные свистоперделки)

– Power-on Reset and Programmable Brown-out Detection
(защита от косяков в работе при пониженном напряжении ака севшие батарейки)

– Internal Calibrated RC Oscillator
(А еще можно сэкономить 20рублей на покупке внешнего кварца. Он нафиг не нужен!:) И это круто!)

– External and Internal Interrupt Sources
(Есть внешние прерывания. Очень удобная вещь)

– Six Sleep Modes: Idle, ADC Noise Reduction, Power-save, Power-down, Standby
and Extended Standby
(Дофига режимов энергосбережения)

• I/O and Packages
– 32 Programmable I/O Lines
– 40-pin PDIP, 44-lead TQFP, and 44-pad QFN/MLF

(число полезных ножек, тем самых вводов выводов)

• Operating Voltages designs.
– 2.7 - 5.5V for ATmega16L
– 4.5 - 5.5V for ATmega16

(Питающие напряжения. Помните я говорил про низковольтные серии — вот они, во всей красе)

• Speed Grades
– 0 - 8 MHz for ATmega16L
– 0 - 16 MHz for ATmega16

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

• Power Consumption @ 1 MHz, 3V, and 25°C for ATmega16L
– Active: 1.1 mA
– Idle Mode: 0.35 mA
– Power-down Mode: < 1 µA
(Потребляемая мощность в разных режимах. 1мА даже в активном режиме это фигня. В 10 раз меньше самого тухлого светодиода)

Установка.
Сначала надо с сайта atmel.com скачать последнюю версию AVR Studio. Весит она что то около 30 метров. Можно и старые релизы использовать, не преступно, но там может не оказаться новых микроконтроллеров. AVR Studio, как и многие буржуйские программы, крайне хреново понимает русские имена и длинные пути. Поэтому ставь ее по максимально простому пути, что то вроде C:\AVR\ А сами проекты тоже держи как можно ближе к корню, У меня, например, это D:\Work\AVR — никаких имен длинней 8 символов и, конечно же, никаких русских символов. Привет родимый DOS, как говорится.

Да, если планируешь (если не планируешь, то все равно скачай и поставь, не помешает) писать на Си, то рекомендую скачать GCC aka WinAVR и установить ее ДО студии, туда же, поближе к корню. Тогда студия подхватит ее в качестве своего плагина. Если поставить после, то тоже, может быть подхватит, но возможны проблемы.

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

В центре будут уже созданные проекты, а нас интересует кнопка New Project. Жми ее и вводи параметры будущей разработки.

Выбирай тип языка на котором будешь писать: Си или Ассемблер, а также имя будущего проекта. Также не помешает указать путь к папке с проектами. Студия умная и запомнит ее раз и навсегда и под каждый новый проект будет генерить новую папку. Так что скоро там будет полный гадюшник:))))) Дальше есть две кнопки Finish и Next. Тебе надо жать на Next. Нажмешь на финиш и получишь пустой проект в котором даже процессор то не определен. А вот если Next, то будет следующий диалог:

Сильно сомневаюсь, что у тебя первоначально сразу же будет AVR Dragon или какой нибудь ICE 2, так что мы будем симулировать. Выбирай симулятор. Чем отличается AVR Simulator от AVR Simulator2 я так и не понял, работают одинаково. Выбрал? Вот теперь FINISH HIM! В смысле жми Finish.

Во, появилось пустое окно проекта. Оглядим что тут есть:

Увеличить скриншот

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

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

Подробно по пунктикам. Первый ряд.

  • Бинокль - поиск в коде. Кроме поиска там есть еще Mark ALL - пометить строки с найденым барахлом. Появляются такие голубенькие меточки возле строк.
  • Синий флажок и компания — поставить/снять пометку вручную. Удобнейшая вещь эти пометки. Пользуйся!
  • Две фиговины для форматирования блоков текста. Типа выделил процедуру, а потом подвинул ее влево или вправо. Сишники оценят:)
  • Синяя муть и птичка — кнопки для программаторов понтовых. Если их у тебя нет, то забей.
  • Стрелка Play – запуск симуляции.
  • Квадратик Stop — остановка симуляции. Все просто.
  • Листок со стрелочкой - запуск программы.
  • Пауза — остановка программы там где получилось
  • синяя стрелка аля Enter – виртуальный Reset контроллера
  • Желтая стрелка - показать где программа находится сейчас. Жутко полезно когда проект побит на части, и ты пытаешься найти где прога стоит в данный момент.
  • Три стандартные кнопки любого отладчика Step Into - сделать шаг по тексту программы. Step Over — сделать шаг по тексту, но не заходить в процедуры и функции (процедуры и функции при этом выполняются, просто нам это не показывают). Step-Out — Выход из процедуры на уровень выше. Конечно, назад МК шагать не умеет, но вот если там цикл какой, то Step Out это равносильно тому, что МК сделает одну итерацию цикла и встанет над инструкцией.
  • Фигурные скобки и стрелка — выполнить программу до текущего положения курсора. Пощелкай этой кнопочкой и сам поймешь что это
  • Красная точка — BreakPoint поставить бряк. О брейпоинтах ниже.
  • Крестик и красная жопа — нажмешь ее и всем брейкпоинтам в проге настанет жопа — их удалит.
  • Очки - это Watch, способ подглядывать за какой нибудь переменной, адресом в памяти или регистром. О них тоже потом.
  • Кнопки переключалок окон, включать выключать разные блоки интерфейса. Потыкайся по ним и поймешь сам.


Второй ряд:
Тут ничего не работает, т.к. нет подключенных девайсов (JTAG или STK500) и нас интересуют только две последние кнопки.
Первая из них это компиляция проекта, вторая компиляция и запуск симуляции.

Теперь если ты забьешь в проект простейший код, например,

12 .include "m8def.inc"; Используем ATMega8 NOP

Куда уж проще:) То сможешь скомпилировать проект и запустить процесс отладки.

При запуске симулятора повылазит куча разных новых окошек, о которых я тебе сейчас расскажу. Гляди на скриншот:

Увеличить скриншот

I/O View
Окно переферии, то что справа. Обрати внимание на заголовок окна I/O View - там есть строка поиска и ряд кнопочек. Потыкай их, чтобы получить наиболее удобное представление. Я обычно ставлю Tree View. Каждый регистр можно развернуть. Каждый бит подписан и во всплывающей подсказке написано его назначение. Также настоятельно рекомендую прошерстить контекстное меню в этом блоке и выставить там галку Show Bit numbers - удобно. Черный квадратик - бит есть. Белый - бита нет. Там же указано значение в байте. В процессе отладки каждый бит можно вручную принудительно выставить или сбросить. Сэмулировав, например, нажатие кнопки.

Processor
Слева есть окно Processor, в нем указана вся подноготная ядра в текущий момент.

  • Program Counter - счетчик адресов. По нему можно узнать куда уйдет программа на следующем шаге. Когда отлаживаешь всякие индексные переходы, да извращенские конечные автоматы с переходами вида:
12345 LDI R16,AddresL; Кто сказал, что индексные переходы только по спец регистрам? LDI R17,AddresH PUSH R17 PUSH R16; ICALL? Щаз! Откуда хотим оттуда и скачем. RET; Наш извращенский метод!

· Вот когда такие конструкции отлаживаешь PC становится твоим любимым регистром:)

  • Туда же Stack Pointer — указатель стека. Сначала глядим туда, потом в память куда он указывает, и палим где у нас косяк со стеком. Либо если SP не вышел на 0, а по идее доложен был, то у нас срыв стека и неизбежная упячка пыщь пыщь!!!111.
  • Слово из трех букв — три индексные пары X, Y, Z — вообщет это те же регистры от 26 до 31го, а тут для удобства выведены.
  • Cycle Counter — просто счетчик тиков процессора. Ни разу не пригождался.
  • Frequensy — текущая частота эмулируемого процессора. Сразу выставляй ее правильно. Как ее сменить? О! Золотой вопрос. Тому кто придумал прятать эту настройку в задницу надо гвоздь в голову забить. Ничего, нашли, читай ниже.
  • Stop Watch — а вот это мега вещь! Время от старта. По нему можно вычислять сколько времени выполняется тот или иной кусок кода. Например задержка. Только изначально он показывается в микросекундах. Нам такие величины обычно не нужны, поэтому лезь в контекстное меню и переключай его в миллисекунды.
  • SREG это понятно - флаги.
  • Ну и 32 регистра. Правда под регистры я выделил отдельное окошко (слева внизу). Кстати, можно вручную во время эмуляции вписать любое значение в регистр.


Memory
Окно памяти. Можно в списке выбирать любое адресное пространство. Хочешь флеш, хочешь епром, или ОЗУ.

Watch
Это Watch лист. Можно на любой адрес, переменную или любой регистр навесить гляделку и там всегда будет отображаться его содержимое. Удобно при отладке, чтобы не шерстить по коду. Также содержимое регистров/переменных подсвечивается в подсказке при наведении мыши.

Отладка в AVR Studio
Код ты написал, он у тебя даже скомпилировался. Но от радости прыгать не получается — не работает как задумано. Чтож, бывает. Начинаем избавлять код от лажи — отлаживать.
Сначала подготовь плацдарм и выстави требуемую частоту процессора.

Как выставить частоту процессора в AVR Studio:
Загадка века, между прочим. Сходу фиг найдешь. Короче, запускай процесс симуляции. Только в этом случае появится нужный пункт меню. А потом лезь в меню Debug -> AVR Simulations Options. Ну не козлы, а? В такие гребеня прятать столь важный параметр. Я почти два месяца его в свое время искал. Там же можно выставить адрес бутлоадера (он зависит от Fuse Bits в реальном МК).

Итак, симуляция запущена, а желтая стрелка бодро указывает на первую команду. Потыкай на клавишу F11, погляди как процессор шагает. Если все нормально, то переходи на то место, где у тебя предпологаемый затык. Например, не выставляется бит в порт. Можно поставить в это место курсор и нажать Run to Cursor, это если по быстрому. Но лучше использовать брякпоинт.

BreakPoint
Это точка останова. Т.е. если какое то условие совпадет, то процессор встанет как вкопанный, пока ты не примешь решение, что же делать дальше. Мощнейшее средство отладки. Самый простой случай это установка Breakpoint - кнопкой F9, она же его и убирает. Через контекстное меню брейпоинт можно временно дезактивировать. Все, если теперь ты нажмешь на F5 то проц, пойдет молотить код подряд, пока не дойдет до брейкпоинта. Где встанет как вкопаный, перейдя в пошаговый режим.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: