Програмування мікроконтролерів AVR. Пристрій та програмування мікроконтролерів AVR. Мікроконтролер і як його перемогти Мікроконтролери avr для початківців короткий курс самовчитель

Мікроконтролери (далі МК) міцно увійшли до нашого життя, на просторах інтернету можна зустріти дуже багато цікавих схем, які виконані на МК. Чого тільки не можна зібрати на МК: різні індикатори, вольтметри, прилади для дому (пристрої захисту, комутації, термометри…), металошукачі, різні іграшки, роботи тощо. можна перераховувати дуже довго. Першу схему на мікроконтролері я побачив років 5-6 тому у журналі радіо, і практично відразу ж перегорнув сторінку, подумавши про себе "все одно не зможу зібрати". Дійсно, в той час МК для мене були чимось дуже складним і незрозумілим пристроєм, я не уявляв, як вони працюють, як їх прошивати, і що робити з ними у разі неправильної прошивки. Але близько року тому, я вперше зібрав свою першу схему на МК, це була схема цифрового вольтметра на 7 сегментних індикаторах і мікроконтролері ATmega8. Так вийшло, що мікроконтролер я купив випадково, коли стояв у відділі радіодеталей, хлопець переді мною купував МК, і я теж вирішив купити, і спробувати зібрати щось. У своїх статтях я розповім вам про мікроконтролери AVR, навчу вас працювати з ними, розглянемо програми для прошивки, виготовимо простий та надійний програматор, розглянемо процес прошивки та найголовніше проблеми, які можуть виникнути і не тільки у новачків.

Основні параметри деяких мікроконтролерів сімейства AVR:

Мікроконтролер

Пам'ять FLASH

Пам'ять ОЗУ

Пам'ять EEPROM

Порти введення/виводу

U харчування

Додаткові параметри МК AVR mega:

Робоча температура: -55 ... +125 * С
Температура зберігання: -65 ... +150 * С
Напруга на виводі RESET щодо GND: max 13В
Максимальна напруга живлення: 6.0В
Максимальний струм лінії введення/виводу: 40мА
Максимальний струм по лінії живлення VCC та GND: 200мА

Розміщення висновків моделей ATmega 8X

Розміщення висновків моделей ATmega48x, 88x, 168x

Розміщення висновків у моделей ATmega8515x

Розміщення висновків у моделей ATmega8535x

Розміщення висновків у моделей ATmega16, 32x

Розміщення висновків у моделей ATtiny2313

Наприкінці статті прикріплено архів з датташитами на деякі мікроконтролери.

Настановні FUSE біти MK AVR

Запам'ятайте, запрограмований фьюз – це 0, не запрограмований – 1. Обережно варто ставитись до виставлення ф'юзів, помилково запрограмований ф'юз може заблокувати мікроконтролер. Якщо ви не впевнені, який саме фьюз потрібно запрограмувати, краще на перший раз прошийте МК без фьюзів.

Найпопулярнішими мікроконтролерами у радіоаматорів є ATmega8, потім йдуть ATmega48, 16, 32, ATtiny2313 та інші. Мікроконтролери продаються в TQFP корпусах та DIP, новачкам рекомендую купувати у DIP. Якщо купите TQFP, буде проблематичніше їх прошити, доведеться купити або паяти плату т.к. у них ніжки розташовуються дуже близько одна від одної. Раджу мікроконтролери в DIP корпусах, ставити на спеціальні панельки, це зручно і практично, не доведеться випоювати МК якщо закортить перепрошити, або використовувати його для іншої конструкції.

Багато сучасні МК мають можливість внутрисхемного програмування ISP, тобто. якщо ваш мікроконтролер запаяний на плату, то для того, щоб змінити прошивку нам не доведеться випоювати його з плати.

Для програмування використовується 6 висновків:
RESET- Вхід МК
VCC- Плюс харчування, 3-5В, залежить від МК
GND- Загальний провід, мінус харчування.
MOSI- Вхід МК (інформаційний сигнал у МК)
MISO- Вихід МК (інформаційний сигнал із МК)
SCK- Вхід МК (тактовий сигнал МК)

Іноді ще використовують виводи XTAL 1 і XTAL2, на ці висновки чіпляється кварц, якщо МК буде працювати від зовнішнього генератора, ATmega 64 і 128 виводу MOSI і MISO не застосовуються для ISP програмування, замість них виведення MOSI підключають до ніжки PE0, a MISO до PE1. При з'єднанні мікроконтролера з програматором, що з'єднують дроти повинні бути якомога коротшими, а кабель, що йде від програматора на порт LPT, так само не повинен бути занадто довгим.

У маркуванні мікроконтролера можуть бути незрозумілі літери з цифрами, наприклад Atmega 8L 16PU, 8 16AU, 8A PU та ін. Літера L означає, що МК працює від нижчої напруги, ніж МК без літери L, зазвичай це 2.7В. Цифри після дефісу або пробілу 16PU або 8AU говорять про внутрішню частоту генератора, який є в МК. Якщо фьюзи виставлені на роботу від зовнішнього кварцу, кварц повинен бути встановлений на частоту, що не перевищує максимальну за даташит, це 20МГц для ATmega48/88/168, і 16МГц для інших атмег.


У цьому навчальному курсі з avr я постарався описати все найголовніше для початківців програмувати мікроконтролери avr. Усі приклади побудовані на мікроконтролері atmega8. Це означає, що для повторення всіх уроків вам знадобиться лише один МК. Як емулятор електронних схем використовується Proteus - на мій погляд, - найкращий варіант для початківців. Програми у всіх прикладах написані на компіляторі C для CodeVision AVR AVR. Чому не на якомусь асемблері? Тому що початківець і так завантажений інформацією, а програма, яка множить два числа, на асемблері займає близько ста рядків, та й у складних жирних проектах використовують С. Компілятор CodeVision AVR заточений під мікроконтролери atmel, має зручний генератор коду, непоганий інтерфейс і прямо з нього можна прошити мікроконтролер.

У цьому навчальному курсі буде розказано та показано на простих прикладах як:

  • Почати програмувати мікроконтролери, із чого почати, що для цього потрібно.
  • Які програми використовувати для написання прошивки для avr, для симуляції та налагодження коду на ПК,
  • Які периферійні пристрої знаходяться всередині МК, як ними керувати за допомогою програми
  • Як записати готову прошивку в мікроконтролер і як її налагодити
  • Як зробити друковану плату для Вашого пристрою
Для того, щоб зробити перші кроки на шляху програмування МК, вам знадобиться лише дві програми:
  • Proteus - програма-емулятор (у ній можна розробити схему, не вдаючись до реального паяння і потім на цій схемі протестувати нашу програму). Ми всі проекти спочатку запускатимемо в протеусі, а потім вже можна і паяти реальний пристрій.
  • CodeVisionAVR - компілятор мови програмування для AVR. У ньому ми розроблятимемо програми для мікроконтролера, і прямо з нього ж можна буде прошити реальний МК.
Після встановлення Proteus, запускаємо його
Він пропонує подивитися проекти які йдуть з ним, ми чемно відмовляємося. Тепер давайте створимо у ній найпростішу схему. Для цього натисніть на значок візуально нічого не відбувається. Тепер потрібно натиснути на маленьку букву Р (вибрати із бібліотеки)на панелі списку компонентів, відкриється вікно вибору компонентів
у полі маска вводимо назву компонента, який хочемо знайти у бібліотеці. Наприклад, нам потрібно додати мікроконтролер mega8
у списку результатів тикаємо на mega8 і натискаємо кнопку ОК. У нас у списку компонентів з'являється мікроконтролер mega8
У такий спосіб додаємо до списку компонентів ще резистор, ввівши в поле маска слово resта світлодіод led

Щоб розмістити деталі на схемі, клацаємо на деталь, далі клацаємо по полю схеми, вибираємо місце розташування компонента і ще раз клацаємо. Для додавання землі або загального мінусу на схему зліва натискаємо "Термінал" і вибираємо Ground. Таким чином, додавши всі компоненти і з'єднавши їх, отримуємо ось таку просту схему
Все, тепер наша перша схема готова! Але ви, мабуть, спитаєте, а що вона може робити? А нічого. Нічого, тому що для того, щоби мікроконтролер запрацював, для нього потрібно написати програму. Програма – це список команд, які виконуватиме мікроконтролер. Нам потрібно, щоб мікроконтролер встановлював на ніжці PC0логічний 0 (0 вольт) та логічну 1 (5 вольт).

Написання програми для мікроконтролера

Програму ми писатимемо мовою С у компіляторі CodeVisionAVR. Після запуску CV він запитує нас, що ми хочемо створити: Source або Project Ми вибираємо останнє та натискаємо кнопку ОК. Далі нам буде запропоновано запустити майстер CVAVR CodeWizard (це безцінний інструмент для початківця, тому що в ньому можна генерувати основний скелет програми) обираємо Yes
Майстер запускається з активною вкладкою Chip, тут ми можемо вибрати модель нашого МК - це mega8, і частоту, на якій працюватиме МК (за замовчуванням mega8 виставлена ​​на частоту 1 мегагерц), тому виставляємо все, як показано на скріншоті вище. Переходимо у вкладку Ports
У мікроконтролера atmega8 3 порти: Port C, Port D, Port B. У кожного порту 8 ніжок. Ніжки портів можуть перебувати у двох станах:
  • Вихід
За допомогою регістру DDRx.y ми можемо встановлювати ніжку входом чи виходом. Якщо в
  • DDRx.y = 0 - висновок працює як ВХІД
  • DDRx.y = 1 висновок працює на ВИХІД
Коли ніжка налаштована як вихід, ми можемо виставляти на ній лог 1 (+5 вольт) та логічний 0 (0 вольт). Це робиться записом у регістр PORTx.y. Далі буде детально розказано про порти вводу-виводу. А зараз виставляємо все, як показано на скріншоті, і натискаємо File->Generate, Save and Exit. Далі CodeWizard запропонує нам зберегти проект, ми його зберігаємо та дивимося на код:

#include //бібліотека для створення тимчасових затримок void main(void) ( PORTB=0x00; DDRB=0x00; PORTC=0x00; DDRC=0x01; // робимо ніжку PC0 виходом PORTD=0x00; DDRD=0x00; // Timer/Counter 0 initialization TCCR0 = 0x00; 0; OCR1BH=0x00 ; OCR1BL = 0x00; // Timer/Counter 2 initialization; ) Interrupt(s) initialization TIMSK=0x00; // Analog Comparator initialization ACSR=0x00;


Тут вам може здатися все страшним та незнайомим, але насправді все не так. Код можна спростити, викинувши ініціалізацію периферійних пристроїв МК, що не використовуються. Після спрощення він виглядає так:

#include //Бібліотека для роботи з мікроконтролером mega8 #include //бібліотека для створення тимчасових затримок void main(void) ( DDRC=0x01; /* робимо ніжку PC0 виходом запис 0x01 може здатися вам незнайомою, а це всього лише число 1 в шістнадцятковій формі, цей рядок буде еквівалентний 0b00000001 писатиму саме так.*/ while (1) ( );


Все гаразд. Але для того, щоб світлодіод замиготів, нам потрібно змінювати логічний рівень на ніжці PC0. Для цього до головного циклу потрібно додати кілька рядків:

#include //Бібліотека для роботи з мікроконтролером mega8 #include //бібліотека для створення тимчасових затримок void main(void) ( DDRC=0x01; /* робимо ніжку PC0 виходом запис 0x01 може здатися вам незнайомою, а це всього лише число 1 в шістнадцятковій формі, цей рядок буде еквівалентний 0b00000001 буду писати саме так. 500 мілісекунд PORTC.0=0; //виставляємо на ніжку 0 порту С 0 delay_ms(500); //робимо затримку в 500 мілісекунд);// закривається операторна дужка головного циклу програми


Тепер код готовий. Клацаємо на піктограму Build all Project files, щоб скомпілювати нашу програму (перекласти в інструкції процесора МК). У папці Exe, яка знаходиться в нашому проекті, має з'явитися файл з розширенням hex, це і є файл прошивки для МК. Щоб нашу прошивку згодувати віртуальному мікроконтролеру в Proteus, потрібно двічі клікнути на зображенні мікроконтролера в протеусі. З'явиться ось таке віконце
клацаємо на піктограму папки в полі Program File, вибираємо hex - файл нашої прошивки та натискаємо кнопку ОК. Тепер можна запустити симуляцію нашої схеми. Для цього натискаємо кнопку "Відтворити" у нижньому лівому куті вікна Протеус.

Доброго дня, шановні радіоаматори!
Вітаю вас на сайті

Що таке мікроконтролер і для чого він потрібен. Давайте звернемося до його визначення:

– мікросхема, призначена керувати електронними пристроями, чи інакше – простенький комп'ютер (мікро-ЕОМ), здатний виконувати нескладні завдання.

Тобто, по суті, мікроконтролер - це пристрій, що дозволяє втілити в життя наші ідеї (навіть марення), але, природно, в межах своїх можливостей. І найголовніше, втілення ідеї в життя досягається не створенням наворочених електронних конструкцій, а тільки, в основному, силою нашої думки (бажаєте стати чарівником?).
Найбільшою популярністю у радіоаматорів користуються два види мікроконтролерів:
PIC- Фірми Microchip Technology
AVR– фірми Atmel

Відразу хочу зробити невеликий відступ і пояснити свою позицію. Я не збираюся ні зараз, ні потім, міркувати про переваги того чи іншого виду мікроконтролерів, того чи іншого програмного забезпечення, і взагалі всього, що пов'язано з мікроконтролерами, щось радити, а тим більше нав'язувати читачам. Вся ця справа смаку, особистих уподобань та поставлених кінцевих цілей у вивченні мікроконтролерів. Ну а оскільки "неосяжне - не осягнути", все своє подальше оповідання я вестиму стосовно мікроконтролерів AVR і, не дуже поширеної, але мною улюбленої, програми "Algorithm Builder". У різних типів мікроконтролерів, програм є, звичайно, відмінності, але багато в них і загальне. А пізнавати світ мікроконтролерів ми будемо так, щоб потім отримані знання можна було б без проблем застосувати і до PIC, і до будь-якого програмного забезпечення. І ще раз нагадаю, ця серія статей – моя спроба допомогти тим, хто вперше почув про існування мікроконтролерів і бажає збагнути роботу з ними.

Що потрібно для того, щоб навчитися працювати з мікроконтролерами? Я виділив би кілька, на мій погляд, головних умов:
1. Бажання та наполегливість .
Тут все дуже просто: є бажання – все вийде. А бажання із наполегливістю – взагалі, річ суперська.
2. Знання пристрою мікроконтролера.
Тут не важливі глибокі знання (та може і взагалі не потрібні), але знати, що є на борту мікроконтролера необхідно. Тільки знаючи, з чого складається мікроконтролер, які пристрої в ньому є, їх можливості, як вони працюють – тільки тоді ми зможемо використовувати можливості мікроконтролера на повну котушку.
3. Знання мови програмування та команд управління мікроконтролером.
Як працюватиме мікроконтролер, які завдання ви на нього покладаєте і як він їх виконуватиме, визначається закладеною в нього програмою – програмою яку для мікроконтролера складаєте ви самі. І на цьому пункті ми зупинимося докладніше, щоб розглянути питання, які можуть виникнути в майбутньому.

Програма(У перекладі це слово означає – “припис”) – попередній опис майбутніх подій чи дій.

Наприклад, ми хочемо, щоб мікроконтролер блимав світлодіодом. Просте завдання, але для того, щоб мікроконтролер виконав це завдання, ми попередньо повинні, крок за кроком, описати всі дії мікроконтролера, написати програму, яку він повинен виконати для отримання потрібного нам результату - миготливий світлодіод. Щось на кшталт такого:
♦ Запалити світлодіод:
- налаштувати висновок, до якого підключений світлодіод для роботи на виведення інформації
- подати цей висновок логічний рівень, який дозволить запалити світлодіод
♦ Зачекати деякий час:
- перейти до підпрограми, що формує паузу (яку теж потрібно “розжувати”)
- по виконанню підпрограми паузи повернутися до основної програми
♦ Погасити світлодіод:
- подати на висновок логічний рівень, що гасить світлодіод
і таке інше.
З терміном Програманерозривно пов'язаний інший термін - Алгоритм(як Вовк та Заєць, Том та Джеррі).

Алгоритм- Набір інструкцій, що описують порядок дії для досягнення потрібного результату.

Якщо у програмі ми докладніше прописуємо діїмікроконтролера, то в алгоритмі ми визначаємо порядок діймікроконтролера, на основі яких ми потім створимо програму. За аналогією з наведеним вище прикладом:
♦ Засвітити світлодіод
♦ Зачекати деякий час
♦ Погасити світлодіод
і таке інше.
Таким чином, алгоритм – це попередник програми. І чим ретельно і продумано буде створено алгоритм, тим простіше створюватиме програму.

Отже, програма для мікроконтролера – це послідовність дій мікроконтролера у вигляді набору команд та інструкцій, які він має виконати для досягнення поставлених нами цілей.

Команди для мікроконтролера мають вигляд набору одиниць та нулів:
00110101 011000100
так звані - коди команд,а коди команд – це мова, яка розуміє мікроконтролер. А для того, щоб перекласти наш алгоритм з російської мови на мову мікроконтролера – у ці набори нулів і одиниць, існують спеціальні програми.
Ці програми дозволяють описати порядок роботи для мікроконтролера більш-менш зрозумілою для нас мовою, а потім перекласти цей порядок на мову зрозумілу мікроконтролеру, в результаті чого виходить так званий машинний код- Послідовність команд та інструкцій (ті самі нулі та одиниці) які тільки і розуміє мікроконтролер. Текст програми, написаний програмістом, називається вихідним кодом. Переклад програми з мови програмування (вихідного коду) на мову мікроконтролера (машинний код) здійснюється трансляторами. Транслятор перетворює текст програми на машинні коди, які потім записуються на згадку про мікроконтролера.
У таких програмах порядок роботи мікроконтролера описується спеціальною мовою – мовою програмування. Мова програмування відрізняється від нашої, людської мови. Якщо наша мова спілкування служить в основному для того, щоб обмінюватися інформацією, то:

Мова програмування – це спосіб передачі команд, інструкцій, чіткого керівництва до дії мікроконтролера.

Існує безліч мов програмування і їх можна поділити на два типи:
мови програмування низького рівня
мови програмування високого рівня
Чим вони відрізняються. А відрізняються вони своєю близькістю до мікроконтролера.
На зорі зародження мікропроцесорної техніки програми писали в машинних кодах, тобто весь алгоритм роботи послідовно прописували у вигляді нулів і одиниць. Ось так, наприклад, виглядала програма:

01000110
10010011
01010010

Навряд чи хтось зможе розібратися в такому наборі комбінацій із двох цифр, а праця перших програмістів була дуже трудомісткою. Для полегшення свого життя програмісти і стали створювати перші мови програмування. Так ось, чим ближче мова програмування до такого набору нулів і одиниць тим більше він "низького рівня", а чим далі від них - тим більше "високого рівня".
Найпоширеніші мови програмування для мікроконтролерів:
- мова низького рівня - Асемблер
– мова високого рівня – С (Сі)
Давайте подивимося на прикладі їхньої відмінності (ці приклади абстрактні).
Допустимо нам треба скласти два числа: 25 та 35.
У машинних кодах ця команда може мати такий вигляд:
00000101 1101001
Мовою низького рівня:
ADD Rd, Rr
Мовою високого рівня:
25+35
Різниця мов низького та високого рівня видно неозброєним оком, коментарі, як кажуть, зайві.
Але давайте копнемося в цих прикладах глибше. Приклад машинного коду не будемо розбирати, оскільки він ідентичний прикладу на Асемблері. За своєю суттю, асемблерні команди це ті ж машинні коди (команди) яким просто, щоб не заблукати в нулях і одиницях, присвоєні буквені абревіатури. Асемблерною командою ADD Rd, Rr ми ставимо мікроконтролеру завдання скласти два числа, які знаходяться (а для цього ми повинні їх записати туди попередньо) – перше в Rd, друге в Rr, а результат додавання помістити в Rd. Як бачите, ми ставимо дуже конкретне завдання мікроконтролеру: де взяти, що з цим зробити і куди помістити результат. І тут ми працюємо безпосередньо з микроконтроллером.
Команда мовою високого рівня: 25+35, звична для нас математична запис, що тішить наше око. Але в цьому випадку ми не працюємо безпосередньо з мікроконтролером, ми просто ставимо йому завдання скласти два числа. Результат і послідовність дій в даному випадку буде той же, що і при виконанні асемблерної команди: спочатку ці два числа будуть кудись записані, потім складені а результат кудись поміщений.
І ось тут криється головна відмінність мов високого та низького рівня. Якщо в Асемблері ми контролюємо весь процес (хочемо ми того, чи ні): ми знаємо де записані ці два числа, і ми знаємо де буде результат, то в мові високого рівня ми процес не контролюємо. Програма сама вирішує куди заздалегідь записати числа і куди помістити результат. Найчастіше нам це і не треба знати, адже для нас головне підсумок – число 60 на виході. Як результат, програми на мовах високого рівня більш читані, приємні для ока і менше за розміром - адже нам не доводиться "лізти в усі дірки" і розписувати кожен крок мікроконтролера, програма це робить потім за нас, коли компілює її - перекладає в машинні коди . Але тут є мінус. Два однакових алгоритму написаних на Ассемблері та на Сі, після перетворення їх у машинні коди матимуть різний розмір: програма написана на Ассемблері буде на 20-40% коротше програми написаної на Сі – чорт його знає, яким шляхом йде Сі для досягнення потрібного нам результату . І трапляються випадки, коли немає довіри до мови високого рівня і в програмі на Сі роблять вставки коду, написані на Асемблері.
Професійні програмісти, як правило, знають кілька мов програмування (або працюють у команді, в якій є фахівці з різних мов), творчо поєднуючи їхні можливості та переваги в одній програмі. Ну а нам, любителям, треба знати хоча б одну мову (для початку), і починати треба (а я в цьому твердо впевнений, і ніхто мене не переконає) з язика низького рівня – Асемблера.

Ну що, я думаю, і тут нам все зрозуміло, – мову програмування вивчати треба, інакше – ніяк.

Команди та інструкції для керування мікроконтролером.
У мікроконтролерів AVR більше 130 різних команд, які дозволяють йому реалізувати всі закладені у ньому можливості. Але одразу скажу – мало хто з аматорів знає їх усе і тим більше користується всіма. Зазвичай, у аматорській практиці вистачає знання та половини команд, а то й менше. Але вивчати команди треба. Чим більше команд ви будете знати, тим витонченіші (у хорошому сенсі слова) та елегантніші програми будуть виходити.

Арифметико-логічний пристрій та організація пам'яті – пам'ять програм, пам'ять даних, енергонезалежна пам'ять


Я не раз і не два говорив, що вивчення МК треба починати з асемблера. Цьому було присвячено цілий курс на сайті (правда він не дуже послідовний, але поступово я його зачісую до адекватного вигляду). Так, це складно, результат буде не в перший день, зате ти навчишся розуміти що відбувається у тебе в контролері. Знатимеш як це працює, а не по мавпій копіювати чужі вихідники і намагатися зрозуміти чому воно раптом перестало працювати. Крім того, Сі набагато простіше наробити бидлокода, який вилізе вилами в невідповідний момент.

На жаль, всі хочуть результат негайно. Тому я вирішив піти з іншого боку — зробити взутку Сі, але з показом його нижньої білизни. Хороший програміст-ембеддер завжди міцно тримає свою залізницю за шкварник, не даючи їй ні кроку ступити без дозволу. Так що буде спочатку Сі код, потім те, що народив компілятор і як все це працює насправді:)

З іншого боку, у Сі сильна сторона це переносимість коду. Якщо, звісно, ​​писати все правильно. Поділяючи алгоритми роботи та їх залізні реалізації у різні частини проекту. Тоді для перенесення алгоритму в інший МК достатньо буде переписати лише інтерфейсний шар, де прописано все звернення до заліза, а весь робочий код залишити як є. І, звичайно ж, читальність. Сишний вихідник простіше зрозуміти з першого погляду (хоча ... мені, наприклад, вже пофігу на що фтикати - хоч си, хоч асм:)), але, знову ж таки, якщо правильно все написати. Цим моментам я теж приділятиму увагу.

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

Перша програма на Сі для AVR

Вибір компілятора та встановлення середовища
Для AVR існує безліч різних компіляторів:
Насамперед це IAR AVR C- майже однозначно визнається найкращим компілятором для AVR, т.к. сам контролер створювався тісному співробітництві Atmel і фахівців з IAR. Але за все доводиться платити. І цей компілятор мало того, що є дорогим комерційним софтом, так ще володіє такою прорвою налаштувань, що просто взяти й скомпилити в ньому треба постратися. У мене з ним правда не зрослося дружби, проект загнивав на дивних помилках на етапі лінківки (пізніше з'ясував, що це був кривий кряк).

Другим йде WinAVR GCC— потужний компілятор, що оптимізує. Повний опенсорц, кросплатформний, загалом, усі радощі життя. Ще він відмінно інтегрується в AVR Studio дозволяючи вести налагодження прямо там, що дуже зручно. Загалом я вибрав його.

Також є CodeVision AVR C- дуже популярний компілятор. Став популярним у зв'язку зі своєю простотою. Робочу програму в ньому отримати можна вже за кілька хвилин — майстер стартового коду цьому дуже сприяє, штампуючи стандартині ініціалізації будь-яких уартів. Чесно кажучи, я якось з підозрою до нього ставлюся - якось доводилося дизасміть прогу написану цим компілером, каша якась а не код виходила. Жахлива кількість непотрібних рухів тіла і операцій, що виливалося в неслабкий об'єм коду і повільну швидкодію. Втім, можливо, тут була помилка в ДНК, що писав вихідну прошивку. Плюс він хоче грошей. Не так багато, як IAR, але відчутно. А в деморежимі дає писати не більше ніж 2кб коду.
Кряк звичайно є, але якщо вже красти, то мільйон, у сенсі IAR:)

Ще є Image Craft AVR Cі MicroCвід мікроелектроніки Ні тим, ні іншим користуватися не доводилося, але ось SWGдуже вже нахвалює MicroPascal, мовляв, дуже зручне середовище програмування та бібліотеки. Думаю, MicroC не гірше буде, але теж платний.

Як я вже сказав, я вибрала WinAVRз трьох причин: халявний, інтегрується в AVR Studio і під нього написана просто прорва готового коду на всі випадки життя.

Так що качай собі інсталях WinAVR з і AVR Studio. Далі спочатку ставиться студія, потім зверху накочується WinAVR і чіпляється до студії у вигляді плагіна. Наполегливо рекомендую ставити WinAVR коротким шляхом, щось на кшталт C:WinAVR тим самим ти уникнеш купи проблем з шляхами.

Створення проекту
Отже, студія поставлена, Сі прикручений, пора б і спробувати щось запрограмувати. Почнемо з простого, найпростішого. Запускай студію, вибирай там новий проект як компілятор AVR GCC і вписуй назву проекту.

Відкриється робоче поле з порожнім файлом *.c.

Тепер не завадить настроїти відображення шляхів у закладках студії. Для цього злазь за адресою:
Меню Tools - Options - General - FileTabs і вибираємо у випадаючому списку "Filename Only". Інакше працювати буде неможливо - на вкладці буде повний шлях файлу і на екрані буде не більше двох вкладок.

Налаштування проекту
Взагалі, класичним вважається створення make файлу в якому були б описані всі залежності. І це, мабуть, правильно. Але мені, який виріс на повністю інтегрованих IDE начебто uVisionабо AVR Studioцей підхід є глибоко чужим. Тому робитиму за своїм, усе засобами студії.

Тикай у кнопку з шестернею.


Це налаштування твого проекту, а точніше, налаштування автоматичної генерації make файлу. На першій сторінці треба лише вписати частоту на якій працюватиме твій МК. Це залежить від ф'юз бітів, так що вважаємо, що частота у нас 8000000Гц.
Також зверніть увагу на рядок оптимізації. Зараз там стоїть -Os це оптимізація за розміром. Поки залиш як є, потім можеш спробувати погратися з цим параметром. -O0 це відсутність оптимізації взагалі.

Наступним кроком буде налаштування шляхів. Насамперед додай туди директорію твого проекту — туди підкладатимеш сторонні бібліотеки. У списку з'явиться шлях ".\"

Make файл згенерований, його ти можеш подивитися в папці default у своєму проекті, просто пробігайся очима, подивися що там є.


На цьому поки що все. Тисни скрізь ОК і переходь у вихідник.

Постановка задачі
Чистий лист так і підмиває втілити якусь хитру задумку, так як банальне миготіння діодом вже не вставляє. Давай вже відразу брати бика за роги і реалізуємо зв'язок з комп'ютером - це насамперед що я роблю.

Працюватиме так:
При приході по COM порту одиниці (код 0х31) запалюватимемо діодик, а при приході нуля (код 0х30) гаситимемо. Причому зроблено буде все на перериваннях, а фоновим завданням буде блимання іншого діода. Просто і з сенсом.

Збираємо схему
Нам треба з'єднати модуль USB-USART конвертера з висновками USART мікроконтролера. Для цього беремо перемичку з двох проводків і накидаємо на штирьки навхрест навхрест. Тобто Rx контролера з'єднуємо з Tx конвертером, а Tx конвертером з Rx контролером.

Вийде, у результаті ось така схема:


Підключення решти висновків, харчування, скидання не розглядаю, воно стандартне

Пишемо код

Відразу обмовлюся, що я не заглиблюватимусь конкретно в опис самої мови Сі. Для цього існує колосальна кількість матеріалу, починаючи від класики «Мова програмування Сі» від K&R і закінчуючи різними методичками.

Одна така методу знайшлася у мене в загашнику, я колись саме по ній вивчав цю мову. Там усе коротко, зрозуміло й у справі. Я її поступово верстаю та перетягую на свій сайт.

Там, правда, ще не всі глави перенесені, але, думаю, це ненадовго.

Навряд чи я опишу краще, тому з навчального курсу, замість докладного роз'яснення сишних тонкощів, я просто даватиму прямі лінки на окремі сторінки цієї методички.

Додаємо бібліотеки.
Насамперед ми додаємо потрібні бібліотеки та заголовки з визначеннями. Адже Сі це універсальна мова і йому треба пояснити, що ми працюємо саме з AVR, так що вписуй у вихідний рядок:

1 #include

#include

Цей файл знаходиться в папці WinAVRі в ньому міститься опис усіх регістрів та портів контролера. Причому там все хитро, з прив'язкою до конкретного контролера, який передається компілятором через makeфайл у параметрі MCUі на підставі цієї змінної в твій проект підключається заголовний файл з описом адрес всіх портів і регістрів саме на цей контролер. Ось як! Без нього теж можна, але тоді ти не зможеш використовувати символічні імена регістрів на кшталт SREG або UDR і доведеться пам'ятати адресу кожного на кшталт «0xC1», а це зламати голову.

Сама ж команда #include<имя файла> дозволяє додати у твій проект вміст будь-якого текстового файлу, наприклад, файл з описом функцій або шматок іншого коду. А щоб директива могла цей файл знайти ми і вказували шляхи до нашого проекту (директорія WinAVR там уже прописана по дефолту).

Головна функція.
Програма мовою Сі вся складається з функцій. Вони можуть бути вкладеними і викликатись один з одного в будь-якому порядку та різними способами. Кожна функція має три обов'язкові параметри:

  • Значення, що повертається, наприклад, sin(x)повертає значення синусу ікс. Як у математиці, коротше.
  • Параметри, що передаються, цей ікс.
  • Тіло функції.

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

Будь-яка програма на Сі повинна містити функцію mainяк точку входу в головну програму, інакше це ніфіга не Сі:). За наявності main в чужому вихіднику з мільйона файлів можна зрозуміти, що це і є головна частина програми, звідки починається все. Ось і поставимо:

1 2 3 4 5 int main (void) (return 0;)

int main(void) ( return 0; )

Все, перша найпростіша програма написана, не біда, що вона нічого не робить, ми ж тільки почали.

Розберемо що ми зробили.
intце тип даних, яка функція main повертає.

Звичайно, у мікроконтролері mainнічого повернути в принципі не може і за ідеєю має бути void main(void), але GCC спочатку заточений на PC і там програма може повернути значення операційної системи після завершення. Тому GCC на void main(void)лається Warning'ом.

Це не помилка, працюватиме, але я не люблю варнінги.

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

Ось такі { } фігурні дужки це програмний блок, в даному випадку тіло функції main, там буде розміщуватися код.

return— це значення, що повертається, яке функція main віддасть при завершенні, оскільки у нас int, тобто число то повернути ми повинні число. Хоча це однаково немає сенсу, т.к. на мікроконтролері з main нам виходити хіба що нікуди. Я повертаю нуль. Бо нефіг. А компілятор зазвичай розумний і цього випадку код не генерує.
Хоча, якщо перекрутитися, то з mainна МК вийти можна - наприклад вивалитися в секцію бутлоадера і виконати її, але тут вже знадобиться низькорівневе колупання прошивки, щоб підправити адреси переходу. Нижче ти сам побачиш і зрозумієш, як це зробити. Навіщо? Ось це вже інше питання, у 99.999% випадків це нафіг не треба:)

Зробили, поїхали далі. Додамо змінну, вона нам не особливо потрібна і без потрібні вводити змінні не варто, але ж ми вчимося. Якщо змінні додаються всередині тіла функції, то вони локальні і існують тільки в цій функції. Коли з функції виходиш ці змінні видаляються, а пам'ять ОЗУ віддається під найважливіші потреби. .

1 2 3 4 5 6 int main(void ) ( unsigned char i; return 0 ; )

int main(void) ( unsigned char i; return 0; )

unsignedзначить беззнаковий. Справа в тому, що в двійковому поданні у нас старший біт відводиться під знак, а значить, в один байт (char) влазить число +127/-128, але якщо знак відкинути то влізе вже від 0 до 255. Зазвичай знак не потрібен. Так що unsigned.
i— це лише ім'я змінної. Не більше.

Тепер треба проініціалізувати порти та UART. Звичайно, можна взяти і підключити бібліотеку і викликати якийсь UartInit (9600); але тоді ти не дізнаєшся, що сталося насправді.

Робимо так:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int main(void ) ( unsigned char i; #define XTAL 8000000L #define baudrate 9600L #define bauddivider (XTAL/(16*baudrate)-1)#define HI(x) ((x)>>8) #define LO(x) ((x)& 0xFF) UBRRL = LO(bauddivider) ; UBRRH = HI (bauddivider); UCSRA = 0; UCSRB = 1<< RXEN| 1 << TXEN| 1 << RXCIE| 0 << TXCIE; UCSRC = 1 << URSEL| 1 << UCSZ0| 1 << UCSZ1; }

int main(void) ( unsigned char i; #define XTAL 8000000L #define baudrate 9600L #define bauddivider (XTAL/(16*baudrate)-1) #define HI(x) ((x)>>8) #define LO( x) ((x)& 0xFF) UBRRL = LO(bauddivider);<

Страшна? Насправді реалного коду тут лише п'ять останніх рядків. Все що #defineце макромова препроцесора. Майже те ж бадилля, що і в Асемблері, але синтаксис дещо інший.

Вони полегшать твої рутинні операції з обчислення потрібних коефіцієнтів. У першому рядку ми говоримо, що замість XTALможна сміливо підставляти 8000000, а L- Вказівка ​​типу, мовляв long - це тактова частота процесора. Те ж саме baudrate- Частота передачі даних по UART.

bauddividerвже складніше, замість нього буде підставлятись вираз обчислений за формулою з двох попередніх.
Ну, а LOі HIцього результату візьмуть молодший і старший байти, т.к. в один байт воно може не влізти. У HIробиться зсув ікса (вхідний параметр макросу) вісім разів направо, в результаті від нього залишиться лише старший байт. А в LOми робимо побітове І з числом 00FF, в результаті залишиться лише молодший байт.

Так що все, що зроблено як #defineможна сміливо викинути, а потрібні числа підрахувати на калькуляторі і відразу ж вписати в рядки UBBRL = …. та UBBRH = …..

Можна. Але! Робити цього КАТЕГОРИЧНО НЕ МОЖНА!

Працюватиме і так і так, але в тебе в програмі з'являться так звані магічні числа— значення взяті незрозуміло звідки й незрозуміло навіщо і якщо ти через пару років відкриєш такий проект, то зрозуміти що це за значення буде дуже важко. Та й зараз, захочеш ти змінити швидкість, або зміниш частоту кварцу і все доведеться перераховувати заново, а так змінив пару циферок у коді і все саме. Загалом, якщо не хочеш уславитися бидлодером, то роби код таким, щоб він легко читався, був зрозумілий і легко модифікувався.

Далі все просто:
Всі ці "UBRRL і C" це регістри конфігурації UART передавача за допомогою якого ми будемо спілкуватися зі світом. І зараз ми надали їм потрібні значення, налаштувавши на потрібну швидкість і потрібний режим.

Запис виду 1<Це означає: взяти 1 і поставити її на місце RXENу байті. RXENце 4й біт регістру UCSRB, так що 1<утворює двійкове число 00010000, TXEN— це третій біт, а 1<дасть 00001000. Поодинока «|» це побітове АБО, Отже 00010000 | 00001000 = 00011000. Таким же чином виставляються і додаються в загальну купу інші необхідні біти конфігурації. У результаті зібране число записується в UCSRB. Докладніше розписано в датасіті на МК в розділі USART. Тож не відволікаємось на технічні деталі.

Готово, настав час подивитися що вийшло. Тисніть на компіляцію та запуск емуляції (Ctrl+F7).

Налагодження
Пробігли всілякі прогреси, студія змінилася і біля входу в функцію main з'явилася жовта стрілочка. Це де процесор в даний момент, а симуляція на паузі.

Справа в тому, що спочатку, насправді, вона стояла на рядку UBRRL = LO (bauddivider); Адже те, що у нас в define це не код, а просто попередні обчислення, ось симулятор трохи і затупив. Але тепер він усвідомив, першу інструкцію виконано і якщо ти залізеш у дерево I/O View, в розділ USART і подивишся там на байт UBBRL то побачиш, що там значення вже є! 0х33.

Зроби ще один крок. Подивись як зміниться вміст іншого регістру. Так пройди їх усі, зверни увагу на те, що всі зазначені біти виставляються як я тобі і говорив, причому виставляються одночасно для всього байта. Далі Return справа не піде – програма скінчилася.

Розтин
Тепер скинь симуляцію у нуль. Натисніть там Reset (Shift+F5). Відкривай дизассембльований лістинг, зараз ти побачиш, що відбувається в контролері насправді. View -> Disassembler. І не ЫЫАААА! Асемблер! ЖАХ!!! А ТРЕБА. Щоб потім, коли щось піде не так, не тупив у код і не ставив ламерських питаннях на форумах, а відразу ж ліз у тельбухи і дивився де в тебе затик. Нічого страшного там немає.

Спочатку буде бадилля із серії:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 +00000000: 940C002A JMP 0x0000002A Jump +00000002: 940C0034 JMP 0x00000034 Jump 00000004: 940C0034 0x00000034 Jump +00000008: 940C0034 JMP 0x00000034 Jump +0000000A: 940C0034 JMP 0x00000034 Jump +0000000C: 940C00 0000000E: 940C0034 JMP 0x00000034 Jump +00000010: 940C0034 JMP 0x00000034 Jump +00000012: 940C0034 JMP 0x00000034 Jump +00000014: 940C0034 JMP 0x00000034 Jump +00000016: 940C0034 JMP 0x00000034 Jump +00000018: 940C0034 JMP 0x00000034 Jump +0000001A: 940C0034 JMP 0x00000034 Jump +0000001C : 940C0034 JMP 0x00000034 Jump +0000001E: 940C0034 JMP 0x00000034 Jump +00000020: 940C0034 JMP 0x00000034 Jump +00 034 Jump +00000024: 940C0034 JMP 0x00000034 Jump +00000026: 940C0034 JMP 0x00000034 Jump +00000028: 940C0034 JMP00

00000000: 940C002A JMP 0x0000002A Jump +00000002: 940C0034 JMP 0x00000034 Jump +00000004: 940C0034 JMP 0x00000034 Jump +00000006: 940C0034 JMP 0x00000034 Jump +00000008: 940C0034 JMP 0x00000034 Jump +0000000A: 940C0034 JMP 0x00000034 Jump +0000000C: 940C0034 JMP 0x00000034 Jump +0000000E : 940C0034 JMP 0x00000034 Jump +00000010: 940C0034 JMP 0x00000034 Jump +00000012: 940C0034 JMP 0x00000034 Jump +00 034 Jump +00000016: 940C0034 JMP 0x00000034 Jump +00000018: 940C0034 JMP 0x00000034 Jump +0000001A: 940C0034 JMP00 940C0034 JMP 0x00000034 Jump +0000001E: 940C0034 JMP 0x00000034 Jump +00000020: 940C0034 JMP 0x00000034 Jump +0000 4 Jump +00000024: 940C0034 JMP 0x00000034 Jump +00000026: 940C0034 JMP 0x00000034 Jump +00000028: 940C0034 JMP 0x0

Це таблиця векторів переривань. До неї ми ще повернемося, поки просто подивися і запам'ятай, що вона є. Перша колонка - адреса осередку флешу в якій лежить команда, друга код команди третя мнемоніка команди, та сама асемблерна інструкція, третя операнди команди. Та й автоматичний комент.
Так от, якщо ти подивишся, то тут суцільні переходи. А код команди JMP чотирьох байтний, у ньому міститься адреса переходу, записана задом наперед - молодший байт за молодшою ​​адресою та код команди переходу 940C

0000002B: BE1F OUT 0x3F,R1 Перейти до I/O location

Запис цього нуля на адресу 0x3F, Якщо ти подивишся в колонку I/O view, то побачиш що адресу 0x3F це адреса регістра SREG — прапорового регістру контролера. Тобто. ми обнулюємо SREG, щоб запустити програму на нульових умовах.

1 2 3 4 +0000002C: E5CF LDI R28,0x5F Load immediate +0000002D: E0D4 LDI R29,0x04 Load immediate +0000002E: BFDE OUT 0x3E,R29 I/O location +00000002

0000002C: E5CF LDI R28,0x5F Load immediate +0000002D: E0D4 LDI R29,0x04 Load immediate +0000002E: BFDE OUT 0x3E,R29 На I/O location +00000002

Це завантаження покажчика стека. Безпосередньо вантажити в I/O регістри не можна, тільки через проміжний регістр. Тому спочатку LDI проміжний, а потім звідти OUT в I/O. Про стеку я також розповім детальніше. Поки знай, що це така динамічна область пам'яті, висить в кінці ОЗУ і зберігає в собі адреси і проміжні змінні. Ось зараз ми вказали на те, звідки у нас починатиметься стек.

00000032: 940C0041 JMP 0x00000041 Jump

Стрибок у сааааамий кінець програми, а там у нас заборона переривань і зациклювання наглухо саме на себе:

1 2 +00000041: 94F8 CLI Global Interrupt Disable +00000042: CFFF RJMP PC-0x0000 Relative jump

00000041: 94F8 CLI Global Interrupt Disable +00000042: CFFF RJMP PC-0x0000 Relative jump

Це випадок непередбачених обставин, наприклад виходу з функції main. З такого зациклювання контролер можна вивести або апаратним скиданням, або, ймовірно, скиданням від сторожового собаки - watchdog. Ну або, як я говорив вище, підправити це місць у хекс редакторі і поїхати куди нам душі завгодно. Також зверніть увагу на те, що буває два типи переходів JMP і RJMP перший це прямий перехід за адресою. Він займає чотири байти і може зробити прямий перехід по всій області пам'яті. Другий тип переходу – RJMP – відносний. Його команда займає два байти, але перехід він робить від поточного положення (адреси) на 1024 кроки вперед або назад. І його параметрах вказується зміщення від поточної точки. Використовується найчастіше, т.к. займає вдвічі менше місця у флеші, а довгі переходи потрібні рідко.

1 +00000034: 940C0000 JMP 0x00000000 Jump

00000034: 940C0000 JMP 0x00000000 Jump

А це стрибок на початок коду. Перезавантаження свого роду. Можеш перевірити, чи всі вектори стрибають сюди. З цього висновок — якщо ти зараз дозволиш переривання (вони дефолтом заборонені) і в тебе переривання пройде, а обробника немає, то буде програмне скидання — програму кине на початок.

Функція main. Все аналогічно навіть можна і не описувати. Подивися щойно до регістру заноситься вже обчислене число. Препроцесор компілятора рулить! Тож жодних «магічних» чисел!

1 2 3 4 5 6 7 8 9 10 11 12 <

00000036: E383 LDI R24,0x33 Load immediate +00000037: B989 OUT 0x09,R24 Перейти до I/O location 15: UBRRH = HI(bauddivider); +00000038: BC10 OUT 0x20,R1 Перейти до I/O location 16: UCSRA = 0; +00000039: B81B OUT 0x0B,R1 Перейти до I/O location 17: UCSRB = 1<

А ось тут косяк:

1 2 3 +0000003E: E080 LDI R24,0x00 Load immediate +0000003F: E090 LDI R25,0x00 Load immediate +00000040: 9508 RET Subroutine return

0000003E: E080 LDI R24,0x00 Load immediate +0000003F: E090 LDI R25,0x00 Load immediate +00000040: 9508 RET Subroutine return

Постає питання, навіщо це компілятор додає таке бадилля? А це не що інше, як Return 0, функцію ми визначили як int main(void) ось і просрали ще цілих чотири байти не зрозумій на що:) А якщо зробити void main(void) то залишиться тільки RET, але з'явиться варнінг, що мовляв, у нас функція main нічого не повертає. Загалом, роби як хоч:)

Важко? Начебто ні. Пощелкай покрокове виконання в режимі дизассемблера і пози як процесор виконує окремі інструкції, що при цьому відбувається з регістрами. Як відбувається переміщення по командам та підсумкове зациклювання.

Продовження слідує через пару днів.

Offtop:
Alexei78зварганив плагінчик для файрфокса, що полегшує навігацію по моєму сайту та форуму.
Обговорення та скачування,


Сучасне радіоаматорство неможливо уявити без мікроконтролерів, і це очевидно. В останні десятиліття мікроконтролери різних виробників стали поширені у різних сферах діяльності. Нерідко їх можна зустріти в найнесподіваніших пристроях та конструкціях. Ми з вами є свідками комп'ютеризації та автоматизації навколишніх процесів. Істина така, що без знання основ програмування створювати сучасні конкурентоспроможні пристрої стало практично неможливо.

Якщо ви читаєте цю статтю, можливо у вас виникло бажання зрозуміти, як працюють мікроконтролери, і швидше за все постали питання:

4. Яку літературу вивчати?

Спробуємо відповісти на ці запитання.

1. Який мікроконтролер вибрати для роботи?

Великою популярністю у радіоаматорів користуються 8-бітові мікроконтролери PICфірми Microchip Technology та AVRфірми Atmel, 16-бітові MSP430фірми TI, а також 32-бітові мікроконтролери, архітектури ARM.

У промисловості, дещо інакше, перше місце з великим відривом посідає Renesas Electronicsна другому Freescale, на третьому Samsungпотім йдуть Microchipі TI, Далі всі інші.
Популярність визначається ціною та доступністю, чималу роль відіграють наявність технічної інформації та вартість програмного супроводу.

Ми вивчатимемо 8-бітні мікроконтролери AVR, сімейства ATMEGA 8 та 16 серії. Вибір визначився, знову ж таки доступністю, наявністю безлічі аматорських розробок, величезною кількістю навчального матеріалу. Наявністю різноманітних вбудованих компонентів та функціональністю цього сімейства.

2. Яке середовище розробки використовуватиме програмування обраного мікроконтролера?

Для AVR створено різні інтегровані середовища розробки (IDE, Integrated development environment).
IDE– це система програмних засобів, що використовується програмістами для розробки програмного забезпечення (ПЗ), до складу якої входять:
текстовий редактор,
компілятор та/або інтерпретатор,
засоби автоматизації складання,
відладчик.

Найбільш поширені з них AVRStudio, ATmelStudio, WINAVR, CodeVision, IAR Embedded Workbench.
Для того, щоб писати програми, ми скористаємося безкоштовною IDE ATmelStudio версії 6та вище.
Завантажити Atmel Studio можна з офіційного сайту після реєстрації (реєстрація абсолютно безкоштовна і нічого не зобов'язує!)

ATmelStudio дозволяє створювати проекти і писати програми як в асемблері, так і на СІ.

Спочатку завжди постає питання: яку мову програмування вибрати, щоб писати ефективні програми?

Відповім просто: потрібно вміти писати як мінімум двома мовами асемблері та СІ. Асемблер просто необхідний, коли потрібно написати швидкі та компактні підпрограми та макроси, різні драйвери пристроїв. Але, коли потрібно створити об'ємний проект, побудований на складних алгоритмах, без знання СІ може бути витрачено дуже багато часу, особливо в процесі налагодження, а якщо виникне бажання перенести на іншу платформу, наприклад PIC18 або STM, може стати нерозв'язною проблемою.
Окрім цього, зараз з'явилися апаратні обчислювальні платформи Arduino, робота з якими вимагає знання мови СІ++
Тому писатимемо програми як в асемблері, так і на СІ.

Щоб наочно бачити результат своєї роботи, не використовуючи паяльник чи макетну плату достатньо встановити програму Proteus.

3. Як прошивати контролер і які додаткові прилади та аксесуари потрібні для зручної роботи з ними?

Використовуємо датагорську. Крім цього, потрібно буде придбати макетні плати, блок живлення із вихідною напругою 5 Вольт. Можна як БП з малими пульсаціями використовувати, застосувавши стабілітрон на 5 Вольт.
Можливо, згодом ми з Ігорем запропонуємо проект для складання налагоджувальної плати.

4. Яку літературу вивчати?

А ось, наприклад:
Практичне програмування AVR на асемблері. Ревіч, 2011
1000 та одна мікроконтролерна схема Вип. 1-2. Рюмік, 2010-2011
10 практичних пристроїв на МК AVR Книжка 1-2. Кравченка, 2008-2009
Самовчитель розробника пристроїв на МК AVR. Бєлов, 2008
МК AVR сімейств Tiny та Atmega. Єфстіфєєв, 2008
CodeVisionAVR. Посібник для початківців. Лебедєв, 2008
Мікропроцесорне керування пристроями, тиристори, реле. Бєлов, 2008
Аналогові інтерфейси МК. Стюард, Болл, 2007
Створюємо пристрої на МК AVR. Бєлов, 2007
МК AVR у радіоаматорській практиці. Повний аналіз ATTINY2313. Бєлов, 2007
Мережевий та міжмережевий обмін даними з МК. Іди, 2007
МК AVR. практикум для початківців. Хартів, 2007
Схеми, алгоритми, програми. Баранів, 2006
Мікроконтролери AVR. Вступний курс. Мортон, 2006
Вимірювання, керування та регулювання за допомогою AVR. Трамперт, 2006
Програмування мовою С для AVR та PIC МК. Шпак, 2006
Конструювання пристроїв на МК. Бєлов, 2005
МK - це просто, томи 1-3. Фрунзе, 2002-2003
Мова програмування Сі, 2-ге видання. Керніган, Рітчі, 2009
Програмування мікроконтролерів ATMEL мовою С. Прокопенко, 2012

5. Де в інтернеті можна ставити запитання та отримувати конкретні відповіді?

Запитувати ви можете на нашому або будь-якому іншому форумі, де так чи інакше торкнулися теми з мікроконтролерів. Головне на форумах правильно формулювати питання, щоб чітко отримувати відповіді. Абстрактні питання не вітаються, і швидше за все замість відповіді ви отримаєте жорстку критику, або ваше питання залишиться поза увагою!

Тепер розглянемо ближче нашого лідера, мікроконтролер ATMEGA 8

8-розрядний високопродуктивний AVR мікроконтролер із малим споживанням
Прогресивна RISC архітектура
130 високопродуктивних команд, більшість команд виконується за один тактовий цикл
32 8-розрядних робітників регістру загального призначення
Повністю статична робота
продуктивність, що наближається до 16 MIPS (при тактовій частоті 16 МГц)
Вбудований 2-цикловий перемножувач

Енергонезалежна пам'ять програм та даних
8 Кбайт внутрішньосистемно програмованої Flash пам'яті (In-System Self-Programmable Flash)
Забезпечує 1000 циклів стирання/запису
Додатковий сектор завантажувальних кодів із незалежними бітами блокування
Забезпечено режим одночасного читання/запису (Read-While-Write)
512 байт EEPROM
Забезпечує 100000 циклів стирання/запису
1 Кбайт вбудованої SRAM
Програмоване блокування, що забезпечує захист програмних засобів користувача

Вбудована периферія
Два 8-розрядні таймери/лічильники з окремим попереднім дільником, один з режимом порівняння
Один 16-розрядний таймер/лічильник з окремим попереднім дільником та режимами захоплення та порівняння
Лічильник реального часу з окремим генератором
Три канали PWM
8-канальний аналого-цифровий перетворювач (у корпусах TQFP та MLF)
6 каналів із 10-розрядною точністю
6-канальний аналого-цифровий перетворювач (у корпусі PDIP)
4 канали з 10-розрядною точністю
2 канали з 8-розрядною точністю
Байт-орієнтований 2-провідний послідовний інтерфейс
Програмований послідовний USART
Послідовний інтерфейс SPI (провідний/відомий)
Програмований сторожовий таймер з окремим вбудованим генератором
Вбудований аналоговий компаратор

Спеціальні мікроконтролерні функції
Скидання подачі живлення та програмований детектор короткочасного зниження напруги живлення
Вбудований калібрований RC-генератор
Внутрішні та зовнішні джерела переривань
П'ять режимів зниженого споживання: Idle, Power-save, Power-down, Standby та зниження шумів ADC

Висновки I/O та корпусу
23 програмовані лінії введення/виводу
28-вивідний корпус PDIP, 32-вивідний корпус TQFP та 32-вивідний корпус MLF

Робоча напруга
2,7 - 5,5 В (ATmega8L)
4,5 - 5,5 (ATmega8)

Робоча частота
0 - 8 МГц (ATmega8L)
0 - 16 МГц (ATmega8)

відмінності ATMEGA16 від 8
16 Кбайт внутрішньосистемно програмованої Flash пам'яті (In-System Self-Programmable Flash)

Інтерфейс JTAG (сумісний із IEEE 1149.1)
Можливість сканування периферії, що відповідає стандарту JTAG
Розширена підтримка вбудованого налагодження
Програмування через JTAG інтерфейс: Flash, EEPROM пам'яті, перемичок та біт блокування

Чотири канали PWM / ШИМ

8-канальний 10-розрядний аналого-цифровий перетворювач
8 несиметричних каналів
7 диференціальних каналів (тільки у корпусі TQFP)
2 диференціальних канали з програмованим посиленням 1, 10 або 200 крат (тільки в корпусі TQFP)

Шість режимів зниженого споживання: Idle, Power-save, Power-down, Standby, Extended Standby та зниження шумів ADC

32 програмовані лінії введення/виводу

40-вивідний корпус PDIP та 44-вивідний корпус TQFP

AtmelStudio

Якщо Ви тільки починаєте, то потрібно завантажити та встановити програму AtmelStudio з офіційної сторінки atmel.com
Після встановлення програми AtmelStudio можна розпочати створення проекту.
Проект– це ваша програма, яку ви писатимете, налагоджуватимете і прошиватимете, після компіляції, на згадку про мікроконтролера.

Щоб створити проект, треба відкрити програму, з'явитися така заставка,

та відкриється сторінка створення проекту

Щоб створити новий проект, потрібно натиснути на "New Project ..."
У цьому випадку відкриється нове вікно, де можна вибрати мову програмування, назву проекту, його місцезнаходження, назву пакета з файлами проекту та можливість створення каталогу для подальшого використання в інших перехресних проектах. Щоб створити проект, де ми програмуватимемо в асемблері, потрібно вибрати - Assembler, після цього змінимо назву проекту, його розташування, і вибираємо ОК.

З'явиться наступне вікно

Вибираємо "megaAVR, 8-bit"і знаходимо потрібний нам мікроконтролер, ми вибрали ATmega8.У правій частині заставки з'являється список пристроїв, які працюють із цим мікроконтролером, один з яких ми можемо підключити. Вибираємо ОК.

З'являється сторінка редактора тексту, яка дозволяє редагувати та налагоджувати програму. Поки сторінка чиста, вказано час і дату створення та назву файлу проекту, ім'я користувача. Існують додаткові вікна пристроїв введення-виводу, вікно звітів компіляції програми. Тепер ми


можемо програмувати в асемблері.
Аналогічно створюється проект для програмування мовою СІ.
gastroguru 2017