Микроконтролери Atmega8. Atmega8 програмиране за начинаещи. AVR микроконтролери. Програмиране за начинаещи Обучение за микроконтролер atmega8

декември 2015 г

1. Предимства на предложения метод

Веригите на устройства, базирани на микроконтролери (MCU), обикновено се отличават с комбинация от две трудни за комбиниране качества: максимална простота и висока функционалност. В допълнение, функционалността може да бъде променяна и разширявана в бъдеще, без да се правят промени в схемата - само чрез подмяна на програмата (мигане). Тези характеристики се обясняват с факта, че създателите на съвременни MKs се опитаха да поставят на един чип всичко, от което един разработчик може да се нуждае електронно устройство- поне доколкото е възможно. В резултат на това имаше изместване на акцента от схемите и инсталацията към софтуера. С използването на MK сега има по-малко нужда от „зареждане“ на веригата с части и има по-малко връзки между компонентите. Това, разбира се, прави схемата по-привлекателна за повторение както от опитни, така и от начинаещи инженери по електроника. Но, както обикновено, трябва да платите за всичко. Това също не беше лишено от трудности. Ако закупите нов MK, инсталирате го във верига, правилно сглобена от обслужваеми части и подадете захранване, тогава нищо няма да работи - устройството няма да работи. Микроконтролерът се нуждае от програма.

Изглежда, че и с това всичко е просто - в интернет можете да намерите много схеми с безплатен фърмуер. Но тук има една уловка: фърмуерът трябва по някакъв начин да бъде „качен“ в микроконтролера. За някой, който никога не е правил това преди, подобна задача често се превръща в проблем и основен отблъскващ фактор, често ги принуждава да изоставят удоволствията от използването на MK и да търсят схеми, базирани на „хлабава“ и твърда логика. Но всичко не е толкова сложно, колкото може да изглежда на пръв поглед.

След като анализирате публикации в Интернет, можете да видите, че този проблем най-често се решава по един от двата начина: закупуване на готов програмист или създаване на домашен. В същото време публикуваните схеми на домашни програмисти много често са неоправдано сложни - много по-сложни, отколкото е наистина необходимо. Разбира се, ако планирате да мигате MK всеки ден, по-добре е да имате „готин“ програмист. Но ако необходимостта от такава процедура възниква рядко, от време на време, тогава можете да се справите напълно без програмист. Не, разбира се, не говорим за това да се научим да правим това със силата на мисълта. Това означава, че като разберем как програмистът взаимодейства с микроконтролера, когато пише и чете информация в неговия режим на програмиране, можем да се задоволим с наличните инструменти за по-широка цел. Тези инструменти ще трябва да заменят както софтуерната, така и хардуерната част на програмиста. Хардуерът трябва да осигурява физическа връзка с микросхемата MK, възможност за прилагане на логически нива към нейните входове и четене на данни от нейните изходи. Софтуерната част трябва да осигури работата на алгоритъма, който контролира всички необходими процеси. Също така отбелязваме, че качеството на запис на информация в MK не зависи от това колко „готин“ е вашият програмист. Няма такова нещо като „по-добре записано“ или „по-лошо“. Има само две опции: „регистриран“ и „нерегистриран“. Това се обяснява с факта, че процесът на запис вътре в кристала се контролира директно от самия MK. Просто трябва да му осигурите висококачествено захранване (без смущения или вълни) и правилно да организирате интерфейса. Ако резултатите от тестовото отчитане не показват грешки, тогава всичко е наред - можете да използвате контролера по предназначение.

За да напишем програма в MK, без да имаме програмист, се нуждаем от преобразувател на USB-RS232TTL порт и също. Конверторът USB-RS232TTL ви позволява да използвате USB порт за създаване на COM порт, който се различава от „истинския“ само по това, че неговите входове и изходи използват TTL логически нива, тоест напрежение в диапазона от 0 до 5 волта ( можете да прочетете повече в статията " "). Във всеки случай е полезно да имате такъв преобразувател във вашето „домакинство“, така че ако все още нямате такъв, определено си струва да го купите. Що се отнася до логическите нива, в нашия случай TTL дори е предимство пред обикновен COM порт, тъй като входовете и изходите на такъв порт могат да бъдат директно свързани към всеки микроконтролер, захранван от 5 V, включително ATtiny и ATmega. Но не се опитвайте да използвате обикновен COM порт - те използват напрежения в диапазона от -12 до +12 V (или -15...+15V). В този случай директната връзка с микроконтролера е недопустима!!!

Идеята за създаване на скрипт за програмата Perpetuum M, която изпълнява функциите на програмиста, възникна след прочитане на редица публикации в Интернет, предлагащи определени решения за фърмуера на MK. Във всеки случай бяха открити сериозни недостатъци или прекомерни затруднения. Често се натъквах на програмистни схеми, които съдържаха микроконтролер, и в същото време се даваха съвети доста сериозно като: „... и за да програмираме микроконтролера за този програмист, ще ни трябва... точно така - друг програмист!“ След това беше предложено да отидете при приятел и да потърсите платена услугаи така нататък. Качеството на софтуера, разпространяван в мрежата за тези цели, също не беше впечатляващо - бяха забелязани много проблеми както с функционалността, така и с „облачността“ на потребителския интерфейс. Често отнема много време, за да разберете как да използвате дадена програма - тя трябва да се изучава дори за извършване на най-простите действия. Друга програма може да прави нещо дълго време и усърдно, но потребителят научава, че нищо не се записва в MK само след като целият фърмуер е напълно завършен и последващо тестово четене. Възниква и следният проблем: потребителят се опитва да избере своя MK от списъка с поддържани кристали, но той не е в списъка. В този случай няма да можете да използвате програмата - включването в списъка с липсващи MK по правило не е предвидено. В допълнение, ръчното избиране на контролер от списъка изглежда странно, като се има предвид, че програмистът в много случаи може сам да определи типа на MK. Всичко това се казва не за да се хвърля кал върху съществуващите продукти, а за да се обясни причината за появата на скрипта за програмата Perpetuum M, описана в тази статия. Проблемът наистина съществува и засяга предимно начинаещи, които не винаги успяват да преодолеят тази „стена“, за да направят първата си стъпка в света на микроконтролерите. Предложеният скрипт отчита недостатъците, открити в други програми. Реализирана е максимална „прозрачност“ на работата на алгоритъма, изключително опростен потребителски интерфейс, който не изисква обучение и не оставя шанс да се объркате и да „щракнете на грешното“. Ако необходимият MK не е сред поддържаните, можете сами да добавите описанието му, като вземете необходимите данни от документацията, изтеглена от уебсайта на разработчика на MK. И най-важното е, че сценарият е отворен за изучаване и модификация. Всеки може, като отвори в текстов редактор, изучавайте и редактирайте го по свое усмотрение, като променяте съществуващите функции по ваш вкус и добавяте липсващи.

Първата версия на скрипта е създадена през юни 2015 г. Тази версия осигурява поддръжка само за микроконтролерите от серията ATtiny и ATmega на Atmel с функции за запис/четене на флаш памет, задаване на конфигурационни битове и автоматично откриване на типа контролер. Записването и четенето на EEPROM не е реализирано. Имаше планове за допълване на функционалността на скрипта : добавяне на писане и четене на EEPROM, внедряване на поддръжка за PIC контролери и т.н.. Поради тази причина скриптът все още не е публикуван.Но поради липса на време изпълнението на плана беше забавено и за да не стане най-доброто враг на доброто, беше решено да се публикува съществуващата версия. Ако вече внедрените функции няма да са достатъчни, моля, не се разстройвайте. В този случай можете да опитате сами да добавите желаната функция. Няма да крия: идеята за създаване на този скрипт първоначално също има образователен смисъл.След като разберете алгоритъма и добавите нещо свое към него, ще можете да разберете по-добре работата на MK в режим на програмиране, така че в в бъдеще няма да се окажете в положението на момиче пред разбита кола, замислено оглеждайки вътрешностите й и не разбирайки защо „не работи“.

2. MK интерфейс в режим на програмиране

Има няколко различни начина за поставяне на контролера в режим на програмиране и работа с него в този режим. Най-лесният за изпълнение за контролери от сериите ATtiny и ATmega е може би SPI. Ще го използваме.

Но преди да започнем да разглеждаме сигналите, необходими за генериране на SPI, ще направим няколко уговорки. Микроконтролерът има конфигурационни битове. Това са нещо като превключватели, превключването на които ви позволява да промените някои свойства на микросхемата в съответствие с нуждите на проекта. Физически това са клетки с енергонезависима памет, като тези, в които е записана програма. Разликата е, че има много малко от тях (до три байта за ATmega) и те не са част от адресното пространство на никоя памет. Записването и четенето на конфигурационни данни се извършва чрез отделни команди в режим на програмиране на MK. Сега е важно да се отбележи, че някои конфигурационни битове засягат самата способност за използване на SPI. При някои от стойностите им може да се окаже, че SPI не може да се използва. Ако попаднете на такъв микроконтролер, методът, предложен в тази статия, няма да помогне. В този случай ще трябва или да промените настройките на конфигурационните битове в програматора, който поддържа различен режим на програмиране, или да използвате различен микроконтролер. Но този проблем се отнася само за използвани МК или такива, с които някой вече неуспешно е „играл“. Факт е, че новите MCU идват с конфигурационни битови настройки, които не предотвратяват използването на SPI. Това се потвърждава от резултатите от теста на скрипта на програмиста за програмата Perpetuum M, по време на който бяха успешно флашнати четири различни MK (ATmega8, ATmega128, ATtiny13, ATtiny44). Всички бяха нови. Първоначалната настройка на конфигурационните битове беше в съответствие с документацията и не пречеше на използването на SPI.

Като се има предвид горното, трябва да обърнете внимание на следните битове. Битът SPIEN изрично разрешава или забранява използването на SPI, следователно в нашия случай неговата стойност трябва да е разрешаваща. Битът RSTDISBL може да превърне един от изходите на микросхемата (предварително определен) във входа на сигнала „нулиране“ или да не го завърти (в зависимост от стойността, записана на този бит). В нашия случай е необходим входът „нулиране“ (ако липсва, няма да е възможно да превключите MK в режим на програмиране чрез SPI). Има и битове от групата CKSEL, които определят източника на тактовия сигнал. Те не пречат на използването на SPI, но също трябва да се имат предвид, защото ако изобщо няма тактови импулси или честотата им е по-ниска от допустимата за дадена SPI скорост, също няма да се случи нищо добро. Обикновено новите MCU, които имат вътрешен RC осцилатор, имат групови битове CKSEL, конфигурирани да го използват. Това ни устройва доста добре – клокването става без никакви допълнителни усилия от наша страна. Няма нужда да запоявате кварцовия резонатор или да свързвате външен генератор. Ако посочените битове съдържат различна настройка, ще трябва да се погрижите за тактовата честота в съответствие с настройката. В този случай може да се наложи да свържете кварцов резонатор или външен тактов генератор към MCU. Но в тази статия няма да разглеждаме как се прави това. Примерите за свързване на MK за програмиране, съдържащи се в тази статия, са предназначени за най-простия случай.

Ориз. 1. Обмен на данни през SPI в режим на програмиране

Сега нека се обърнем към фигура 1, взета от документацията за ATmega128A MK. Той показва процеса на предаване на един байт към MK и едновременно получаване на един байт от MK. И двата процеса, както виждаме, използват едни и същи тактови импулси, подавани от програмиста към микроконтролера на неговия SCK вход - един от щифтовете на микросхемата, за който е възложена такава роля в режима на програмиране на SPI. Още две сигнални линии осигуряват приемане и предаване на данни по един бит на такт. Чрез входа MOSI данните влизат в микроконтролера, а данните за четене се вземат от изхода MISO. Обърнете внимание на двете пунктирани линии, начертани от SCK към MISO и MOSI. Те показват в кой момент микроконтролерът „поглъща” битовете данни, зададени на входа MOSI, и в кой момент сам задава свой бит данни на изхода MISO. Всичко е съвсем просто. Но за да влезем в MK в режим на програмиране, все още се нуждаем от сигнал RESET. Да не забравяме и общия GND проводник и VCC захранването. Общо се оказва, че само 6 проводника трябва да бъдат свързани към микроконтролера, за да мига неговия фърмуер чрез SPI. По-долу ще анализираме това по-подробно, но засега ще добавим, че обменът на данни с MK в режим на програмиране чрез SPI се извършва в пакети от 4 байта. Първият байт на всеки пакет е основно изцяло предназначен за кодиране на инструкции. Вторият байт, в зависимост от първия, може да бъде продължение на кода на командата или част от адреса, или може да има произволна стойност. Третият байт се използва основно за предаване на адреси, но може да има произволна стойност в много инструкции. Четвъртият байт обикновено предава данни или има произволна стойност. Едновременно с предаването на четвъртия байт някои команди получават данни, идващи от микроконтролера. Подробности за всяка команда могат да бъдат намерени в документацията на контролера в таблицата, наречена „SPI Serial Programming Instruction Set“. Засега отбелязваме само, че целият обмен с контролера е изграден от поредица от 32-битови пакети, във всеки от които се предава не повече от един байт полезна информация. Това не е много оптимално, но като цяло работи добре.

3. Свързване на MK за програмиране

За да се гарантира, че всички необходими сигнали се подават към входовете на микроконтролера за организиране на SPI интерфейса и четене на данни от неговия MISO изход, не е необходимо да се създава програмист. Това може лесно да се направи с помощта на най-обикновения USB-RS232TTL конвертор.

В интернет често можете да намерите информация, че такива конвертори са по-лоши и че нищо сериозно не може да се направи с тях. Но по отношение на повечето модели конвертори това мнение е погрешно. Да, в продажба има преобразуватели, които нямат всички налични входове и изходи в сравнение със стандартен COM порт (например само TXD и RXD), докато имат неразделим дизайн (микросхемата е пълна с пластмаса - това е невъзможно е да се достигнат неговите щифтове). Но тези не си струва да се купуват. В някои случаи можете да получите липсващите входове и изходи на портове чрез запояване на кабелите директно към чипа. Пример за такъв „подобрен“ преобразувател е показан на фигура 2 (чип PL-2303 - повече подробности за предназначението на неговите щифтове в статията „”). Това е един от най-евтините модели, но има своите предимства, когато се използва в домашни дизайни. Пълнофункционалните адаптерни кабели със стандартен девет-пинов конектор в края, като COM порт, също са широко разпространени. Те се различават от обикновения COM порт само по нивата на TTL и несъвместимостта с наследството софтуери малко старо оборудване. Може също да се отбележи, че кабелите на чипа CH34x се показват като много по-надеждни и стабилни при различни екстремни тестове в сравнение с конверторите на PL-2303. При нормална употреба обаче разликата не се забелязва.

Когато избирате USB-RS232TTL конвертор, трябва да обърнете внимание и на съвместимостта на неговия драйвер с версията на операционната система, която използвате.

Нека разгледаме по-отблизо принципа на свързване на микроконтролер и USB-RS232TTL конвертор, използвайки примера на четири различни модели MK: ATtiny13, ATtiny44, ATmega8 и ATmega128. Фигура 3 показва общата схема на такава връзка. Може да ви изненада да знаете, че RS232 сигналите (RTS, TXD, DTR и CTS) се използват неподходящо. Но не се притеснявайте за това: програмата Perpetuum M може да работи директно с тях - задава изходни стойности и чете входни състояния. Във всеки случай широко използваните преобразуватели USB-RS232TTL на чипове CH34x и PL-2303 предоставят тази възможност - това е проверено. Не трябва да има проблеми и с други популярни конвертори, тъй като за достъп до порта се използват стандартни функции на Windows.

Резисторите, показани на общата схема, по принцип не могат да бъдат инсталирани, но все пак е по-добре да ги инсталирате. Каква е тяхната цел? Използвайки TTL входовете и изходите на преобразувателя и петволтовото захранване на микроконтролера, по този начин се отърваваме от необходимостта да координираме логическите нива - всичко вече е съвсем правилно. Това означава, че връзките могат да бъдат директни. Но по време на експерименти , всичко може да се случи.Например по закона на подлостта една отвертка може да падне точно на мястото, където не би могла да падне и да даде на късо нещо, което в никакъв случай не трябва да бъде на късо.Разбира се всичко може се окаже „отвертка". Резисторите в този случай понякога намаляват последствията. една от целите им е да елиминират евентуален изходен конфликт. Факт е, че след приключване на програмирането микроконтролерът преминава в нормален режим на работа и може се случи, че неговият щифт, свързан към изхода на преобразувателя (RTS, TXD или DTR), също става изход, според току-що записаната програма в MK.В този случай ще бъде много лошо, ако два директно свързани изхода се "бият" - опитайте се да зададете различни логически нива. В такава „борба“ някой може да „загуби“, но ние не искаме това.

Стойностите на трите резистора са избрани на ниво 4,3 KOhm. Това се отнася за връзките между изхода на преобразувателя и входа на микроконтролера. Точността на резисторите няма значение: можете да намалите съпротивлението им до 1 KOhm или да го увеличите до 10 KOhm (но във втория случай рискът от смущения се увеличава при използване на дълги проводници по пътя към MK). Що се отнася до връзката между входа на преобразувателя (CTS) и изхода на микроконтролера (MISO), тук се използва резистор от 100 Ohm. Това се обяснява с особеностите на входа на използвания преобразувател. По време на тестовете е използван преобразувател на микросхемата PL-2303, чиито входове, очевидно, са свързани към положителното захранване със сравнително ниско съпротивление (от порядъка на няколкостотин ома). За да „прекъсна изтеглянето“, трябваше да инсталирам резистор с толкова малко съпротивление. Не е нужно обаче изобщо да го инсталирате. На преобразувателя това винаги е входът. Тя не може да стане изход, което означава, че няма да има конфликт на изходи при каквото и да е развитие на събитията.

Ако чипът има отделен AVCC щифт за захранване на аналогово-цифровия преобразувател (например ATmega8 или ATmega128), той трябва да бъде свързан към общия VCC захранващ щифт. Някои интегрални схеми имат повече от един VCC захранващ щифт или повече от един GND. Например ATmega128 има 3 GND пина и 2 VCC пина. В постоянен дизайн е по-добре да свържете щифтове със същото име един към друг. В нашия случай, по време на програмиране, можете да използвате по един VCC и GND щифт.

А ето как изглежда връзката ATtiny13. Фигурата показва назначенията на щифтовете, използвани при програмиране чрез SPI. До снимката е как изглежда временната връзка в действителност.


Някои може да кажат, че това не е сериозно - връзки по окабеляването. Но аз и ти сме разумни хора. Нашата цел е да програмираме микроконтролера, като отделяме минимум време и други ресурси за него, а не да се изтъкваме пред някого. Качеството не страда. Методът „на кабели“ в този случай е доста ефективен и оправдан. Мигането на фърмуера на контролера е еднократна процедура, така че няма смисъл да го покривате с кристали. Ако се предвижда промяна на фърмуера в бъдеще, без да се премахва контролерът от веригата (в готовия продукт), тогава това се взема предвид при инсталирането по време на производството на устройството. Обикновено за тази цел е инсталиран конектор (RESET, SCK, MOSI, MISO, GND), а MK може да бъде мига дори след инсталиране на платката. Но това са творчески изкушения. Разглеждаме най-простия случай.

Сега нека да преминем към ATtiny44 MK. Тук всичко е почти същото. Въз основа на чертежа и снимката дори начинаещ няма да има затруднения да разбере връзката. Подобно на ATtiny44, можете да свържете микроконтролерите ATtiny24 и ATtiny84 - назначенията на щифтовете за тези три са еднакви.


Друг пример за временно свързване на контролер за програмирането му е ATmega8. Тук има повече щифтове, но принципът е същият - няколко проводника и сега контролерът е готов да „попълни“ информация в него. Допълнителният черен проводник на снимката, идващ от пин 13, не участва в програмирането. Той е предназначен да премахне звуков сигнал от него, след като MK излезе от режима на програмиране. Това се дължи на факта, че по време на отстраняване на грешки в скрипта за "Perpetuum M" програмата беше изтеглена в MK музикална кутия.


Често един контролер се предлага в различни корпуси. В този случай присвояването на щифтове за всеки случай се разпределя по различен начин. Ако корпусът на вашия контролер не е подобен на показания на фигурата, проверете предназначението на щифтовете в техническата документация, която можете да изтеглите от уебсайта на разработчика на MK.

За да завършим картината, нека да разгледаме свързването на MK микросхема с голям брой "крака". Предназначението на допълнителния черен проводник на снимката, идващ от пин 15, е точно същото като в случая с ATmega8.


Вероятно вече сте се убедили, че всичко е съвсем просто. Всеки, който знае как да брои щифтовете на микросхемите (от маркировката в кръг обратно на часовниковата стрелка), ще го разбере. И не забравяйте за точността. Микросхемите обичат спретнати хора и не прощават небрежно отношение.

Преди да преминете към софтуерната част, уверете се, че драйверът за конвертор USB-RS232TTL е инсталиран правилно (проверете Windows Device Manager). Запомнете или запишете номера на виртуалния COM порт, който се появява, когато свържете преобразувателя. Този номер ще трябва да бъде въведен в текста на скрипта, за който можете да прочетете по-долу.

4. Скрипт - програматор за "Перпетуум М"

Разбрахме хардуерната част на „програмиста“. Това вече е половината битка. Сега остава да се справим със софтуерната част. Неговата роля ще изпълнява програмата Perpetuum M под управлението на скрипт, който изпълнява всички необходими функции за взаимодействие с микроконтролера.

Архивът със скрипта трябва да бъде разопакован в същата папка, където се намира програмата perpetuum.exe. В този случай, когато стартирате файла perpetuum.exe, на екрана ще се покаже меню със списък с инсталирани скриптове, сред които ще има реда „AVR MK Programmer“ (може да е единственият). Това е линията, от която се нуждаем.

Скриптът се намира в папката PMS във файла "MK Programmer AVR.pms". Този файл може да се разглежда, изучава и редактира, ако е необходимо, в обикновен текстов редактор като Windows Notepad. Преди да използвате скрипта, най-вероятно ще трябва да направите промени в текста, свързан с настройките на порта. За да направите това, проверете името на порта, използван в Windows Device Manager и, ако е необходимо, направете съответната поправка в реда "PortName="COM4";" - вместо числото 4 може да има друго число. Освен това, когато използвате различен модел USB-RS232TTL конвертор, може да се наложи да промените настройките за инвертиране на сигнала (редовете на скрипта, започващи с думата „High“). Можете да проверите инверсията на сигналите от USB-RS232TTL конвертора, като използвате един от примерите, съдържащи се в инструкциите за програмата Perpetuum M (раздел с функции за работа с порта).

Подпапката MK_AVR съдържа файлове с описания на поддържаните контролери. Ако контролерът, от който се нуждаете, не е сред тях, можете сами да добавите този, който ви трябва, следвайки аналогия. Вземете един от файловете като проба и с помощта на текстов редактор въведете необходимите данни, като ги вземете от документацията за вашия микроконтролер. Основното е да внимавате, да въведете данните без грешки, в противен случай MK няма да бъде програмиран или ще бъде програмиран неправилно. Оригиналната версия поддържа 6 микроконтролера: ATtiny13, ATtiny24, ATtiny44, ATtiny84, ATmega8 и ATmega128. Скриптът реализира автоматично разпознаване на свързания контролер - няма нужда да го задавате ръчно. Ако прочетеният от MK идентификатор не е сред наличните описания, се показва съобщение, че контролерът не може да бъде разпознат.

Архивът със скрипта също съдържа Допълнителна информация. Папката AVR controller inc files съдържа много полезна и обширна колекция от файлове с дефиниции на контролери. Тези файлове се използват при писане на ваши собствени програми за MK. Още четири папки "MusicBox_..." съдържат файлове с програма на асемблерен език и фърмуер, готов за изтегляне в MK отделно за ATtiny13, ATtiny44, ATmega8 и ATmega128. Ако вече сте свързали един от тези MK за програмиране, както е предложено в тази статия, тогава можете да го флашнете точно сега - ще получите музикална кутия. Повече за това по-долу.

Когато изберете реда „MK AVR Programmer“ в менюто на скрипта, скриптът започва да се изпълнява. В същото време той отваря порта, изпраща команда до MK за преминаване в режим на програмиране, получава потвърждение от MK за успешния преход, изисква идентификатора на MK и търси описание на този MK по неговия идентификатор сред наличните файлове с описания. Ако не намери необходимото описание, извежда съответното съобщение. Ако бъде намерено описание, се отваря главното меню на програмиста. Можете да видите неговата екранна снимка на Фигура 8. По-нататъшното разбиране не е трудно - менюто е много просто.

В първата версия на скрипта някои функции на пълноправен програмист не са реализирани. Например, няма начин да четете и записвате в EEPROM. Но ако отворите скрипта в текстов редактор, ще видите, че той е много малък по размер, въпреки факта, че основното нещо вече е внедрено в него. Това предполага, че добавянето на липсващите функции не е толкова трудно - езикът е много гъвкав, позволява ви да внедрите богата функционалност в малка програма. Но в повечето случаи дори съществуващите функции са достатъчни.

Някои функционални ограничения са описани директно в текста на скрипта:
//внедрено записване само от нулевия адрес (записът на разширения сегментен адрес се игнорира, LOAD OFFSET - също)
//редът и непрекъснатостта на записите в HEX файла не се проверяват
//контролната сума не се проверява
Това се отнася за работа с HEX файл, от който се взема кодът на фърмуера за MK. Ако този файл не е повреден, проверката на контролната сума няма да има ефект. Ако е изкривен, няма да е възможно да го откриете с помощта на скрипта. В повечето случаи останалите ограничения няма да навредят, но все пак трябва да ги имате предвид.

5. Музикална кутия - прост занаят за начинаещи

Ако имате един от тези микроконтролери: ATtiny13, ATtiny44, ATmega8 или ATmega128, можете лесно да го превърнете в музикална кутия или музикална карта. За да направите това, достатъчно е да запишете съответния фърмуер в MK - един от четирите, които се намират в папките "MusicBox_..." в същия архив със скрипта. Кодовете на фърмуера се съхраняват във файлове с разширение ".hex". Използването на ATmega128 за такъв занаят, разбира се, е „мазно“, точно като ATmega8. Но това може да бъде полезно за тестване или експериментиране, с други думи, за образователни цели. Приложени са и текстовете на програмите в Assembler. Програмите не са създадени от нулата - за основа е взета програмата за музикална кутия от книгата на А. В. Белов. AVR микроконтролерив радиолюбителската практика." Оригиналната програма е претърпяла редица значителни промени:
1. адаптиран за всеки от четирите MK: ATtiny13, ATtiny44, ATmega8 и ATmega128
2. бутоните са елиминирани - нищо не трябва да се свързва към контролера освен захранване и звуков излъчвател (мелодиите се възпроизвеждат една след друга в безкраен цикъл)
3. продължителността на всяка нота се намалява с продължителността на паузата между нотите, за да се елиминират смущенията в музикалния ритъм
4. осмата мелодия е свързана, не се използва в книжната версия
5. от субективно: някои „подобрения“ за оптимизиране и улесняване на разбирането на алгоритъма

В някои мелодии можете да чуете фалш и дори груби грешки, особено в „Усмивка“ - по средата. Кодовете на мелодията са взети от книгата (или по-скоро изтеглени от уебсайта на автора на книгата заедно с оригиналния asm файл) и не са променени. Явно има грешки в кодирането на мелодиите. Но това не е проблем - всеки, който е „приятелски“ с музиката, може лесно да го разбере и да поправи всичко.

В ATtiny13, поради липсата на 16-битов брояч, трябваше да се използва 8-битов брояч за възпроизвеждане на бележки, което доведе до лек спад в точността на бележките. Но това едва ли се забелязва на ухо.

Относно конфигурационните битове. Техните настройки трябва да съответстват на състоянието на новия микроконтролер. Ако вашият MK е бил използван някъде преди, трябва да проверите състоянието на неговите конфигурационни битове и, ако е необходимо, да ги приведете в съответствие с настройките на новия микроконтролер. Можете да разберете състоянието на конфигурационните битове на новия микроконтролер от документацията за този MK (раздел „Битове за предпазители“). Изключение прави ATmega128. Този MCU има бит M103C, който позволява режим на съвместимост с по-стария ATmega103. Активирането на бита M103C значително намалява възможностите на ATmega128 и този бит е активен на новия MK. Трябва да нулирате M103C в неактивно състояние. За да манипулирате конфигурационните битове, използвайте съответния раздел от менюто на скрипта на програмиста.

Няма смисъл да давам схема на музикалната кутия: тя съдържа само микроконтролер, захранване и пиезо-звуков излъчвател. Захранването се доставя по същия начин, както при програмирането на MK. Излъчвателят на звука е свързан между общия проводник (GND щифт на контролера) и един от пиновете MK, чийто номер може да се намери във файла с асемблиращия код на програмата (*.asm). В началото на програмния текст за всеки MK в коментарите има ред: " звуков сигналсе формира на щифт XX." Когато скриптът на програмиста приключи работата си, микроконтролерът излиза от режима на програмиране и преминава в нормален режим на работа. Възпроизвеждането на мелодии започва веднага. Като свържете звуковия излъчвател, можете да проверите това. Можете да оставите звуковия излъчвател свързан, докато програмирате кристала, само ако аудиото идва от щифт, който не се използва от SPI, в противен случай допълнителният капацитет на щифта може да попречи на програмирането.

Задача: Нека разработим програма за управление на един светодиод. При натискане на бутона светодиодът светва и при отпускане изгасва.

Първо, нека разработим схематична диаграма на устройството. I/O портовете се използват за свързване на външни устройства към микроконтролера. Всеки от портовете може да работи както като вход, така и като изход. Нека свържем светодиода към един от портовете и бутона към другия. За този експеримент ще използваме контролер Atmega8. Този чип съдържа 3 I/O порта, има 2 осем-битови и 1 шестнадесет-битов таймер/брояч. Също така на борда има 3-канален ШИМ, 6-канален 10-битов аналогово-цифров преобразувател и много други. Според мен микроконтролерът е чудесен за изучаване на основите на програмирането.

За свързване на светодиода ще използваме линия PB0, а за четене на информация от бутона ще използваме линия PD0. Диаграмата е показана на фиг.1.

Ориз. 1

Чрез резистор R2 на входа PD0 се подава плюс захранващо напрежение, което съответства на сигнал логическа единица. Когато бутонът е затворен, напрежението пада до нула, което съответства на логическа нула. В бъдеще R2 може да бъде изключен от веригата, като го замени с резистор за вътрешно натоварване, като въведе необходимите настройки в програмата. Светодиодът е свързан към изхода на порт PB0 чрез токоограничаващ резистор R3. За да светне светодиодът, трябва да подадете сигнал логическа единица към линията PB0. Ще използваме вътрешен главен тактов генератор на 4 MHz, тъй като устройството няма високи изисквания за стабилност на честотата.

Сега пишем програмата. Използвам средата за програмиране, за да пиша програми AVR студиоИ WinAvr.Отворете AVR Studio, изскача прозорец за добре дошли, щракнете върху бутона „Създаване на нов проект“, след това изберете типа на проекта – AVR GCC, напишете името на проекта, например „cod1“, проверете „Създаване на папка на проекта“ и „Създаване файл за инициализиране", щракнете върху бутона „Напред", изберете „AVR Simulator“ в левия прозорец и тип микроконтролер „Atmega8“ в десния прозорец, щракнете върху бутона „Край“, отваря се редакторът и дървото на категориите на проекта - първоначалните настройки са завършени.

Първо, нека добавим стандартен описателен текст за Atmega8, използвайки оператора за прикачване на външни файлове: #включи

директивен синтаксис #включи

#включи<имя_файла.h>
#include “filename.h”

Ъглови скоби< и >указва на компилатора, че включените файлове трябва първо да бъдат потърсени в стандартната папка WinAvr, наречена include. Двойните кавички “ и “ казват на компилатора да започне да търси в директорията, където се съхранява проектът.

Всеки тип микроконтролер има свой собствен заглавен файл. За ATMega8 този файл се нарича iom8.h, за ATtiny2313 - iotn2313.h. В началото на всяка програма трябва да включим заглавния файл на микроконтролера, който използваме. Но има и общ заглавен файл io.h. Препроцесорът обработва този файл и в зависимост от настройките на проекта включва необходимия заглавен файл в нашата програма.

За нас първият ред на програмата ще изглежда така:

#включи

Всяка C програма трябва да съдържа една основна функция. Нарича се основен. Изпълнението на програмата винаги започва с изпълнението на основната функция. Една функция има заглавка - int main(void) и тяло - ограничена е фигурни скоби {}.

int main(void)
{
функционално тяло
}

Ще добавим нашия код към тялото на функцията. Типът на връщане се посочва преди името на функцията. Ако функцията не върне стойност, се използва ключът невалиден.

вътр- това е 2-байтово цяло число, обхватът на стойностите е от - 32768 до 32767

След името на функцията параметрите, които се предават на функцията, когато се извиква, са посочени в скоби (). Ако функцията няма параметри, се използва ключовата дума невалиден. функция основенсъдържа набор от команди, системни настройки и основния програмен цикъл.

След това конфигурираме порта дна входа. Режимът на работа на порта се определя от съдържанието на регистъра DDRD(регистър на посоката на предаване на информация). Записваме числото „0x00“ (0b0000000 - в двоична форма) в този регистър; нищо не е свързано към този порт освен бутона, така че конфигурираме целия порт D като вход. Можете да конфигурирате порта бит по бит, като запишете числата 0 или 1 във всеки бит на регистъра (0-вход, 1-изход), например DDRD = 0x81 (0b10000001) - първият и последният ред на порт D работят като изход, останалото като вход. Резисторът за вътрешно натоварване също трябва да бъде свързан. Регистърът PORTx контролира дали вътрешните резистори са включени или изключени, когато портът е в режим на въвеждане. Нека запишем единици там.

Настройка на порта бкъм изхода. Режимът на работа на порта се определя от съдържанието на регистъра DDRB. Нищо освен светодиод към порта бне е свързан, така че целият порт може да бъде конфигуриран като изход. Това става чрез писане в регистъра DDRBчислата "0xFF". За да предотвратите светването на светодиода, когато го включите за първи път, пишете на порта блогически нули. Това става чрез запис PORTB= 0x00;

За присвояване на стойности се използва символът "=" и се нарича оператор за присвояване, за да не се бърка със знака "равно".

Конфигурацията на порта ще изглежда така:

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

Пишем основния цикъл на програмата. докато(“while” от английски) - тази команда организира цикъл, повтаряйки тялото на цикъла много пъти, докато условието бъде изпълнено, тоест докато изразът в скоби е верен. В C изразът се счита за верен, ако не е равен на нула, и за фалшив, ако е равен на нула.

Командата изглежда така:

докато (състояние)
{
тяло на примка
}

В нашия случай основният цикъл ще се състои само от една команда. Тази команда присвоява регистър PORTBрегистърна стойност, която трябва да бъде обърната PORTD.

PORTB = ~PIND; //вземете стойността от порт D, обърнете я и я присвоете на PORTB (пишете на PORTB)

// C изразите се четат отдясно наляво

ПИНрегистър за въвеждане на информация. За да прочетете информация от външния изход на контролера, първо трябва да превключите желания бит на порта в режим на въвеждане. Тоест пишете в съответния бит на регистъра DDRxнула. Едва след това към този щифт може да се подаде цифров сигнал от външно устройство. След това микроконтролерът ще прочете байта от регистъра PINx. Съдържанието на съответния бит съответства на сигнала на външния щифт на порта. Нашата програма е готова и изглежда така:

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

Коментарите се използват широко в езика C. Има два начина за писане.

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

В този случай компилаторът няма да обърне внимание на написаното в коментара.

Ако използвате същата програма и свържете 8 бутона и 8 светодиода към микроконтролера, както е показано на фигура 2, тогава ще стане ясно, че всеки бит от порта дсъвпада с неговия порт бит б. При натискане на бутон SB1 светва HL1, при натискане на бутон SB2 светва HL2 и т.н.

Фигура 2

Статията използва материали от книгата на А. В. Белов. „Урок за разработчици на AVR устройства“

Не веднъж или два пъти съм казвал, че изучаването на MK трябва да започне с асемблер. Цял курс на уебсайта беше посветен на това (въпреки че не е много последователен, но постепенно го сресвам до адекватен външен вид). Да, трудно е, резултатът няма да е на първия ден, но ще се научите да разбирате какво се случва във вашия контролер. Ще знаете как работи, а не да копирате източниците на други хора като маймуна и да се опитвате да разберете защо изведнъж спря да работи. Освен това е много по-лесно за C да създаде реднек код, който ще излезе с вила в най-неподходящия момент.

За съжаление всички искат резултати веднага. Затова реших да тръгна по друг начин - да направя урок за C, но с показване на бельото му. Добрият програмист за вграждане винаги държи своята част от хардуера здраво за болта, като не му позволява да направи нито една стъпка без разрешение. Така че първо ще има C кода, след това какво е произвел компилаторът и как всъщност работи всичко :)

От друга страна, силната страна на C е преносимостта на кода. Ако, разбира се, напишете всичко правилно. Разделяне на работните алгоритми и техните хардуерни реализации в различни части на проекта. След това, за да прехвърлите алгоритъма на друг микроконтролер, ще бъде достатъчно да пренапишете само интерфейсния слой, където се записват всички повиквания към хардуера, и да оставите целия работен код такъв, какъвто е. И, разбира се, четливост. Изходният код на C е по-лесен за разбиране на пръв поглед (въпреки че... например не ме интересува какво да посоча - било то C или ASM :)), но отново, ако всичко е написано правилно. Ще обърна внимание и на тези точки.

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

Първата C програма за AVR

Избор на компилатор и настройка на средата
Има много различни C компилатори за AVR:
На първо място това IAR AVR C- почти определено е признат за най-добрия компилатор за AVR, т.к самият контролер е създаден в тясно сътрудничество между Atmel и специалисти от IAR. Но трябва да платите за всичко. И този компилатор е не само скъп комерсиален софтуер, но също така има толкова много настройки, че отнема много усилия просто да го компилирате в него. Наистина не развих приятелство с него; проектът гниеше поради странни грешки на етапа на свързване (по-късно разбрах, че това е крив крак).

Второ идва WinAVR GCC- мощен оптимизиращ компилатор. Напълно отворен код, крос-платформа, като цяло всички радости от живота. Той също така се интегрира перфектно в AVR Studio, което ви позволява да отстранявате грешки точно там, което е адски удобно. Общо взето го избрах.

Има и CodeVision AVR Cе много популярен компилатор. Стана популярен поради своята простота. Можете да получите работеща програма в него само за няколко минути - съветникът за стартиращ код значително улеснява това, като премахва стандартите за инициализация на всякакви неща. Честно казано, малко съм подозрителен към това - след като трябваше да демонтирам програма, написана от този компилатор, се оказа някаква бъркотия, а не код. Ужасно количество ненужни движения и операции, което доведе до значително количество код и ниска производителност. Въпреки това, може би е имало грешка в ДНК на човека, който е написал оригиналния фърмуер. Освен това той иска пари. Не толкова, колкото IAR, но забележимо. А в демо режим ви позволява да пишете не повече от 2kb код.
Разбира се, че има крак, но ако ще крадете, това е милион, в смисъла на IAR :)

Има и Image Craft AVR CИ MicroCот микроелектрониката. Не трябваше да използвам нито едното, но S.W.G.много похвално Микропаскал, казват, страшно удобна среда за програмиране и библиотеки. Мисля, че MicroC няма да е по-лош, но също е платен.

Както казах, избрах WinAVRпоради три причини: безплатно е, интегрира се в AVR Studio и има само един тон готов код, написан за него за всички случаи.

Така че изтеглете инсталацията на WinAVR с AVR Studio. След това първо се инсталира студиото, след което WinAVR се навива отгоре и се прикрепя към студиото под формата на плъгин. Горещо препоръчвам да инсталирате WinAVR на кратък път, нещо като C:\WinAVR, по този начин ще избегнете много проблеми с пътищата.

Създаване на проект
И така, студиото е инсталирано, C е завинтен, време е да опитате да програмирате нещо. Да започнем с простото, най-простото. Стартирайте студиото, изберете там нов проект като AVR GCC компилатор и въведете името на проекта.

Отваря се работно поле с празен *.c файл.

Сега няма да навреди да конфигурирате показването на пътища в отметките на студиото. За да направите това, отидете на:
Меню Инструменти - Опции - Общи - Раздели на файлове и изберете "Само име на файл" от падащия списък. В противен случай ще бъде невъзможно да работите - разделът ще съдържа пълния път на файла и няма да има повече от два или три раздела на екрана.

Настройка на проекта
Като цяло се счита за класическо да се създаде make файл, в който са описани всички зависимости. И това вероятно е правилно. Но за мен, който израснах с напълно интегрирани IDE като uVisionили AVR студиотози подход е дълбоко чужд. Затова ще го направя по моя начин, всичко използвайки студиото означава.

Натиснете бутона със зъбното колело.


Това са настройките на вашия проект и по-прецизни настройкиавтоматично генериране на makefile. На първата страница просто трябва да въведете честотата, на която ще работи вашият MK. Това зависи от битовете на предпазителя, така че приемаме, че нашата честота е 8000000Hz.
Обърнете внимание и на линията за оптимизация. Сега има -Os - това е оптимизация на размера. Оставете го както е засега, след което можете да опитате да играете с този параметър. -O0 изобщо не е оптимизация.

Следващата стъпка е да конфигурирате пътищата. Първо, добавете директорията на проекта си там - там ще добавите библиотеки на трети страни. Пътят „.\“ ще се появи в списъка.

Файлът Make е генериран, можете да го разгледате в папката по подразбиране във вашия проект, просто погледнете и вижте какво има там.


Това е всичко за сега. Щракнете OK навсякъде и отидете на източника.

Формулиране на проблема
Празен лист хартия е изкушаващ да реализира някаква хитра идея, тъй като баналното мигане на диод вече не работи. Нека веднага да хванем бика за рогата и да реализираме връзката с компютъра - това е първото нещо, което правя.

Ще работи така:
Когато единица (код 0x31) пристигне на COM порта, ще включим диода, а когато пристигне нула (код 0x30), той се изключва. Освен това всичко ще се прави на прекъсвания, а фоновата задача ще бъде мигането на друг диод. Просто и смислено.

Сглобяване на веригата
Трябва да свържем USB-USART преобразувателния модул към USART щифтовете на микроконтролера. За да направите това, вземете джъмпер от два проводника и го поставете на щифтовете на кръст. Тоест свързваме Rx на контролера към Tx на преобразувателя и Tx на преобразувателя към Rx на контролера.

В крайна сметка това е диаграмата:


Не смятам да свързвам останалите пинове, захранване или нулиране, това е стандартно.

Писане на код

Нека направя резервация веднага, че няма да се задълбочавам специално в описанието на самия език C. Има просто колосално количество материал за това, вариращ от класическия "C програмен език" от K&R до различни ръководства.

Намерих един такъв метод в скривалището си; веднъж го използвах, за да изучавам този език. Там всичко е кратко, ясно и по същество. Постепенно го събирам и го плъзгам на моя уебсайт.

Вярно е, че все още не са прехвърлени всички глави, но мисля, че няма да е за дълго.

Малко вероятно е да мога да го опиша по-добре, така че от курса на обучение, вместо подробно обяснение на тънкостите, просто ще предоставя директни връзки към отделни страници от това ръководство.

Добавяне на библиотеки.
На първо място, добавяме необходимите библиотеки и заглавки с дефиниции. В крайна сметка C е универсален език и трябва да му обясним, че работим специално с AVR, така че напишете реда в изходния код:

1 #включи

#включи

Този файл се намира в папката WinAVRи съдържа описание на всички регистри и портове на контролера. Освен това всичко там е хитро, с обвързване към конкретен контролер, който се предава от компилатора през направифайл в параметър MCUи въз основа на тази променлива към вашия проект се свързва заглавен файл с описание на адресите на всички портове и регистри за този конкретен контролер. Еха! Без него също е възможно, но тогава няма да можете да използвате символни имена на регистри като SREG или UDR и ще трябва да запомните адреса на всеки като „0xC1“, което ще бъде главоболие.

Самият екип #включи<имя файла> ви позволява да добавяте съдържание от всякакъв вид към вашия проект текстов файл, например файл с описание на функции или част от друг код. И за да може директивата да намери този файл, ние посочихме пътя до нашия проект (директорията WinAVR вече е регистрирана там по подразбиране).

Главна функция.
C програмата се състои изцяло от функции. Те могат да бъдат вложени и извиквани един от друг в произволен ред и различни начини. Всяка функция има три задължителни параметъра:

  • Върнатата стойност е напр. грях(х)връща стойността на синус от x. Като в математиката, накратко.
  • Предаваните параметри са същите X.
  • Функционално тяло.

Всички предадени и върнати стойности трябва да бъдат от някакъв тип в зависимост от данните.

Всяка C програма трябва да съдържа функция основенкато входна точка в основната програма, иначе изобщо не е C :). По наличието на main в изходния код на някой друг от милион файлове можете да разберете, че това е основната част от програмата, където всичко започва. Така че нека попитаме:

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

int main(void) ( return 0; )

Това е, първо най-простата програманаписано, няма значение, че не прави нищо, току-що започнахме.

Нека да разберем какво направихме.
вътрТова е типът данни, който основната функция връща.

Разбира се, в микроконтролер основенпо принцип нищо не може да се върне и на теория би трябвало да има void main(void), но GCC първоначално е проектиран за компютър и там програмата може да върне стойността операционна системапри завършване. Следователно GCC на void main(void)кълне се в Предупреждение.

Това не е грешка, ще работи, но не харесвам предупрежденията.

невалидентова е типът данни, които предаваме на функцията, в този случай основенследователно също не може да приеме нищо отвън невалиден- манекен. Мъничето се използва, когато няма нужда да се предава или връща нещо.

Ето ги и тях { } фигурните скоби са програмен блок, в този случай тялото на функция основен, кодът ще се намира там.

връщане- това е върнатата стойност, която основната функция ще върне след завършване, тъй като имаме int, тоест число, тогава трябва да върнем число. Въпреки че това все още няма смисъл, защото... на микроконтролера, не можем да стигнем до никъде от main. Връщам нула. Защото няма значение. Но компилаторът обикновено е умен и не генерира код за този случай.
Въпреки че, ако е перверзен, тогава от основенМожете да отидете до MK - например да попаднете в секцията за зареждащо устройство и да го изпълните, но това ще изисква бърникане на ниско ниво с фърмуера, за да коригирате преходните адреси. По-долу ще видите сами и ще разберете как да го направите. За какво? Това е друг въпрос, в 99,999% от случаите това не е необходимо :)

Направихме го и продължихме. Нека добавим променлива, всъщност нямаме нужда от нея и няма смисъл да въвеждаме променливи без нея, но се учим. Ако променливите се добавят в тялото на функция, тогава те са локални и съществуват само в тази функция. Когато излезете от функцията, тези променливи се изтриват и RAM паметта се разпределя за по-важни нужди. .

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

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

неподписанозначава неподписано. Факт е, че в двоичното представяне най-значимият бит се разпределя за знака, което означава, че числото +127/-128 се побира в един байт (char), но ако знакът бъде изхвърлен, той ще се побере от 0 до 255. Обикновено знакът не е необходим. Така неподписан.
азе просто име на променлива. Няма повече.

Сега трябва да инициализираме портовете и 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*скорост на предаване)-1)#define HI(x) ((x)>>8) #define LO(x) ((x)& 0xFF) UBRRL = LO(bauddivider) ; UBRRH = HI(бодделител); 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(бодделител); UBRRH = HI(бодделител); UCSRA = 0; UCSRB = 1<

Страшен? Всъщност има само пет последни реда истински код. Всичко, това #дефинирайтова е предпроцесорен макро език. Почти същите неща като в Assembly, но синтаксисът е малко по-различен.

Те ще улеснят рутинните ви операции по изчисляване на необходимите коефициенти. В първия ред казваме, че вместо това XTALможете спокойно да замените 8000000 и Л- индикация за типа, като long е тактовата честота на процесора. Същото скорост на предаване— честота на предаване на данни чрез UART.

бодделителвече по-сложно, вместо него ще бъде заменен изразът, изчислен по формулата от предишните две.
Добре и Л.О.И здрастиниските и високите байтове ще бъдат взети от този резултат, защото Очевидно може да не се побира в един байт. IN здрасти X (макро входният параметър) се измества осем пъти надясно, което води до оставане само на най-значимия байт. И в Л.О.правим побитово И с числото 00FF, като резултат ще остане само ниският байт.

Така че всичко, което е направено, е като #дефинирайможете спокойно да го изхвърлите и да изчислите необходимите числа на калкулатор и веднага да ги въведете в редовете UBBRL = …. и UBBRH = …..

Мога. Но! Направите това АБСОЛЮТНО НЕВЪЗМОЖНО!

Ще работи така или иначе, но ще имате т.нар магически числа- ценности, взети от нищото и по неизвестни причини, и ако отворите такъв проект след няколко години, ще бъде адски трудно да разберете какви са тези ценности. Дори и сега, ако искате да промените скоростта или да промените честотата на кварца, всичко ще трябва да се преизчисли отново, но променихте няколко числа в кода и това е. Като цяло, ако не искате да бъдете брандирани като кодер, направете кода си така, че да е лесен за четене, разбираем и лесен за модифициране.

Тогава всичко е просто:
Всички тези “UBRRL and Co” са конфигурационни регистри на UART предавателя, с чиято помощ ще комуникираме със света. И сега им присвоихме необходимите стойности, като ги настроихме на желаната скорост и режим.

Тип запис 1<Означава следното: вземете 1 и го поставете на място RXENв байт. RXENтова е 4-ти бит от регистъра UCSRB, Така 1<образува двоичното число 00010000, TXEN- това е 3-тият бит и 1<ще даде 00001000. Единичен "|" това е побитово ИЛИ, така че 00010000 | 00001000 = 00011000. По същия начин останалите необходими конфигурационни битове се задават и добавят към общата купчина. В резултат на това събраният брой се записва в UCSRB. Повече подробности са описани в листа с данни на MK в раздела USART. Така че нека не се разсейваме от технически подробности.

Готово, време е да видим какво се е случило. Кликнете върху компилация и започнете емулация (Ctrl+F7).

Отстраняване на грешки
Минаха всякакви ленти за напредъка, студиото се промени и се появи жълта стрелка близо до входа на основната функция. Това е мястото, където процесорът работи в момента и симулацията е на пауза.

Факт е, че първоначално всъщност беше на линията UBRRL = LO(bauddivider); В края на краищата това, което имаме в define, не е код, а просто предварителни изчисления, поради което симулаторът е малко скучен. Но сега той осъзна, че първата инструкция е завършена и ако се качите на дървото I/O изглед, към секцията USART и погледнете UBBRL байта там, ще видите, че стойността вече е там! 0x33.

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

Отваряне
Сега нулирайте симулацията. Кликнете там Нулиране (Shift+F5). Отворете разглобения листинг, сега ще видите какво всъщност се случва в контролера. Изглед -> Разглобител. И не УАААААА!!! Асемблер!!! УЖАС!!! И Е НЕОБХОДИМО. Така че по-късно, когато нещо се обърка, да не сте глупави в кода и да не задавате тъпи въпроси във форумите, а веднага да влезете в червата и да видите къде сте заседнали. Там няма нищо страшно.

Първо ще има топове от серията:

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 Скок +00000002: 940C0034 JMP 0x00000034 Скок +00000004: 940C0034 JMP 0x00000034 Скок +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 +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 +00000022: 940C0034 JMP 0x000000 34 Jump +00000024: 940C0034 JMP 0x00000034 Jump +00000026: 940C0034 JMP 0x00000034 Jump +00000028: 940C0034 JMP 0x00000034 Jump

00000000: 940C002A JMP 0x0000002A Скок +00000002: 940C0034 JMP 0x00000034 Скок +00000004: 940C0034 JMP 0x00000034 Скок +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 +00000014: 940C0034 JMP 0x000000 34 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 +00000022: 940C0034 JMP 0x000000 34 Jump +00000024: 940C0034 JMP 0x00000034 Jump +00000026: 940C0034 JMP 0x00000034 Jump +00000028: 940C0034 JMP 0x00000034 Jump

Това е векторната таблица на прекъсванията. Ще се върнем към него по-късно, но засега просто погледнете и запомнете, че съществува. Първата колона е адресът на флаш клетката, в която се намира командата, втората е кодът на командата, третата е мнемониката на командата, същата инструкция за асемблиране, третата е операндите на командата. Е, автоматичен коментар.
Така че, ако погледнете, има непрекъснати преходи. И кодът на командата JMP е четири байта, той съдържа адреса за прескачане, записан назад - ниския байт на ниския адрес и кода на командата за прескачане 940C

0000002B: BE1F OUT 0x3F,R1 Out to I/O местоположение

Записване на тази нула на адрес 0x3F.Ако погледнете колоната за изглед на I/O, ще видите, че адрес 0x3F е адресът на SREG регистъра - флаговия регистър на контролера. Тези. ние нулираме SREG да изпълнява програмата при нулеви условия.

1 2 3 4 +0000002C: E5CF LDI R28,0x5F Зареждане незабавно +0000002D: E0D4 LDI R29,0x04 Зареждане незабавно +0000002E: BFDE OUT 0x3E,R29 Out to I/O location +0000002F: BFCD OUT 0x3D,R28 Out to I/O location

0000002C: E5CF LDI R28,0x5F Зареждане незабавно +0000002D: E0D4 LDI R29,0x04 Зареждане незабавно +0000002E: BFDE OUT 0x3E,R29 Out to I/O location +0000002F: BFCD OUT 0x3D,R28 Out to I/O location

Това е зареждане на указателя на стека. Не можете директно да зареждате в I/O регистри, само чрез междинен регистър. Следователно, първо LDI към междинен, а след това оттам OUT към I/O. Също така ще ви разкажа повече за стека по-късно. Засега знайте, че това е област с динамична памет, която виси в края на RAM и съхранява адреси и междинни променливи. Сега сме посочили откъде ще започне нашият стек.

00000032: 940C0041 JMP 0x00000041 Скок

Отидете до самия край на програмата и там имаме забрана за прекъсвания и зацикляне на самата себе си:

1 2 +00000041: 94F8 CLI Global Interrupt Disable +00000042: CFFF RJMP PC-0x0000 Относителен скок

00000041: 94F8 CLI Global Interrupt Disable +00000042: CFFF RJMP PC-0x0000 Относителен скок

Това е в случай на непредвидени обстоятелства, като например излизане от основната функция. Контролерът може да бъде изведен от такъв цикъл или чрез хардуерно нулиране, или, по-вероятно, чрез нулиране от наблюдателно куче. Е, или, както казах по-горе, коригирайте това в шестнадесетичния редактор и галопирайте, където сърцето ни желае. Също така имайте предвид, че има два вида преходи: JMP и RJMP; първият е директен преход към адрес. Той заема четири байта и може директно да преминава през цялата област на паметта. Вторият тип преход е RJMP – относителен. Командата му отнема два байта, но той се придвижва от текущата позиция (адрес) 1024 стъпки напред или назад. И неговите параметри показват отместването от текущата точка. Използва се по-често, тъй като заема половината пространство при промиване и рядко са необходими дълги преходи.

1 +00000034: 940C0000 JMP 0x00000000 Скок

00000034: 940C0000 JMP 0x00000000 Скок

И това е скок до самото начало на кода. Един вид рестартиране. Можете да проверите дали всички вектори скачат тук. Изводът от това е, че ако сега активирате прекъсванията (те са деактивирани по подразбиране) и вашето прекъсване се случи, но няма манипулатор, тогава ще има софтуерно нулиране - програмата ще бъде върната в самото начало.

Основна функция. Всичко е подобно, дори не е нужно да го описвате. Просто погледнете вече изчисленото число, което се въвежда в регистрите. Препроцесорът на компилатора е страхотен!!! Така че няма „магически“ числа!

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

00000036: E383 LDI R24,0x33 Незабавно зареждане +00000037: B989 OUT 0x09,R24 Изход към I/O местоположение 15: UBRRH = HI(бододивер); +00000038: BC10 OUT 0x20,R1 Изход към I/O местоположение 16: UCSRA = 0; +00000039: B81B OUT 0x0B,R1 Изход към I/O местоположение 17: UCSRB = 1<

И ето бъга:

1 2 3 +0000003E: E080 LDI R24.0x00 Зареждане незабавно +0000003F: E090 LDI R25.0x00 Зареждане незабавно +00000040: 9508 RET Връщане на подпрограма

0000003E: E080 LDI R24.0x00 Зареждане незабавно +0000003F: E090 LDI R25.0x00 Зареждане незабавно +00000040: 9508 RET Връщане на подпрограмата

Въпросът е защо компилаторът добавя такива върхове? И това не е нищо повече от Return 0, дефинирахме функцията като int main(void) и така загубихме още четири байта за нищо :) И ако направите void main(void), тогава ще остане само RET, но ще се появи предупреждение , че основната ни функция не връща нищо. Като цяло, правете както искате :)

Труден? Очевидно не. Щракнете върху изпълнение стъпка по стъпка в режим на разглобяване и вижте как процесорът изпълнява отделни инструкции, какво се случва с регистрите. Как става движението през командите и крайния цикъл?

Продължение след няколко дни...

Offtop:
Алексей78Създадох плъгин за Firefox, който улеснява навигацията в моя сайт и форум.
Обсъждане и изтегляне,


Съвременното любителско радио не може да се представи без микроконтролери и това е очевидно. През последните десетилетия микроконтролерите от различни производители са широко разпространени в различни области на човешката дейност. Те често могат да бъдат намерени в най-неочакваните устройства и дизайни. Вие и аз сме свидетели на компютъризацията и автоматизацията на процесите около нас. Истината е, че без познаване на основите на програмирането е станало почти невъзможно да се създават модерни конкурентни устройства...

Ако четете тази статия, вероятно имате желание да разберете как работят микроконтролерите и най-вероятно имате въпроси:

4. Каква литература да уча?

Нека се опитаме да отговорим на тези въпроси.

1. Кой микроконтролер да избера за работа?

8-битовите микроконтролери са много популярни сред радиолюбителите. СНИМКАМикрочипова технология и AVR Atmel, 16-битов MSP430от TI, както и 32-битови микроконтролери, архитектури ARM.

В индустрията, малко по-различно, първото място с голяма разлика се заема от Renesas Electronicsна втория Freescale, на третия Samsung, тогава тръгвай МикрочипИ Т.И., след това всички останали.
Популярността се определя от цената и наличността; наличието на техническа информация и цената на софтуерната поддръжка играят важна роля.

Ще изучаваме 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 ви позволява да създавате проекти и да пишете програми както на асемблер, така и на SI.

Първоначално въпросът винаги е: какъв език за програмиране да избера, за да пиша ефективни програми?

Моят отговор е прост: трябва да можете да пишете на поне два езика: асемблер и SI. Асемблерният език е просто необходим, когато трябва да пишете бързи и компактни подпрограми и макроси, както и различни драйвери на устройства. Но когато трябва да създадете голям проект, изграден върху сложни алгоритми, без познаване на SI, може да се изразходва много време, особено в процеса на отстраняване на грешки, и ако има желание да го прехвърлите на друга платформа, например PIC18 , или STM, може да се превърне в неразрешим проблем.
Освен това вече се появиха хардуерни изчислителни платформи Ардуино, работата с която изисква познаване на езика SI++.
Затова ще пишем програми както на асемблер, така и на SI.

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

3. Как да мигате контролера и какви допълнителни устройства и аксесоари са необходими за удобна работа с тях?

Използваме Datagorian. Освен това ще трябва да закупите макетни платки и захранване с изходно напрежение от 5 волта. Можете да го използвате като захранване с ниска пулсация, като използвате 5-волтов ценеров диод.
Може би с времето Игор и аз ще предложим проект за сглобяване на платка за отстраняване на грешки.

4. Каква литература да уча?

Но, например:
Практическо програмиране на AVR в асемблер. Ревич, 2011
1000 и една микроконтролерна схема Vol. 1-2. Рюмик, 2010-2011
10 практически устройства на AVR MK Книга 1-2. Кравченко, 2008-2009
Урок за разработчик на устройства, използващ AVR MK. Белов, 2008
MK AVR семейства Tiny и Atmega. Ефстифеев, 2008 г
CodeVisionAVR. Ръководство за начинаещи. Лебедев, 2008
Микропроцесорно управление на устройства, тиристори, релета. Белов, 2008
Аналогови интерфейси MK. Стюард, топка, 2007 г
Ние създаваме устройства на AVR MK. Белов, 2007
MK AVR в радиолюбителската практика. Пълен анализ на ATTINY2313. Белов, 2007
Обмен на данни в мрежа и мрежа с MK. Давай, 2007 г
MK AVR. работилница за начинаещи. Хартов, 2007
Приложение на AVR схеми, алгоритми, програми. Баранов, 2006
AVR микроконтролери. Въвеждащ курс. Мортън, 2006 г
Измерване, контрол и регулиране чрез AVR. Тръмпърт, 2006 г
Програмиране на език C за AVR и PIC MK. Шпак, 2006
Проектиране на устройства на MK. Белов, 2005
MK - това е просто, томове 1-3. Фрунзе, 2002-2003
Езикът за програмиране C, 2-ро издание. Керниган, Ричи, 2009 г
Програмиране на микроконтролери ATMEL на езика S. Prokopenko, 2012

5. Къде в интернет можете да зададете въпроси и да получите конкретни отговори?

Можете да задавате въпроси в нашия или във всеки друг форум, където по един или друг начин се засягат теми за микроконтролери. Основното във форумите е да формулирате правилно въпросите, за да получите ясни отговори. Абстрактните въпроси не са добре дошли и най-вероятно ще получите остра критика вместо отговор или въпросът ви ще остане без отговор!

Сега нека разгледаме по-отблизо нашия любим микроконтролер ATMEGA 8

8-битов, високопроизводителен AVR микроконтролер с ниска мощност
Прогресивна RISC архитектура
130 инструкции с висока производителност, повечето инструкции, изпълнени в един тактов цикъл
32 8-битови работни регистъра с общо предназначение
Напълно статична работа
Доближаваща се производителност от 16 MIPS (при 16 MHz).
Вграден 2-цикличен умножител

Енергонезависима памет за програми и данни
8 KB вградена в системата самопрограмируема флаш памет
Осигурява 1000 цикъла на изтриване/запис
Допълнителен сектор с код за зареждане с независими заключващи битове
Осигурява едновременен режим на четене/запис (четене докато записвате)
512 байта EEPROM
Осигурява 100 000 цикъла на изтриване/запис
1 KB вградена SRAM памет
Програмируемо заключване за защита на потребителския софтуер

Вградени периферни устройства
Два 8-битови таймера/брояча с отделен предскалер, единият с режим на сравнение
Един 16-битов таймер/брояч с отделен прескалер и режими на улавяне и сравнение
Брояч в реално време с отделен генератор
Три ШИМ канала
8-канален A/D преобразувател (TQFP и MLF)
6 канала с 10-битова точност
6-канален аналогово-цифров преобразувател (в PDIP пакет)
4 канала с 10-битова точност
2 канала с 8-битова точност
Байт-ориентиран двупроводен сериен интерфейс
Програмируем сериен USART
Сериен интерфейс SPI (главен/подчинен)
Програмируем таймер за наблюдение с отделен вграден осцилатор
Вграден аналогов компаратор

Специални функции на микроконтролера
Нулиране при включване и програмируемо откриване на прекъсване
Вграден калибриран RC осцилатор
Вътрешни и външни източници на прекъсване
Пет режима на ниска консумация: неактивен, пестене на енергия, изключване, режим на готовност и намаляване на шума от ADC

I/O щифтове и корпуси
23 програмируеми I/O линии
28-пинов PDIP пакет, 32-пинов TQFP пакет и 32-пинов MLF пакет

Работни напрежения
2,7 - 5,5 V (ATmega8L)
4,5 - 5,5 V (ATmega8)

Работна честота
0 - 8 MHz (ATmega8L)
0 - 16 MHz (ATmega8)

разлики между ATMEGA16 и 8
16 KB вградена в системата самопрограмируема флаш памет

JTAG интерфейс (съвместим с IEEE 1149.1)
Възможност за периферно сканиране, съвместима с JTAG стандарта
Разширена поддръжка за вградено отстраняване на грешки
Програмиране чрез JTAG интерфейс: Flash, EEPROM памет, джъмпери и заключващи битове

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

8-канален 10-битов аналогово-цифров преобразувател
8 небалансирани канала
7 диференциални канала (само TQFP пакет)
2 диференциални канала с програмируемо усилване от 1x, 10x или 200x (само пакет TQFP)

Шест режима на ниска консумация: неактивен, енергоспестяващ, изключване, режим на готовност, разширен режим на готовност и намаляване на шума от ADC

32 програмируеми I/O линии

40-пинов PDIP пакет и 44-пинов TQFP пакет

AtmelStudio

Ако тепърва започвате, тогава трябва да изтеглите и инсталирате програмата AtmelStudio от официалната страница atmel.com
След като инсталирате програмата AtmelStudio, можете да започнете да създавате проект.
Проект- това е вашата програма, която ще напишете, дебъгвате и флашвате, след компилация, в паметта на микроконтролера.

За да създадете проект, трябва да отворите програмата, ще се появи следният скрийнсейвър:

и ще се отвори страницата за създаване на проект

За да създадете нов проект, трябва да кликнете върху "Нов проект..."
В този случай ще се отвори нов прозорец, където можете да изберете езика за програмиране, името на проекта, неговото местоположение, името на пакета с файловете на проекта и възможността да създадете директория за по-нататъшно използване в други кръстосани проекти . За да създадем проект, в който ще програмираме на асемблер, трябва да изберем - Асемблер, след което променяме името на проекта, местоположението му и избираме ДОБРЕ.

Ще се появи следният прозорец

Избирам „megaAVR, 8 бита“и да намерим микроконтролера, от който се нуждаем, ние избрахме ATmega8.От дясната страна на скрийнсейвъра се появява списък с устройства, които работят с този микроконтролер, едно от които можем да свържем. Избирам ДОБРЕ.

Появява се страницата на текстовия редактор, която ви позволява да редактирате и отстранявате грешки в програмата. Докато страницата е празна, се показват часът и датата на създаване и името на файла на проекта, потребителското име. Има прозорец с допълнителни I/O устройства и прозорец с отчети за компилация на програма. сега ние


Можем да програмираме на асемблер.
По същия начин се създава проект за програмиране на език SI.

Здравейте, жители на MySku! Героят на нашия преглед е микроконтролерът Atmega8A-16PU. Ще ви разкажа за програмирането на този микроконтролер в интегрираната среда за разработка CodeVisionAvr, ще мигаме светодиода и ще разгледаме плюсовете и минусите на работата в тази среда. Може би в бъдеще това ще ви послужи като алтернатива на вече „популярния“ Arduino. Ако се интересувате, отидете на изрязване.

Преамбюл.
Просто така се случи, че започнах запознанството си с MK с Arduino. Премигнах светодиода, свързах различни сензори и щитове и направих различни проекти. Всичко работи, бях доволен, но исках нещо повече. Попаднах на един проект, в който участва Atmega8A, за който трябва сам да напиша фърмуера. Именно той ме накара да проуча процеса на програмиране на „гол“ MK.
И така, имаме микроконтролер от Atmel, семейство AVR Atmega8A.

Спецификации:


Pinout:


Ето го
Сега за работа и програмиране трябва да го свържете към програмиста според схемата:

За съжаление, аз съм като обущар - без ботуши, сега нямам програмист под ръка, така че ще използвам Arduino UNO, за да заредя готовия фърмуер в микроконтролера и да конфигурирам предпазителите. Просто трябва да изтеглите скицата „Arduinoisp“ от папката с примери на Arduino IDE и да я свържете според диаграмата:


Това решение обаче има значителен недостатък, за който ще говоря малко по-късно. Преди да започнем да пишем програма в CodeVisionAvr (наричана по-нататък CvAvr), трябва да решим на каква честота ще работи нашият микроконтролер. По подразбиране, от фабриката, нашият герой работи от вътрешен rc генератор на честота 1 MHz (с възможност за преконфигуриране на 2, 4 и 8 MHz). Тъй като вътрешният rc генератор е фабрично калибриран при определени условия (точно напрежение, температура), точността на работата му в "полеви" условия може да варира от 3% до 10%. За задачи, при които не е необходима висока точност на времето, това може да се пренебрегне; в други случаи е по-добре да се използва външен кварц. В моя проект използвах външен кварц на честота 8 MHz. Сега трябва да „обясним“ на MC, че трябва да работи от външен кварц. Това става чрез смяна на предпазителите. С прости думи, това е нещо като BIOS, като на дънна платка, където посочвате режимите му на работа; по същия начин ние казваме на MK в какви режими, в допълнение към честотата, трябва да работи. Цялата информация ще се съхранява в енергонезависима памет.
Ще ви разкажа за сливането на фърмуера под спойлера; тези, които знаят как да го направят сами, могат да превъртат по-нататък.

Допълнителна информация

Как се регистрират същите тези предпазители?! За това използвах програмата AvrDude, тя е безплатна и може лесно да се намери в интернет. За да настроите правилно предпазителите в съответствие с желаната честота, погледнете листа с данни или можете да използвате обикновен.
Задаваме параметрите, както е на снимката.


Тук всичко е просто:
Clock Source - настройте честотата (External Crystal 3 - 16 Mhz) от външния кварц.
Време за стартиране - стартова скорост на MC след отстраняване на RESET или подаване на захранване (16K CK + 4,1 ms бързо).
Поставете отметка в квадратчето: Ext. Часовник/RC Osc./Ниска честота Crystal: активирайте вътрешни кондензатори (36 pF)
Вътрешен R/C Osc.: оставете без отметка! Външен кристал: активирайте пълно размахване (необходимо за >8 MHz).
Така получихме нисък предпазител 0xEF и висок предпазител 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 е вид нашия подобен на Arduino програмист
COM13 е номерът на com порта, който идентифицира нашия Arduino в системата (във вашия случай трябва да го потърсите в диспечера на устройствата)
19200 - скорост на com порта, оставете както е
m8 - показват, че нашият MK е Atmega8
-U lfuse:w:0xef:m -U hfuse:w:0xc9:m - нашите ниски предпазители 0xEF и високи предпазители 0xC9 са посочени тук
Бъда МОЛЯ ВНИМАТЕЛНО!!, Неправилно посоченият предпазител може да доведе до повреждане на MK (не е нужно да танцуваме с тамбура, за да го възстановим).
Натискаме "Enter" и на изхода получаваме резултата, както е на снимката:


Ако по време на процеса не се появят грешки, тогава работата е свършена, нашият микроконтролер вече ще работи от външен кварц.
Можете да прочетете за предпазителите много подробно, а също и като потърсите в Google.


Сега сме готови да започнем да програмираме. За себе си избрах средата за разработка CvAvr. Езикът за програмиране ще бъде различен от Arduino; в CvAvr той е подобен на C. Нека напишем нашия първи Blink.
След като инсталираме и стартираме средата, ще използваме съветника за създаване на проекти. Изберете „Файл“ - „Нов“ - „Проект“. На въпрос дали ще използваме съветника, отговаряме утвърдително. Целеви тип AVR чип: AT90, ATtity, ATmega.
Ето как изглежда съветникът за проекти:


В раздела Chip изберете ATmega8A, Clock 8.000000 Mhz. Отидете в раздела Портове. Нашият светодиод ще бъде свързан към пин 14 на микроконтролера, според разводката - PB0. В раздела изберете Port B, бит 0 превключете от IN към OUT, т.е. Превключваме режима на работа на 14-ия крак на нашия микроконтролер към изхода.


Това завършва магистърската работа. Изберете „Програма“ - „Генериране, запазване и изход“. Записваме нашия проект, например, под името Blink.

Нека вземем кърпа за крака като тази

/*******************************************************
Тази програма е създадена от
CodeWizardAVR V3.12 Advanced
Автоматичен генератор на програми
Тип чип: ATmega8A
Тип програма: Приложение
Честота на ядрото на AVR: 8.000000 MHz
Модел памет: Малък
Размер на външната RAM памет: 0
Размер на стека от данни: 256
*******************************************************/
#включи
#включи
// Декларирайте вашите глобални променливи тук

Void main(void)
{
// Декларирайте вашите локални променливи тук

// Инициализация на входно/изходни портове
// Инициализация на порт B
// Функция: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=Out
DDRB=(0<// Състояние: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=0
PORTB=(0<

// Инициализация на порт C
// Функция: Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRC=(0<// Състояние: Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTC=(0<

// Инициализация на порт D
// Функция: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<// Състояние: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<

// Инициализация на таймер/брояч 0

// Стойност на часовника: Таймер 0 Спрян
TCCR0=(0<TCNT0=0x00;

// Инициализация на таймер/брояч 1
// Източник на часовник: Системен часовник
// Стойност на часовника: Timer1 Stopped
// Режим: нормален отгоре=0xFFFF
// OC1A изход: Прекъснат
// OC1B изход: Прекъснат
// Потискане на шума: Изкл
// Улавяне на вход при спадащ ръб
// Прекъсване при препълване на Timer1: Изкл
// Прекъсване при улавяне на вход: Изкл
// Сравняване на прекъсване на съвпадение: Изкл
// Сравняване B Match Interrupt: Off
TCCR1A=(0<TCCR1B=(0<TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Инициализация на таймер/брояч 2
// Източник на часовник: Системен часовник
// Стойност на часовника: Timer2 Stopped
// Режим: нормален отгоре=0xFF
// OC2 изход: Прекъснат
ASSR=0<TCCR2=(0<TCNT2=0x00;
OCR2=0x00;

// Инициализация на прекъсване на таймер(а)/брояч(а).
TIMSK=(0<

// Инициализация на външно прекъсване(я).
// INT0: Изкл
// INT1: Изкл
MCUCR=(0<

// USART инициализация
// USART деактивиран
UCSRB=(0<

// Инициализация на аналоговия компаратор
// Аналогов компаратор: Изкл
// Положителният вход на аналоговия компаратор е
// свързан към щифта AIN0
// Отрицателният вход на аналоговия компаратор е
// свързан към щифта AIN1
ACSR=(1<SFIOR=(0<

// Инициализация на ADC
//ADC е деактивиран
ADCSRA=(0<

// SPI инициализация
// SPI деактивиран
SPCR=(0<

// TWI инициализация
// TWI деактивиран
TWCR=(0<

Докато (1)
{


Тук няма за какво да се притеснявате; проектът определя режимите на работа на портовете, таймерите, прекъсванията, USART, аналоговия компаратор, ADC, SPI и свързаните библиотеки. Накратко, всички параметри, които посочихме в съветника, всичко с изключение на портовете и чипа, са конфигурирани по подразбиране. Ще напишем основния програмен цикъл в while (1) (програмен текст). защото работим с PB0 (14 крак), в програмния цикъл ще напишем:
докато (1)
{
PORTB.0=1;
забавяне_ms(1000);
PORTB.0=0;
забавяне_ms(1000);
}
Тук задаваме високо PB0, изчакваме 1 секунда и задаваме ниско, след което цикълът се повтаря. Не забравяйте да включите библиотеката в началото на проекта #include . Нашата програма е готова!!! Както можете да видите, всичко е много просто. Сега изберете „Проект“ - „Изграждане на всички“. Ако не са допуснати грешки, ще видим отчета на съветника:

Размерът на нашата програма беше 198 байта и заемаше 2,4% от паметта на микрона.
След това сглобяваме диаграмата:


Сега отидете в папката с нашия проект, отидете в папката „Debug“, след това „Exe“, има файл с шестнадесетично разширение. В моя случай това е blink.hex.
Остава една последна стъпка. Копирайте този файл в папката с AvrDude. Стартираме отново командния ред, отиваме в нашата папка. Въведете реда avrdude -C avrdude.conf -c avrisp -P COM13 -b 19200 -p m8 -U flash:w:blink.hex
Ето как изглежда на снимката:


Ако всичко е въведено правилно, натиснете "Enter"


Честито! Работата е свършена, светодиодът трябва да мига щастливо за вас :)
Заключение.
В заключение искам да кажа за недостатъка на подобен на Arduino програмист; CvAvr просто не го поддържа. Имайки например AVRISP mkII в ръка, можете да мигате предпазителите и да изтеглите програмата директно от CodeVisionAvr. Между другото, програмистът homebrew също отказа да използва графичния интерфейс AvrDude и работеше само от командния ред.
Разбрах CodeVisionAvr доста бързо; Интернет е пълен с текстови и видео уроци. За няколко седмици усвоих работата с хардуерна ШИМ, прекъсвания, таймери, работа с бутони и свързване на графичен дисплей. По-конкретно, трябваше да направя част от моя проект: да организирам хардуерен 16-битов PWM на Atmega8, да свържа 2 бутона, за да го контролирам, и също така да покажа режимите му на работа на графичен дисплей, което направих с лекота :) Ето няколко снимки:

Допълнителна информация





Резултати в сравнение с Arduino:
+ Разбирането на CvArv не е трудно, защото има съветник за създаване на проект;
+ Наличие на библиотеки с плъгини, има достатъчно от тях;
+ Бърза компилация;
+ Възможност за симулиране на проект в Proteus, както и отстраняване на грешки с помощта на вградения дебъгер;
+ Размерът на програмата е няколко пъти по-малък. Standard Blink ни отне 198 байта, подобна скица в Arduino IDE 1084 байта + 2 KB буутлоудър;
+ Възможност за прилагане на режими, които не могат да бъдат направени на Arduino. Например 16-битова ШИМ (като цяло е възможно на Arduino, но само с „патерици“);
+ Възможността да използвате ATtiny, ATmega микроконтролери за вашите проекти, където Arduino би бил излишен;
- Все пак е по-добре за начинаещ да започне да овладява MK с Arduino;
- Езикът за програмиране е различен от обработката на Arduino;
- Има още библиотеки за Arduino;
- CodeVisionAvr е платена програма, има безплатни версии с ограничения;
Програмирайки „голия“ микроконтролер в CodeVisionAvr, натрупах много опит. Изучаването на таймери, регистри, режими на работа, архитектура, четене на таблици с данни ще повиши вашите умения, ще разшири хоризонтите ви и ще отвори нови аспекти на работа с микроконтролери.
Като бонус, прикачвам няколко снимки, когато разбрах графичния LCD дисплей и си поиграх малко.





P.s. Има още много неща, за които исках да напиша, но това няма да е рецензия, а огромна статия. Готов съм да отговоря на въпроси от моята компетентност, на лични или в коментари. Можете да гледате много уроци на AVR.

Връх