Мікроконтролери Atmega8. Програмування Atmega8 для початківців. AVR мікроконтролери. Програмування для початківців Мікроконтролер atmega8 навчання

Грудень 2015 р.

1. Переваги запропонованого способу

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

Здавалося б із цим теж все просто – в інтернеті можна зустріти безліч схем з безкоштовними прошивками. Але тут з'являється одна проблема: прошивку потрібно якось "залити" в мікроконтролер. Для того, хто ніколи цим раніше не займався, таке завдання часто стає проблемою і головним фактором, що відштовхує, нерідко змушує відмовитися від принад використання МК і пошукати схеми на "розсипуху" і жорсткій логіці. Адже все не так вже й складно, як може здатися на перший погляд.

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

Для того, щоб, не маючи програматора, записати в МК програму, нам знадобиться перетворювач порту USB-RS232TTL і , а також . Конвертер USB-RS232TTL дозволяє за допомогою порту USB створити COM-порт, який відрізняється від "справжнього" лише тим, що на його входах та виходах використовуються логічні рівні TTL, тобто напруга в інтервалі від 0 до 5 вольт (докладніше можна почитати у статті " "). Такий конвертер у будь-якому випадку корисно мати в "господарстві", тому якщо у вас його ще немає, неодмінно варто придбати. Що стосується логічних рівнів, то в нашому випадку TTL - це навіть перевага перед звичайним COM-портом, тому що входи та виходи такого порту можна безпосередньо підключати до будь-якого мікроконтролера, що живиться від напруги 5 В, у тому числі ATtiny та ATmega. Але не намагайтеся використовувати стандартний COM-порт - там використовуються напруги в інтервалі від -12 до +12 В (або -15 ... +15В). Безпосереднє з'єднання з мікроконтролером у цьому випадку неприпустимо!

Ідея створення скрипта для програми "Перпетуум М", що реалізує функції програматора, виникла після ознайомлення з рядом публікацій в інтернеті, що пропонують ті чи інші рішення щодо прошивки МК. У кожному випадку виявлялися серйозні недоліки чи надмірні складності. Часто траплялися схеми програматорів, що містять у собі мікроконтролер і при цьому цілком серйозно давалися поради типу: "...а щоб запрограмувати мікроконтролер для цього програматора нам знадобиться... правильно - інший програматор!". Далі пропонувалося сходити до друга, пошукати платну послугуі т.п. Якість програмного забезпечення, що розповсюджується в мережі для цих цілей, також не вразило - помічено безліч проблем як з функціональністю, так і з "каламутністю" інтерфейсу користувача. Найчастіше потрібно витратити, щоб зрозуміти, як використовувати програму - її необхідно вивчати навіть задля здійснення найпростіших дій. Інша програма може довго і старанно щось робити, але про те, що нічого в МК не записується, користувач дізнається тільки після завершення всієї прошивки та наступного контрольного зчитування. Зустрічається і така проблема: користувач намагається вибрати зі списку кристалів, що підтримуються, свій МК, а його в списку немає. У цьому випадку скористатися програмою не вдасться - внесення до списку відсутніх МК, як правило, не передбачено. Крім того, ручний вибір контролера зі списку виглядає дивно, якщо врахувати, що програматор у багатьох випадках може сам визначити тип МК. Все це сказано не для того, щоб облити брудом існуючі продукти, а для того, щоб пояснити причину появи скрипту до програми "Перпетуум М", що описується у цій статті. Проблема дійсно існує, і вона стосується насамперед новачків, яким не завжди вдається подолати цю "стіну", щоб зробити свій перший крок у світ мікроконтролерів. У запропонованому скрипті враховано недоліки, виявлені інших програмах. Реалізовано максимальну "прозорість" роботи алгоритму, гранично простий інтерфейс користувача, що не вимагає вивчення і не залишає шансу заплутатися і "не туди натиснути". За відсутності потрібного МК серед підтримуваних можна самостійно додати його опис, взявши потрібні дані з документації, завантаженої з сайту розробника МК. І, найголовніше - скрипт відкритий для вивчення та модифікації. Кожен охочий може, відкривши в текстовому редакторі, вивчати і правити його на власний розсуд, змінюючи на свій смак існуючі функції і додаючи відсутні.

Першу версію скрипту було створено у червні 2015 року. У цій версії реалізована тільки підтримка Atmel'івських МК серій ATtiny та ATmega з функціями запису/читання флеш-пам'яті, з налаштуванням конфігураційних біт, з автоматичним визначенням типу контролера. Запис та читання EEPROM не реалізовані. Були плани доповнити функціональність скрипту читання EEPROM, реалізувати підтримку PIC-контролерів і т. д. З цієї причини скрипт досі не був опублікований, але через брак часу здійснення задуманого затяглося, і щоб краще не ставало ворогом хорошого, вирішено опублікувати наявну версію. реалізованих функцій виявиться недостатньо, прошу не засмучуватися.У цьому випадку ви можете спробувати самостійно додати потрібну функцію.Не стану приховувати: ідея створення даного скрипту спочатку несе в собі ще й освітній зміст. зможете глибше зрозуміти роботу МК в режимі програмування, щоб у майбутньому не опинитися в становищі дівчини перед автомоблем, що зламався, задумливо розглядає його нутрощі і не розуміє, чому "не їде".

2. Інтерфейс МК як програмування

Існує кілька різних способів перевести контролер у режим програмування та працювати з ним у цьому режимі. Найпростішим у реалізації для контролерів серій ATtiny та ATmega є, мабуть, SPI. Ним і скористаємося.

Але, як розпочати розгляду сигналів, необхідні формування SPI, зробимо ряд застережень. Мікроконтролер має конфігураційні біти. Це щось на кшталт тумблерів, перемикання яких дозволяє змінювати деякі властивості мікросхеми відповідно до потреб проекту. Фізично це осередки енергонезалежної пам'яті, на зразок тих, у які записується програма. Різниця в тому, що їх дуже мало (до трьох байт для ATmega), і вони не входять до адресного простору будь-якої пам'яті. Запис та читання конфігураційних даних виконується окремими командами режиму програмування МК. Зараз важливо відзначити, що деякі конфігураційні біти впливають на можливість використання SPI. При деяких значеннях може виявитися, що SPI не можна використовувати. Якщо вам трапиться такий мікроконтролер, то метод, який пропонується в даній статті, не допоможе. У цьому випадку доведеться або змінити налаштування конфігураційних біт програматорі, який підтримує інший режим програмування, або використовувати інший мікроконтролер. Але ця проблема стосується лише тих, хто був у вживанні МК, або тих, з якими вже хтось невдало "погрався". Справа в тому, що нові МК поставляються з налаштуваннями конфігураційних біт, що не перешкоджають використанню SPI. Це підтверджується і результатами випробувань скрипта-програматора для програми "Перпетуум М", під час яких були успішно прошиті чотири різні МК (ATmega8, ATmega128, ATtiny13, ATtiny44). Усі вони були нові. Початкова настройка конфігураційних біт відповідала документації та не заважала використанню SPI.

Зважаючи на сказане вище, слід звертати увагу на такі біти. Біт SPIEN у явному вигляді дозволяє або забороняє використання SPI, отже, у нашому випадку його значення має бути вирішальним. Біт RSTDISBL здатний перетворити один із висновків мікросхеми (заздалегідь зумовлений) у вхід сигналу "скидання", або не перетворити (залежно від записаного в цей біт значення). У нашому випадку вхід "скидання" необхідний (за його відсутності не вдасться перевести МК в режим програмування через SPI). Існують ще біти групи CKSEL, що задають джерело тактового сигналу. Вони не перешкоджають використанню SPI, але їх теж необхідно мати на увазі, тому що при повній відсутності тактових імпульсів, або при їх частоті нижче за допустиму для заданої швидкості SPI, також нічого хорошого не вийде. Зазвичай у нових МК, мають внутрішній RC-генератор, біти групи CKSEL налаштовані його використання. Нас це цілком влаштовує – тактування забезпечене без будь-яких додаткових зусиль з нашого боку. Ні кварцовий резонатор припаювати, ні зовнішній генератор не потрібно підключати. Якщо ж зазначені біти містять інше налаштування, доведеться подбати про тактування відповідно до налаштування. У цьому випадку може знадобитися підключення до МК кварцового резонатора або тактового зовнішнього генератора. Але в рамках цієї статті ми не розглядатимемо, як це робиться. Приклади підключення МК для програмування, що містяться в цій статті, розраховані на найпростіший випадок.

Мал. 1. Обмін даними по SPI у режимі програмування

Тепер звернемося до малюнка 1, взятому з документації МК ATmega128A. На ньому показаний процес передачі одного байта МК і одночасного прийому одного байта з МК. Обидва ці процесу, як бачимо, використовують одні й самі тактові імпульси, які від програматора в мікроконтролер з його вхід SCK - одне із висновків мікросхеми, котрій у режимі програмування по SPI відведена така роль. Ще дві сигнальні лінії забезпечують прийом та передачу даних по одному біту за такт. Через вхід MOSI дані надходять у мікроконтролер, а з виходу MISO знімаються дані, що зчитуються. Зверніть увагу на дві пунктирні лінії, проведені від SCK до MISO та MOSI. Вони показують, коли мікроконтролер "ковтає" виставлений на вході MOSI біт даних, і коли сам виставляє на вихід MISO свій біт даних. Все досить просто. Але щоб ввести МК в режим програмування, нам ще знадобиться сигнал RESET. Не забудемо також про загальний провід GND та живлення VCC. Загалом виходить, що до мікроконтролера для його прошивки SPI потрібно підключити всього 6 проводків. Нижче розберемо це докладніше, а поки додамо, що обмін даними з МК в режимі програмування SPI виконується пакетами по 4 байти. Перший байт кожного пакета переважно повністю відводиться під кодування команди. Другий байт залежно від першого може бути продовженням коду команди або частиною адреси, а може мати довільне значення. Третій байт використовується переважно передачі адрес, але у багатьох командах може мати довільне значення. Четвертий байт зазвичай передає дані або має довільне значення. Поруч із передачею четвертого байта у деяких командах приймаються дані, які з МК. Подробиці кожної команди можна знайти в документації на контролер у таблиці під назвою "SPI Serial Programming Instruction Set". Поки зазначимо лише, весь обмін з контролером побудований з послідовності 32-бітних пакетів, у кожному з яких передається трохи більше одного байта корисної інформації. Це не дуже оптимально, але загалом працює непогано.

3. Підключення МК для програмування

Щоб забезпечити подачу на входи мікроконтролера всіх необхідних сигналів для організації інтерфейсу SPI та читання даних з виходу MISO, не обов'язково створювати програматор. Це легко здійснити за допомогою звичайного конвертера USB-RS232TTL.

В інтернеті часто можна зустріти інформацію про те, що такі конвертери є неповноцінними, що з ними нічого серйозного зробити не можна. Але щодо більшості моделей конвертерів така думка є помилковою. Так, існують у продажу конвертери, у яких доступні не всі входи та виходи в порівнянні зі стандартним COM-портом (наприклад, тільки TXD і RXD), що мають при цьому нерозбірну конструкцію (мікросхема залита пластмасою - неможливо дістатися її висновків). Але такі й купувати не варто. У деяких випадках отримати відсутні входи і виходи порту можна, підпаявши проводки безпосередньо до мікросхеми. Приклад такого "удосконаленого" конвертера показано на малюнку 2 (мікросхема PL-2303 - докладніше про призначення її висновків у статті ""). Це одна з найдешевших моделей, але має свої переваги при використанні в саморобних конструкціях. Широко поширені і повнофункціональні шнури-перехідники зі стандартним дев'ятиконтактним роз'ємом на кінці, як у COM-порту. Від звичайного COM-порту вони відрізняються лише рівнями TTL та несумісністю із застарілим програмним забезпеченнямта деяким старим обладнанням. Можна ще відзначити, що шнури на мікросхемі CH34x на різних екстремальних тестах показують себе набагато надійнішими та стабільнішими порівняно з перетворювачами на PL-2303. Втім, при звичайному використанні різниця не помітна.

При виборі конвертера USB-RS232TTL слід також звертати увагу на сумісність його драйвера з версією операційної системи, що використовується.

Розглянемо докладніше принцип з'єднання мікроконтролера та конвертера USB-RS232TTL на прикладі чотирьох різних моделейМК: ATtiny13, ATtiny44, ATmega8 та ATmega128. На малюнку 3 показано загальну схему такого з'єднання. Вас може здивувати, що сигнали RS232 (RTS, TXD, DTR та CTS) використовуються не за призначенням. Але не варто турбуватися про це: програма "Перпетуум М" здатна працювати з ними безпосередньо - встановлювати значення на виходах і читати стани входу. У всякому разі, широко поширені конвертери USB-RS232TTL на мікросхемах CH34x і PL-2303 таку можливість забезпечують - це перевірено. З іншими популярними конвертерами проблем не повинно бути, оскільки для доступу до порту використовуються стандартні функції Windows.

Резистори, показані на загальній схемі, в принципі можна не встановлювати, але краще встановити. Яке їхнє призначення? Використовуючи ТТЛ"івські входи і виходи конвертера і п'ятивольтне харчування мікроконтролера, ми тим самим позбавляємося необхідності узгодження логічних рівнів - все і так цілком коректно. Значить, з'єднання можуть бути безпосередніми. Але під час експериментів буває всяке. Саме в те місце, куди вона ніяк не могла б впасти, і замкнути те, що в жодному разі не можна замикати.В ролі "викрутки", звичайно, може виявитися все, що завгодно. одне їх призначення полягає в усуненні можливого конфлікту виходів, що після закінчення програмування мікроконтролер переходить у звичайний режим роботи, і може так вийти, що його висновок, з'єднаний з виходом конвертера (RTS, TXD або DTR) теж стає виходом, згідно Щойно записаної в МК програмі, у цьому випадку буде дуже погано, якщо два напряму з'єднані виходи "боротимуться" - намагатимуться встановити різні логічні рівні. У такій боротьбі хтось може і програти, а нам цього не треба.

Номінали трьох резисторів обрані лише на рівні 4,3 КОм. Це стосується з'єднань вихід конвертера - вхід мікроконтролера. Точність резисторів ролі не грає: можна зменшити їх опір до 1 КОм або збільшити до 10 КОм (але в другому випадку збільшується ризик перешкод при використанні довгих проводів на шляху до МК). Що ж до з'єднання вхід конвертера (CTS) - вихід мікроконтролера (MISO), то тут застосований резистор опором 100 Ом. Це пояснюється особливостями входу використаного конвертера. Під час випробувань був використаний конвертер на мікросхемі PL-2303, входи якої, судячи з усього, підтягнуті до плюсу живлення відносно низьким опором (близько кількох сотень Ом). Щоб "перебити підтяжку", довелося поставити резистор з таким маленьким опором. Втім, його можна взагалі не ставити. На конвертері завжди вхід. Виходом він стати не може, а отже, конфлікту виходів не буде за будь-якого розвитку подій.

Якщо мікросхема має окремий висновок AVCC для живлення аналогово-цифрового перетворювача (наприклад, ATmega8 або ATmega128), слід з'єднати його з виведенням загального живлення VCC. Деякі мікросхеми мають більше одного живлення VCC або більше одного GND. Наприклад, ATmega128 має 3 висновки GND та 2 висновки VCC. У постійній конструкції однойменні висновки краще поєднати між собою. У нашому випадку на час програмування можна задіяти по одному висновку VCC і GND.

А ось як виглядає підключення ATtiny13. На малюнку показано призначення висновків, що використовуються під час програмування через SPI. Поруч на фото – як тимчасове підключення виглядає насправді.


Хтось може сказати, що це несерйозно – з'єднання на проводках. Але ж ми з вами люди розсудливі. Наша мета полягає в тому, щоб запрограмувати мікроконтролер, витративши на це мінімум часу та інших ресурсів, а не в тому, щоби перед кимось покрасуватися. Якість при цьому не страждає. Метод "на проводках" у разі цілком ефективний і виправданий. Прошивка контролера - процедура разова, тому немає сенсу обвішувати її "стразиками". Якщо ж передбачається змінювати прошивку надалі, не виймаючи контролер зі схеми (у готовому виробі), це враховується в монтажі під час виготовлення пристрою. Зазвичай для цього встановлюється роз'єм (RESET, SCK, MOSI, MISO, GND), а МК може бути прошитий навіть після установки на плату. Але це вже творчі вишукування. Ми ж розглядаємо найпростіший випадок.

Тепер перейдемо до МК ATtiny44. Тут усе приблизно так само. По малюнку і фото навіть новачкові не важко розібратися з підключенням. Подібно до ATtiny44 можна підключати МК ATtiny24 і ATtiny84 - призначення висновків у цієї трійці збігається.


Ще один приклад тимчасового підключення контролера для його програмування – ATmega8. Тут висновків більше, але принцип той самий - кілька проводків, і ось уже контролер готовий до "заливання" в нього інформації. Зайвий чорний провід на фото, що йде від виводу 13, програмування участі не бере. Він призначений для зняття звукового сигналу після виходу МК з режиму програмування. Це пов'язано з тим, що під час налагодження скрипту для "Перпетуум М" у МК закачувалася програма музичної скриньки.


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

Для повноти картини подивимося підключення мікросхеми МК із великою кількістю "ніжок". Призначення зайвого чорного дроту на фото, що йде від виведення 15, таке саме, як у випадку з ATmega8.


Ймовірно, ви вже переконалися, що все досить просто. Хто вміє рахувати висновки у мікросхем (від мітки по колу проти годинникової стрілки), той розбереться. І не забувайте про акуратність. Мікросхеми люблять акуратні і не прощають недбалого до себе ставлення.

Перш ніж переходити до програмної частини, переконайтеся, що драйвер конвертера USB-RS232TTL коректно встановлений (перевірте диспетчер пристроїв Windows). Запам'ятайте або запишіть номер віртуального COM-порту, який з'являється під час підключення конвертера. Цей номер потрібно буде вписати до тексту скрипта, про який читайте нижче.

4. Скрипт – програматор для "Перпетуум М"

З апаратною частиною "програматора" розібралися. Це вже півсправи. Тепер залишилося розібратися із програмною частиною. Її роль виконуватиме програма "Перпетуум М" під управлінням скрипта, в якому реалізовані всі необхідні функції взаємодії з мікроконтролером.

Архів зі скриптом слід розпакувати в ту саму папку, де знаходиться програма perpetuum.exe. У цьому випадку при запуску файлу perpetuum.exe на екран буде виводитись меню зі списком встановлених скриптів, серед яких буде рядок "Программатор МК AVR" (вона може бути єдиною). Саме цей рядок нам і знадобиться.

Скрипт знаходиться у папці PMS у файлі "Программатор МК AVR.pms". Цей файл можна переглядати, вивчати та редагувати за необхідності у звичайному текстовому редакторі на кшталт "Блокнота" Windows. Перед використанням скрипта потрібно буде внести зміни в текст, пов'язані з налаштуванням порту. Для цього уточніть у диспетчері пристроїв Windows ім'я порту і, при необхідності, внесіть відповідну поправку в рядок "Ім'яПорта="COM4";" - замість цифри 4 може бути інша цифра. Також при використанні іншої моделі конвертера USB-RS232TTL може знадобитися зміна настройок інвертування сигналів (рядки скрипта, що починаються зі слова "Високий"). Перевірити інвертування сигналів конвертером USB-RS232TTL можна за допомогою одного з прикладів, що міститься в інструкції до програми Перпетуум М (розділ функцій для роботи з портом).

У вкладеній папці MK_AVR знаходяться файли з описами підтримуваних контролерів. Якщо потрібного контролера не виявиться серед них, ви можете додати потрібний самостійно, діючи за аналогією. Візьміть за зразок один із файлів, і за допомогою текстового редактора введіть необхідні дані, взявши їх з документації на мікроконтролер. Головне - будьте уважні, вводьте дані без помилок, інакше МК не запрограмується або запрограмується неправильно. У вихідній версії підтримуються 6 мікроконтролерів: ATtiny13, ATtiny24, ATtiny44, ATtiny84, ATmega8 та ATmega128. У скрипті реалізовано автоматичне розпізнавання підключеного контролера – вручну вказувати не потрібно. За відсутності ліченого з МК ідентифікатора серед наявних описів, видається повідомлення, що розпізнати контролер не вдалося.

В архіві зі скриптом міститься також додаткова інформація. У папці "inc-файли контролерів AVR" знаходиться дуже корисна та велика колекція файлів описів контролерів. Ці файли використовують при написанні власних програм для МК. Ще чотири папки "MusicBox_..." містять файли з програмою на Асемблері та готовою до закачування в МК прошивкою окремо для ATtiny13, ATtiny44, ATmega8 та ATmega128. Якщо ви вже підключили один із цих МК для програмування, як це запропоновано в даній статті, то можете прямо зараз його прошити - вийде музична скринька. Про це нижче.

При виборі меню скриптів рядки " Програматор МК AVR " , скрипт починає виконуватися. При цьому він відкриває порт, посилає в МК команду переходу в режим програмування, приймає підтвердження від МК про успішний перехід, запитує ідентифікатор МК і шукає опис даного МК з його ідентифікатору серед наявних файлів з описами. Якщо не знаходить відповідного опису, видає відповідне повідомлення. Якщо опис знайдено, далі відкривається головне меню програматора. Його скріншот можна бачити на малюнку 8. Далі розібратися не складно - меню дуже просте.

У першій версії скрипту деякі функції повноцінного програматора не реалізовані. Наприклад, немає можливості читати та писати в EEPROM. Але якщо ви відкриєте скрипт у текстовому редакторі, то побачите, що він має дуже невеликий розмір, при тому, що основне в ньому вже реалізовано. Це говорить про те, що додати функції не так вже й складно - мова дуже гнучкий, він дозволяє в невеликій програмі реалізувати багату функціональність. Але для більшості випадків вистачить навіть функцій.

Деякі обмеження функціональності описані у тексті скрипта:
//реалізований запис тільки з нульової адреси (Extended Segment Address Record ігнорується, LOAD OFFSET - теж)
//порядок і безперервність слідування записів у HEX-файлі не перевіряється
//контрольна сума не перевіряється
Це стосується роботи з файлом HEX, з якого береться код прошивки для МК. Якщо файл не спотворений, перевірка контрольної суми ні на що не вплине. Якщо спотворений – засобами скрипту це виявити не вдасться. Інші обмеження здебільшого не завадять, але мати на увазі їх все-таки потрібно.

5. Музична скринька - простий виріб для початківців

Якщо у вас є один з цих мікроконтролерів: ATtiny13, ATtiny44, ATmega8 або ATmega128, ви можете легко перетворити його на музичну скриньку або музичну листівку. Для цього достатньо записати в МК відповідну прошивку - одну з чотирьох, які розміщені в папках "MusicBox_..." в одному архіві зі скриптом. Коди прошивок зберігаються у файлах із розширенням ".hex". Використовувати ATmega128 для такого виробу, звичайно, "жирновато", як і ATmega8. Але це може бути корисно для тестування чи експериментів, інакше кажучи – у навчальних цілях. Тексти програм на асемблері також додаються. Програми створювалися не з нуля - за основу було взято програму музичної скриньки з книги А.В.Бєлова " Мікроконтролери AVRу радіоаматорській практиці". Вихідна програма зазнала ряду суттєвих змін:
1. адаптована для кожного з чотирьох МК: ATtiny13, ATtiny44, ATmega8 та ATmega128
2. ліквідовані кнопки - до контролера взагалі нічого не потрібно підключати, крім живлення та звуковипромінювача (мелодії відтворюються одна за одною в нескінченному циклі)
3. тривалість кожної ноти зменшена тривалість паузи між нотами усунення порушення музичного ритму
4. підключена восьма мелодія, незадіяна у книжковій версії
5. із суб'єктивного: деякі "улучшайзинги" для оптимізації та легшого сприйняття алгоритму

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

В ATtiny13 через відсутність 16-бітного лічильника для відтворення нот довелося використовувати 8-бітний, що призвело до деякого зниження точності звучання нот. Але на слух це мало помітно.

Щодо конфігураційних біт. Їх налаштування має відповідати стану нового мікроконтролера. Якщо ваш МК раніше десь використовувався, потрібно перевірити стан його конфігураційних біт, і, при необхідності, привести їх у відповідність до налаштувань нового мікроконтролера. Дізнатися стан конфігураційних біт нового мікроконтролера можна з документації цей МК (розділ "Fuse Bits"). Виняток становить ATmega128. Цей МК має біт M103C, який включає режим сумісності з більш старим ATmega103. Активізація біта M103C сильно урізує можливості ATmega128, причому у нового МК цей біт активний. Потрібно скинути M103C у неактивний стан. Для маніпуляцій із конфігураційними бітами використовуйте відповідний розділ меню скрипта-програматора.

Схему музичної скриньки наводити немає сенсу: у ній тільки мікроконтролер, харчування та п'єзвуковипромінювач. Харчування подається так само, як ми це зробили при програмуванні МК. Звуковипромінювач підключається між загальним проводом (висновок GND контролера) та одним із висновків МК, номер якого можна подивитися у файлі з асемблерним кодом програми (*.asm). На початку тексту програми для кожного МК у коментарях є рядок: " звуковий сигналформується на виведенні ХХ". При завершенні роботи скрипта - програматора мікроконтролер виходить з режиму програмування і переходить у звичайний режим роботи. Відразу ж починається відтворення мелодій. Підключивши звуковипромінювач, можна це перевірити. якщо звук знімається з виводу, не задіяного в SPI, інакше додаткова ємність виводу може перешкодити програмуванню.

Завдання: Розробимо програму керування одним світлодіодом. При натисканні на кнопку світлодіод світиться, при відпусканні гасне.

Для початку розробимо важливу схему пристрою. Для підключення до мікроконтролера будь-яких зовнішніх пристроїв використовуються порти вводу-виводу. Кожен із портів здатний працювати як на вхід так і на вихід. Підключимо світлодіод до одного з портів, а кнопку до іншого. Для цього досвіду ми будемо використовувати контролер Atmega8. Ця мікросхема містить 3 порти вводу-виводу, має 2 восьмирозрядні і 1 шістнадцятирозрядний таймер/лічильник. Також на борту є 3-х канальний ШІМ, 6-ти канальний 10-ти бітний аналого-цифровий перетворювач та багато іншого. На мою думку, мікроконтролер чудово підходить для вивчення основ програмування.

Для підключення світлодіода ми використовуватимемо лінію PB0, а для зчитування інформації з кнопки скористаємося лінією PD0. Схема наведено на рис.1.

Мал. 1

Через резистор R2 на вхід PD0 подається плюс напруги живлення, що відповідає сигналу логічної одиниці. При замиканні кнопки напруга знижується до нуля, що відповідає логічному нулю. Надалі R2 можна виключити зі схеми, замінюючи його на внутрішній резистор навантаження, ввівши необхідні налаштування в програмі. Світлодіод підключений до виходу порту PB0 через резистор R3, що обмежує струм. Для того, щоб запалити світлодіод, треба подати в лінію PB0 сигнал логічної одиниці. Задає тактовий генератор використовуватимемо внутрішній на 4MHz, так як у пристрої немає високих вимог до стабільності частоти.

Тепер пишемо програму. Для написання програм я використовую програмне середовище AVR Studioі WinAvr.Відкриваємо AVR Studio, спливає віконце вітання, натискаємо кнопку "Створити новий проект" (New project), далі вибираємо тип проекту - AVR GCC, пишемо ім'я проекту наприклад "cod1", ставимо обидві галочки "Створити папку проекту" та "Створити файл ініціалізації" , натискаємо кнопку "Далі", у лівому вікні вибираємо "AVR Simulator", а в правому тип мікроконтролера "Atmega8", натискаємо кнопку "Фініш", відкривається редактор та дерево категорій проекту - початкові установки закінчені.

Для початку додамо стандартний текст описів Atmega8 за допомогою оператора приєднання зовнішніх файлів: #include

синтаксис директиви #include

#include<имя_файла.h>
#include “ім'я_файлу.h”

Кутові дужки< и >вказують компілятору, що файли, що підключаються, потрібно спочатку шукати в стандартній папці WinAvr з ім'ям include. Подвійні лапки "і" вказують компілятор починати пошук з директорії, в якій зберігається проект.

Для кожного типу мікроконтролера є свій заголовний файл. Для ATMega8 цей файл називається iom8.h, для ATtiny2313 – iotn2313.h. На початку кожної програми ми повинні підключати заголовний файл мікроконтролера, який ми використовуємо. Але є й загальний заголовний файл io.h. Препроцесор обробляє цей файл і в залежності від налаштувань проекту включає в нашу програму потрібний файл заголовка.

Для нас перший рядок програми виглядатиме ось так:

#include

Будь-яка програма мовою Сі повинна обов'язково містити одну головну функцію. Вона має ім'я main. Виконання програми завжди починається із виконання функції main. Функція має заголовок - int main(void) і тіло - воно обмежене фігурними дужками {}.

int main(void)
{
тіло функції
}

У тіло функції ми і додаватимемо наш код. Перед ім'ям функції вказується тип значення, що повертається. Якщо функція не повертає значення – використовується ключове void.

int- це ціле 2-байтне число, діапазон значень від - 32768 до 32767

Після імені функції у дужках () вказуються параметри, які передаються функції під час її виклику. Якщо функція без параметрів – використовується ключове слово void. Функція mainмістить у собі набір команд, налаштування системи та головний цикл програми.

Далі налаштовуємо порт Dна вхід. Режим роботи порту визначається вмістом регістру DDRD(Регістр напряму передачі інформації). Записуємо в цей регістр число "0x00" (0b0000000 – у двійковому вигляді), крім кнопки до цього порту нічого не підключено, тому налаштовуємо весь порт D на вхід. Налаштувати порт порозрядно можна записавши в кожен біт регістра числа 0 або 1 (0-вхід, 1-вихід), наприклад DDRD = 0x81 (0b10000001) - перша та остання лінія порту D працюють на вихід, решта на вхід. Необхідно також підключити внутрішній резистор навантаження. Увімкненням та вимкненням внутрішніх резисторів керує регістр PORTx, якщо порт знаходиться в режимі введення. Запишемо туди одиниці.

Налаштовуємо порт Bна вихід. Режим роботи порту визначається вмістом регістру DDRB. Нічого, крім світлодіода до порту Bне підключено, тому весь порт можна налаштувати на вихід. Це робиться записом у регістр DDRBчисла "0xFF". Для того, щоб при першому включенні світлодіод не загорівся запишемо в порт Bлогічні нулі. Це робиться записом PORTB= 0x00;

Для присвоєння значень використовується символ "=" і називається оператором присвоювання, не можна плутати зі знаком "рівно"

Налаштування портів виглядатиме так:

DDRD = 0x00;
PORTD = 0xFF;
DDRB = 0xFF;
PORTB = 0x00;

Пишемо основний цикл програми. while( " поки " з англ.) - ця команда організує цикл, багаторазово повторюючи тіло циклу до тих пір поки виконується умова, т. е поки вираз у дужках є істинним. У мові Сі прийнято вважати, що вираз істинний, якщо він не дорівнює нулю, і хибно, якщо дорівнює.

Команда виглядає так:

while (умова)
{
тіло циклу
}

У нашому випадку основний цикл складатиметься лише з однієї команди. Ця команда надає регістру PORTBзначення регістра, що інвертується PORTD.

PORTB = ~PIND; //Взяти значення з порту D, проінвертувати його і присвоїти PORTB (записати в PORTB)

// вирази мовою Сі читаються справа наліво

PINDрегістр введення інформації. Щоб прочитати інформацію із зовнішнього виведення контролера, потрібно спочатку перевести потрібний розряд порту в режим введення. Тобто записати у відповідний біт регістру DDRxнуль. Тільки після цього на цей висновок можна подавати цифровий сигнал із зовнішнього пристрою. Далі мікроконтролер прочитає байт із регістру PINx. Вміст відповідного біта відповідає сигналу зовнішньому виведенні порту. Наша програма готова і виглядає так:

#include int main (void) (DDRD = 0x00; // порт D - вхід PORTD = 0xFF; // підключаємо навантажувальний резистор DDRB = 0xFF; // порт B - вихід PORTB = 0x00; // встановлюємо 0 на виході while (1) ( PORTB = ~PIND; //~ знак порозрядного інвертування)))

У мові Сі широко використовуються коментарі. Є два способи написання.

/*Коментар*/
//Коментар

При цьому компілятор не звертатиме уваги на те, що написано в коментарі.

Якщо використовуючи цю ж програму і підключити до мікроконтролера 8 кнопок і 8 світлодіодів, як показано на малюнку 2, то буде зрозуміло, що кожен біт порту Dвідповідає своєму биту порту B. Натискаючи кнопку SB1 – загоряється HL1, натискаючи кнопку SB2 – загоряється HL2 тощо.

Малюнок 2

У статті були використані матеріали із книги Бєлова А.В. "Самовчитель розробника пристроїв на AVR"

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

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

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

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

Перша програма на Сі для 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); UBRRH = HI (bauddivider); UCSRA = 0; UCSRB = 1<

Страшна? Насправді реалного коду тут лише п'ять останніх рядків. Все, що #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 JMP 0x0000000000000 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 0x0000000 0x00000034 Jump +00000016: 940C0034 JMP 0x00000034 Jump +00000018: 940C0034 JMP 0x00000034 Jump +0000001A: 940C000 : 940C0034 JMP 0x00000034 Jump +0000001E: 940C0034 JMP 0x00000034 Jump +00000020: 940C0034 JMP 0x00000034 Jump +000 34 Jump +00000024: 940C0034 JMP 0x00000034 Jump +00000026: 940C0034 JMP 0x00000034 Jump +00000028: 940C0034 JMP 0x0

00000000: 940C002A JMP 0x0000002A Jump +00000002: 940C0034 JMP 0x00000034 Jump +00000004: 940C0034 JMP 0x0000000000000 0x00000034 Jump +00000008: 940C0034 JMP 0x00000034 Jump +0000000A: 940C0034 JMP 0x00000034 Jump +0000000C: 940C000 : 940C0034 JMP 0x00000034 Jump +00000010: 940C0034 JMP 0x00000034 Jump +00000012: 940C0034 JMP 0x00000034 Jump +00 34 Jump +00000016: 940C0034 JMP 0x00000034 Jump +00000018: 940C0034 JMP 0x00000034 Jump +0000001A: 940C0034 JMP 0x0 940C0034 JMP 0x00000034 Jump +0000001E: 940C0034 JMP 0x00000034 Jump +00000020: 940C0034 JMP 0x00000034 Jump +00000000 Jump +00000024: 940C0034 JMP 0x00000034 Jump +00000026: 940C0034 JMP 0x00000034 Jump +00000028: 940C0034 JMP 0x000

Це таблиця векторів переривань. До неї ми ще повернемося, поки просто подивися і запам'ятай, що вона є. Перша колонка - адреса осередку флешу в якій лежить команда, друга код команди третя мнемоніка команди, та сама асемблерна інструкція, третя операнди команди. Та й автоматичний комент.
Так от, якщо ти подивишся, то тут суцільні переходи. А код команди 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.У правій частині заставки з'являється список пристроїв, які працюють із цим мікроконтролером, один з яких ми можемо підключити. Вибираємо ОК.

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


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

Здрастуйте, MySkuвчане! Герой нашого огляду – мікроконтролер Atmega8A-16PU. Я розповім вам про програмування даного мк в інтегрованому середовищі розробки CodeVisionAvr, помигаємо світлодіодом, розглянемо плюси та мінуси роботи в даному середовищі. Можливо, надалі це послужить для вас альтернативою вже «народною» Arduino. Якщо зацікавилися, гоу під cut.

Преамбула.
Так вже склалося, що своє знайомство з мк я почав з Arduino. Блимав світлодіодом, підключав різні датчики та шилди, робив різні проекти. Все працювало, мене влаштовувало, проте хотілося чогось більшого. Підвернувся мені один проект, де бере участь Atmega8A, під яку потрібно самостійно написати прошивку. Саме він підштовхнув мене до вивчення процесу програмування голого мк.
Отже, маємо мікроконтролер фірми Atmel, сімейства AVR Atmega8A.

Технічні характеристики:


Розпинування:


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

На жаль, я як шевець - без чобіт, зараз під руками немає програматора, тому я використовуватиму Arduino UNO для завантаження в мк готової прошивки та налаштування ф'юзів. Достатньо лише завантажити скетч «Arduinoisp» із папки прикладів Arduino IDE та підключити за схемою:


Однак, у цього рішення є суттєва вада, про яку розповім трохи пізніше. Перед тим, як приступити до написання програми CodeVisionAvr (далі CvAvr), нам потрібно визначитися, на якій частоті буде працювати наш мк. За замовчуванням, із заводу наш герой працює від внутрішнього rc-генератора на частоті 1Мгц (з можливістю переналаштування на 2, 4 та 8Мгц). Оскільки внутрішній rc-генератор калібрують на заводі за певних умов (точна напруга, температура), то точність його роботи в польових умовах може відрізнятися від 3% до 10%. Для завдань, де не потрібна висока точність тактування, це можна знехтувати, в інших випадках краще використовувати зовнішній кварц. У своєму проекті використав зовнішній кварц на частоту 8 МГц. Тепер нам треба "пояснити" мк, що потрібно працювати від зовнішнього кварцу. Робиться це з допомогою зміни фьюзов. Якщо пояснити «на пальцях», то це щось на зразок БІОСа, як на материнській платі, де ви вказуєте режими її роботи, аналогічно ми повідомляємо мк, в яких режимах, крім частоти, він повинен працювати. Вся інформація зберігатиметься в енергонезалежній пам'яті.
Про прошивку ф'юзів я розповім під спойлером, ті, хто вміє це робити самостійно, можуть гортати далі.

додаткова інформація

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


Тут все просто:
Clock Source – задаємо частоту (External Crystal 3 – 16 Mhz) від зовнішнього кварцу.
Start-up Time – швидкість старту мк після зняття RESET або подачі живлення (16K CK + 4.1ms fast).
Ставимо галку: Ext. Clock/RC Osc./Low-freq. Crystal: enable internal Capacitors (36 pF)
Internal R/C Osc.: leave unchecked! External Crystal: enable full swing (необхідно >8 MHz).
Таким чином, ми отримали Low Fuse 0xEF та High Fuse 0xC9. Чудово, півсправи зробили. Тепер підключаємо мк Arduino UNO, а саму Arduino до комп'ютера відповідно. Запускаємо командний рядок, переходимо до папки з AvrDude. Далі вводимо рядок: avrdude -C avrdude.conf -c avrisp -P COM13 -b 19200 -p m8 -U lfuse:w:0xef:m -U hfuse:w:0xc9:m
Ось як це виглядає на зображенні:


Розберемо рядок, який ввели:
avrisp - це тип нашого ардуїноподібного програматора
COM13 - номер com порту, яким визначається наша Arduino у системі (у вашому випадку його треба подивитися в диспетчері пристроїв)
19200 - швидкість com порту, залишаємо як є
m8 – вказуємо, що наш мк – Atmega8
-U lfuse:w:0xef:m -U hfuse:w:0xc9:m - тут вказані наші Low Fuse 0xEF і High Fuse 0xC9
Будьте УВАЖЛИВІ!!, неправильно вказані Fuse можуть призвести до керування мк (танці з бубном по відновленню нам не потрібні).
Натискаємо «Введення» і на виході отримуємо результат, як на малюнку:


Якщо не з'явилося жодних помилок у процесі, то робота виконана, наш мк тепер працюватиме від зовнішнього кварцу.
Дуже детально про ф'юзи можна прочитати і , а також використовуючи пошук у google.


Тепер ми готові розпочати програмування. Для себе я вибрав середовище розробки CvAvr. Мова програмування буде відрізняється від «ардуїновського», в CvAvr він Сі-подібний. Напишемо наш перший Blink.
Після встановлення та запуску середовища скористаємося майстром створення проектів. Вибираємо "File" - "New" - "Project". На запитання, чи використовуватимемо ми майстер, відповідаємо ствердно. Target AVR Chip Type вказуємо AT90, ATtity, ATmega.
Так виглядає майстер проектів:


На вкладці Chip вибираємо ATmega8A, Clock 8.000 000 Mhz. Переходимо до вкладки Ports. Наш світлодіод буде підключений до 14 виведення мікроконтролера, згідно з розпинуванням - PB0. На вкладці вибираємо Port B, Bit 0 перемикаємо з IN на OUT, тобто. переводимо режим роботи 14 ніжки нашого мк на вихід.


На цьому роботу майстра закінчено. Вибираємо "Program" - "Generate, Save and Exit". Зберігаємо наш проект, наприклад, під назвою Blink.

Отримаємо таку ось онучу

/*******************************************************
Цей program був створений за
CodeWizardAVR V3.12 Advanced
Automatic Program Generator
Chip type: ATmega8A
Program type: Application
AVR Core Clock frequency: 8.000000 MHz
Memory model: Small
External RAM size: 0
Data Stack size: 256
*******************************************************/
#include
#include
// Declare your global variables here

Void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Function: Bit7 = In Bit6 = In Bit5 = In Bit4 = In Bit3 = In Bit2 = In Bit1 = In Bit0 = Out
DDRB=(0<// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=0
PORTB=(0<

// Port C initialization
// Function: Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRC=(0<// State: Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTC=(0<

// Port D initialization
// Function: Bit7 = In Bit6 = In Bit5 = In Bit4 = In Bit3 = In Bit2 = In Bit1 = In Bit0 = In
DDRD=(0<// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<

// Timer/Counter 0 initialization

// Clock value: Timer 0 Stopped
TCCR0=(0<TCNT0 = 0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<TCCR1B=(0<TCNT1H = 0x00;
TCNT1L=0x00;
ICR1H = 0x00;
ICR1L = 0x00;
OCR1AH=0x00;
OCR1AL = 0x00;
OCR1BH = 0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0<TCCR2=(0<TCNT2 = 0x00;
OCR2 = 0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK = (0<

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=(0<

// USART initialization
// USART disabled
UCSRB=(0<

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator"s positive input is
// connected to the AIN0 pin
// The Analog Comparator"s negative input is
// connected to the AIN1 pin
ACSR=(1<SFIOR=(0<

// ADC initialization
// ADC disabled
ADCSRA=(0<

// SPI initialization
// SPI disabled
SPCR=(0<

// TWI initialization
// TWI disabled
TWCR=(0<

While (1)
{


Тут нічого страшного немає, у проекті вказані режими роботи портів, таймерів, переривань, USART, Analog Comparator, ADC, SPI та підключених бібліотек. Словом, всі параметри, які ми вказували в майстрі, все, крім портів і чіпа, у нас налаштовано за замовчуванням. Основний цикл програми будемо писати в while (1) (текст програми). Т.к. ми працюємо з PB0 (14 ніжка), у циклі програми напишемо:
while (1)
{
PORTB.0=1;
delay_ms (1000);
PORTB.0 = 0;
delay_ms (1000);
}
Тут ми встановлюємо високий рівень на PB0, чекаємо 1 секунду та встановлюємо низький рівень, потім цикл повторюється. Ще не забуваємо підключити бібліотеку на початку проекту #include . Наша програма готова! Як бачите, все дуже просто. Тепер вибираємо "Project" - "Build All". Якщо помилок допущено був, побачимо звіт майстра:

Розмір нашої програми становив 198 bytes, і зайняв 2.4% пам'яті мк.
Далі збираємо схему:


Тепер переходимо в папку з нашим проектом, заходимо в папку Debug, потім Exe, там знаходиться файл з розширенням hex. В моєму випадку, це blink.hex.
Залишився останній крок. Копіюємо цей файл до папки з AvrDude. Знову запускаємо командний рядок, переходимо до нашої папки. Вводимо рядок avrdude -C avrdude.conf -c avrisp -P COM13 -b 19200 -p m8 -U flash:w:blink.hex
Так це виглядає на зображенні:


Якщо все ввели правильно, тиснемо «Введення»


Вітаю! Робота виконана, світлодіод повинен вам радісно блимати:)
Висновок.
На закінчення хочу сказати про нестачу ардуїноподібного програматора, CvAvr його просто не підтримує. Маючи на руках, наприклад, AVRISP mkII, виконати прошивку ф'юзів та завантаження програми можна безпосередньо з CodeVisionAvr. До речі, використовувати графічний інтерфейс AvrDude доморощений програматор теж відмовився і працював тільки з командного рядка.
З CodeVisionAvr я розібрався досить швидко, в інтернеті повно текстових та відео уроків. За кілька тижнів освоїв роботу апаратного ШІМ, переривань, таймерів, роботу з кнопками та підключення графічного дисплея. Конкретно мені треба було зробити частину свого проекту: на Atmega8 організувати апаратний 16-бітний ШІМ, підключити 2 кнопки для його керування, а також виводити режими його роботи на графічний дисплей, що з легкістю я і зробив:)

додаткова інформація





Підсумки порівняно з Arduino:
+ Розібратися в CvArv не складно, т.к. є майстер створення проектів;
+ Наявність бібліотек, що підключаються, їх достатньо;
+ Швидка компіляція;
+ Можливість симуляції проекту в Proteus, а також налагодження його силами вбудованого debugger`а;
+ Розмір програми в рази менший. Стандартний Blink у нас зайняв 198 Байт, аналогічний скетч Arduino IDE 1084 Байт + 2 Кб завантажувач;
+ Можливість реалізувати режими, які не можна зробити на Arduino. Наприклад 16-бітний ШІМ (взагалі, на Arduino можна, але тільки з «милицями»);
+ Можливість застосовувати для своїх проектів мк типу ATtiny, ATmega там, де Arduino буде надмірним;
- Все ж новачку починати освоювати мк краще з Arduino;
- Мова програмування відрізняється від ардуїновського processing`a;
- Бібліотек до Arduino все ж таки більше;
- CodeVisionAvr є платною програмою, є безкоштовні версії з обмеженнями;
Програмуючи «голий» мк у CodeVisionAvr, я отримав величезний досвід роботи у свою скарбничку. Вивчення таймерів, регістрів, режимів роботи, архітектури, читання datasheet збільшить вашу кваліфікацію, розширить кругозір і відкриє нові аспекти роботи з мікроконтролерами.
Як бонус додаю пару фото, коли розбирався з графічним ЖК-дисплеєм, трохи погрався.





P.s. Багато чого хотів написати, але це вже вийде не огляд, а величезна стаття. Готовий відповісти на запитання у межах своєї компетенції, у приваті чи коментарях. Дуже багато уроків з AVR можна підглянути.

Top