Pořadí programování mikrokontrolérů avr. programování mikrokontroléru avr

Dobrý den, milí radioamatéři!
Vítám vás na stránce ""

Co je mikrokontrolér a proč je potřeba. Podívejme se na jeho definici:

- mikroobvod určený k ovládání elektronických zařízení, nebo jiným způsobem - jednoduchý počítač (mikropočítač) schopný provádět jednoduché úkoly.

Čili ve skutečnosti je mikrokontrolér zařízení, které nám umožňuje realizovat naše nápady (i bláznivé), ale samozřejmě v rámci svých možností. A co je nejdůležitější, realizace myšlenky se nedosahuje vytvářením sofistikovaných elektronických struktur, ale v podstatě pouze silou naší myšlenky (chtěli byste se stát čarodějem?).
Nejoblíbenější mezi radioamatéry jsou dva typy mikrokontrolérů:
PIC- Technologie mikročipů
AVR- od Atmel

Rád bych udělal krátkou odbočku a objasnil jednu ze svých pozic. Nehodlám zde rozebírat přednosti toho či onoho typu mikrokontrolérů, toho či onoho softwaru a obecně všeho, co s mikrokontroléry souvisí, něco radit, ba co víc čtenářům vnucovat. Vše je věcí vkusu, osobních preferencí a vašich konečných cílů při učení mikrokontrolérů. Protože „nesmírnost nelze obsáhnout“, budu veškeré své další vyprávění vést ve vztahu k mikrokontrolérům AVR a ne příliš běžnému, ale mému oblíbenému programu „Algorithm Builder“. Různé typy mikrokontrolérů, programů, se samozřejmě liší, ale mají také mnoho společného. A svět mikrokontrolérů se naučíme tak, abychom později získané znalosti mohli bez problémů aplikovat na PIC a jakýkoli software. A ještě jednou připomenu, že tato série článků je mým pokusem pomoci těm, kteří poprvé slyšeli o existenci mikrokontrolérů a chtějí pochopit, jak s nimi pracovat.

Co se potřebujete naučit pracovat s mikrokontroléry? Vybral bych několik, podle mého názoru, hlavních podmínek:
1. Touha a vytrvalost .
Všechno je zde velmi jednoduché: existuje touha - všechno bude fungovat. A touha s vytrvalostí je obecně super věc.
2. Znalost zařízení mikrokontroléru.
Hluboké znalosti zde nejsou důležité (a možná vůbec ne), ale je nutné vědět, co je „na palubě“ mikrokontroléru. Jedině vědět, z čeho se mikrokontrolér skládá, jaká má zařízení, jejich možnosti, jak fungují – jedině tak budeme schopni využít možnosti mikrokontroléru naplno.
3. Znalost programovacího jazyka a řídicích příkazů mikrokontroléru.
Jak bude mikrokontrolér fungovat, jaké úkoly mu zadáváte a jak je bude provádět, určuje program v něm vložený – program, který si pro mikrokontrolér sami složíte. A tomuto bodu se budeme věnovat podrobněji, abychom zvážili problémy, které mohou v budoucnu nastat.

Program(v překladu toto slovo znamená „předpis“) - předběžný popis nadcházejících událostí nebo akcí.

Například chceme, aby mikrokontrolér blikal LED. Jednoduchý úkol, ale přesto, aby mikrokontrolér tento úkol splnil, musíme nejprve krok za krokem popsat všechny akce mikrokontroléru, napsat program, který musí provést, aby získal výsledek, který potřebujeme - blikající LED dioda . Něco takového:
♦ Rozsviťte LED:
- nakonfigurujte výstup, ke kterému je LED připojena, aby pracoval na výstupu informací
- aplikujte na tento pin logickou úroveň, která vám umožní rozsvítit LED
♦ Chvíli počkejte:
- přejděte na podprogram, který tvoří pauzu (kterou je také potřeba „rozkousat“)
- po dokončení podprogramu pauza se vraťte do hlavního programu
♦ Vypněte LED:
- použijte logickou úroveň na výstup a zhasněte LED
atd.
s termínem Program další pojem je neoddělitelně spojen - Algoritmus(jako Vlk a zajíc, Tom a Jerry).

Algoritmus- soubor pokynů, které popisují postup k dosažení požadovaného výsledku.

Pokud jsme v programu nejpodrobněji předepisovat akce mikrokontroléru, pak v algoritmu my určit postup mikrokontroléru, na jehož základě pak vytvoříme program. Podobně jako v příkladu výše:
♦ Rozsviťte LED
♦ Chvíli počkejte
♦ Vypněte LED
atd.
Tím pádem, algoritmus je předchůdcem programu. A čím pečlivěji a promyšleněji je algoritmus vytvořen, tím snazší bude vytvoření programu.

Celkově je program pro mikrokontrolér sledem akcí mikrokontroléru ve formě sady příkazů a instrukcí, které musí provést, aby dosáhl našich cílů.

Příkazy pro mikrokontrolér vypadají jako sada jedniček a nul:
00110101 011000100
tzv. - příkazové kódy, a příkazové kódy jsou jazykem, kterému mikrokontrolér rozumí. A abychom mohli přeložit náš algoritmus z ruštiny do jazyka mikrokontroléru - do těchto sad nul a jedniček, existují speciální programy.
Tyto programy nám umožňují popsat pořadí práce pro mikrokontrolér v pro nás více či méně srozumitelném jazyce a následně toto pořadí převést do jazyka srozumitelného mikrokontroléru, což má za následek tzv. strojový kód- posloupnost příkazů a instrukcí (samotné nuly a jedničky), kterým rozumí pouze mikrokontrolér. Zavolá se text programu napsaného programátorem zdrojový kód. Program je přeložen z programovacího jazyka (zdrojového kódu) do jazyka mikrokontroléru (strojového kódu) překladatelé. Překladač převádí text programu na strojové kódy, které se následně zapisují do paměti mikrokontroléru.
V takových programech je pořadí činnosti mikrokontroléru popsáno speciálním jazykem - programovacím jazykem. Programovací jazyk se liší od našeho lidského jazyka. Pokud je náš komunikační jazyk primárně určen k výměně informací, pak:

Programovací jazyk - jedná se o způsob předávání příkazů, instrukcí, přehledný návod k činnosti pro mikrokontrolér.

Programovacích jazyků je mnoho a lze je rozdělit do dvou typů:
nízkoúrovňové programovací jazyky
programovací jazyky na vysoké úrovni
Jaký je rozdíl. A liší se svou blízkostí k mikrokontroléru.
Na úsvitu vzniku mikroprocesorové technologie byly programy psány ve strojových kódech, to znamená, že celý algoritmus práce byl postupně zapsán ve formě nul a jedniček. Takto vypadal program:

01000110
10010011
01010010

Je nepravděpodobné, že by někdo dokázal přijít na takovou sadu kombinací dvou čísel a práce prvních programátorů byla velmi pracná. Aby si programátoři usnadnili život, začali vytvářet první programovací jazyky. Čím blíže je tedy programovací jazyk takové sadě nul a jedniček, tím je „nízká úroveň“ a čím dále od nich, tím více „vyšší úroveň“.
Nejběžnější programovací jazyky pro mikrokontroléry:
- jazyk nízké úrovně - assembler
– jazyk na vysoké úrovni – C (Ci)
Podívejme se na příklad jejich rozdílu (tyto příklady jsou abstraktní).
Řekněme, že potřebujeme sečíst dvě čísla: 25 a 35.
V nativním kódu může tento příkaz vypadat takto:
00000101 1101001
V jazyce nízké úrovně:
PŘIDAT Rd, Rr
V jazyce vysoké úrovně:
25+35
Rozdíl mezi jazyky nízké a vysoké úrovně je viditelný pouhým okem, komentáře, jak se říká, jsou nadbytečné.
Pojďme se ale do těchto příkladů ponořit hlouběji. Nebudeme analyzovat příklad strojového kódu, protože je shodný s příkladem v assembleru. V jádru jsou montážní pokyny stejné strojové kódy (příkazy), kterým jsou jednoduše přiřazeny písmenné zkratky, aby se neztratily v nulách a jedničkách. Pomocí příkazu ADD Rd, Rr assembler nastavíme mikrokontrolér tak, aby sečetl dvě nalezená čísla (a proto je tam musíme nejprve napsat) - první do Rd, druhé do Rr a výsledek sčítání vložíme do Rd. Jak vidíte, nastavili jsme pro mikrokontrolér velmi specifický úkol: kde jej získat, co s ním dělat a kam umístit výsledek. V tomto případě pracujeme přímo s mikrokontrolérem.
Příkaz v jazyce na vysoké úrovni: 25+35 , nám známý matematický zápis, příjemný pro naše oči. Ale v tomto případě nepracujeme přímo s mikrokontrolérem, prostě mu nastavíme za úkol sečíst dvě čísla. Výsledek a posloupnost akcí v tomto případě bude stejná jako při provádění příkazu assembleru: nejprve se tato dvě čísla někam zapíší, pak se sečtou a výsledek se někam umístí.
A zde spočívá hlavní rozdíl mezi jazyky na vysoké a nízké úrovni. Pokud v Assembleru řídíme celý proces (ať se nám to líbí nebo ne): víme, kde jsou tato dvě čísla zapsána, a víme, kde bude výsledek, pak v jazyce na vysoké úrovni proces neřídíme. Program sám rozhodne, kam čísla předpíše a kam umístí výsledek. Ve většině případů to nepotřebujeme vědět, protože pro nás je hlavním výsledkem číslo 60 ve výstupu. Výsledkem je, že programy ve vyšších jazycích jsou čitelnější, příjemnější pro oči a menší – koneckonců nemusíme „lézt do všech děr“ a malovat každý krok mikrokontroléru, programu udělá to za nás později, když to zkompiluje - přeloží to do strojových kódů. Má to ale i nevýhodu. Dva identické algoritmy napsané v assembleru a v C budou mít po převodu do strojových kódů jinou velikost: program napsaný v assembleru bude o 20-40 % kratší než program napsaný v C – čert ví, kudy C vede dosáhnout výsledku, který potřebujeme. A jsou případy, kdy se nedůvěřuje vysokoúrovňovému jazyku a do programu C vloží kód napsaný v Assembleru.
Profesionální programátoři zpravidla znají několik programovacích jazyků (nebo pracují v týmu, který zahrnuje specialisty na různé jazyky), kreativně kombinují své funkce a výhody v jednom programu. No my, amatéři, potřebujeme umět alespoň jeden jazyk (pro začátek) a je potřeba začít (a jsem o tom pevně přesvědčen a nikdo mě nepřesvědčí) od jazyka nízké úrovně - Assembly.

No, myslím, a tady je nám vše jasné - musíte se naučit programovací jazyk jiným způsobem - v žádném případě.

Příkazy a instrukce pro ovládání mikrokontroléru.
Mikrokontroléry AVR mají více než 130 různých příkazů, které mu umožňují realizovat všechny možnosti, které jsou v něm obsaženy. Ale hned řeknu, že málokterý amatér je všechny zná, natož aby je všechny používal. Obvykle je v amatérské praxi dostatek znalostí a polovina týmů, nebo i méně. Ale musíte se naučit příkazy. Čím více příkazů budete znát, tím propracovanější (v dobrém slova smyslu) a elegantnější programy budou.

Aritmetická logická jednotka a organizace paměti - programová paměť, datová paměť, energeticky nezávislá paměť



V tomto návodu na avr jsem se pokusil popsat všechny nejzákladnější věci pro začátečníky k programování mikrokontrolérů. avr. Všechny příklady jsou postaveny na mikrokontroléru atmega8. To znamená, že k opakování všech lekcí budete potřebovat pouze jeden MK. Jako emulátor elektronických obvodů se používá Proteus - podle mého názoru nejlepší volba pro začátečníky. Programy ve všech příkladech jsou napsány na kompilátoru C pro avr CodeVision AVR. Proč ne v nějakém assembleru? Protože začátečník je již nabitý informacemi a program, který násobí dvě čísla, zabere v assembleru asi sto řádků a ve složitých tučných projektech používají C. Kompilátor CodeVision AVR je nabroušený pro mikrokontroléry atmel, má pohodlný generátor kódu, a dobré rozhraní a přímo z něj může být flashován mikrokontrolérem.

Tento tutoriál ukáže a na jednoduchých příkladech vysvětlí, jak:

  • Začněte programovat mikrokontroléry, kde začít, co k tomu potřebujete.
  • Jaké programy použít k napsání firmwaru pro avr, k simulaci a ladění kódu na PC,
  • Jaká periferní zařízení jsou uvnitř MK, jak je ovládat pomocí vašeho programu
  • Jak zapsat hotový firmware do mikrokontroléru a jak jej odladit
  • Jak vyrobit PCB pro vaše zařízení
Abyste mohli udělat první kroky k programování MK, potřebujete pouze dva programy:
  • Proteus je emulátorový program (můžete v něm vyvinout obvod, aniž byste se uchýlili ke skutečnému pájení a poté náš program otestovat na tomto obvodu). Nejprve spustíme všechny projekty v Proteus a poté již můžeme pájet skutečné zařízení.
  • CodeVisionAVR je kompilátor programovacího jazyka C pro AVR. V něm budeme vyvíjet programy pro mikrokontrolér a přímo z něj bude možné flashovat skutečný MK.
Po instalaci Proteus jej spusťte
Nabízí nám, abychom viděli projekty, které s ním jdou, my zdvořile odmítáme. Nyní v něm vytvoříme nejjednodušší obvod. Chcete-li to provést, klikněte na ikonu vizuálně se nic neděje. Nyní musíte kliknout na malé písmeno R (vybrat z knihovny) v panelu seznamu komponent se otevře okno pro výběr komponent
do pole masky zadáme název komponenty, kterou chceme v knihovně najít. Potřebujeme například přidat mikrokontrolér mega8
v seznamu výsledků šťouchněte do mega8 a stiskněte tlačítko OK. V seznamu součástek máme mikrokontrolér mega8
Přidáme tedy další rezistor do seznamu součástek zadáním slova do pole masky res a LED vedený

Chcete-li umístit součásti do diagramu, klikněte na součást, poté klikněte na pole diagramu, vyberte umístění součásti a klikněte znovu. Chcete-li k obvodu nalevo přidat uzemnění nebo společné mínus, klikněte na "Terminal" a vyberte Ground. Sečtením všech součástek a jejich propojením tedy dostaneme takový jednoduchý obvod
Vše, nyní je naše první schéma připraveno! Ale možná se ptáte, co může dělat? Ale nic. Nic, protože aby mikrokontrolér fungoval, je potřeba pro něj napsat program. Program je seznam instrukcí, které mikrokontrolér provede. Potřebujeme mikrokontrolér nainstalovat na nohu PC0 logická 0 (0 voltů) a logická 1 (5 voltů).

Psaní programu pro mikrokontrolér

Program napíšeme v jazyce C pomocí kompilátoru CodeVisionAVR. Po spuštění CV se nás zeptá, co chceme vytvořit: Zdroj nebo Projekt Vybereme to druhé a stiskneme tlačítko OK. Dále budeme požádáni o spuštění CVAVR CodeWizard (toto je neocenitelný nástroj pro začátečníky, protože dokáže vygenerovat hlavní kostru programu) Vybrat Ano
Průvodce začíná aktivní kartou Chip, zde můžeme vybrat model našeho MK - to je mega8 a frekvenci, na které bude MK pracovat (mega8 je standardně nastaveno na 1 megahertz), takže vše nastavíme tak, jak je uvedeno na snímek obrazovky výše. Přejděte na kartu Porty
Mikrokontrolér atmega8 má 3 porty: Port C, Port D, Port B. Každý port má 8 pinů. Piny portu mohou být ve dvou stavech:
  • Výstup
Pomocí registru DDRx.y můžeme pin nastavit jako vstupní nebo výstupní. Pokud v
  • DDRx.y = 0 - výstup funguje jako VCHOD
  • DDRx.y = 1 pin funguje na VÝSTUP
Když je pin nakonfigurován jako výstup, můžeme jej nastavit na logickou 1 (+5 voltů) a logickou 0 (0 voltů). To se provádí zápisem do registru PORTx.y. Dále bude podrobně pojednáno o vstupně-výstupních portech. A nyní nastavíme vše, jak je znázorněno na snímku obrazovky, a klikněte na Soubor->Generovat, Uložit a ukončit. Dále nám CodeWizard nabídne uložení projektu, my ho uložíme a podíváme se na kód:

#zahrnout //knihovna pro vytváření časových zpoždění void main(void) ( PORTB=0x00; DDRB=0x00; PORTC=0x00; DDRC=0x01; // vytvoření výstupu PC0 nohy PORTD=0x00; DDRD=0x00; // Inicializace časovače/počítadla 0 TCCR0=0x00; TCNT0=0x00; // Inicializace časovače/počítadla 1 TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0CR0AH=00; OCR1L=0CR0AH=00; OCR1L=0x0x00; OCR0 ; OCR1BL=0x00; // Inicializace časovače/počítadla 2 ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // Inicializace externího přerušení MCUCR=0x00; // Časovač(y)/počítadla ) Inicializace přerušení TIMSK=0x00; // Inicializace analogového komparátoru ACSR=0x80; SFIOR=0x00; while (1) ( ); )


Všechno se vám zde může zdát děsivé a neznámé, ale ve skutečnosti tomu tak není. Kód lze zjednodušit vyhozením inicializace periferií MK, které nepoužíváme. Po zjednodušení to vypadá takto:

#zahrnout //knihovna pro práci s mikrokontrolérem mega8 #include //knihovna pro vytváření časových zpoždění void main(void) ( DDRC=0x01; /* udělejte z nohy PC0 výstupní záznam 0x01 vám může připadat neznámý a toto je pouze číslo 1 v šestnáctkové soustavě, tento řádek bude ekvivalentní 0b00000001 v binárním formátu, pak budu psát přesně takto. */ while (1) ( ); )


Věci jsou dobré. Aby ale LEDka blikala, musíme změnit logickou úroveň na noze PC0. Chcete-li to provést, přidejte do hlavní smyčky několik řádků:

#zahrnout //knihovna pro práci s mikrokontrolérem mega8 #include //knihovna pro vytváření časových zpoždění void main(void) ( DDRC=0x01; /* udělejte z nohy PC0 výstupní záznam 0x01 vám může připadat neznámý a toto je pouze číslo 1 v šestnáctkové soustavě, tento řádek bude ekvivalentní 0b00000001 binárně, pak budu psát přesně takto.*/ while (1)//hlavní smyčka programu (// závorka operátora hlavní smyčky programu otevře PORTC.0=1; //nastaví port C 1 na pin 0 delay_ms(500); //udělá zpoždění za 500 milisekund PORTC.0=0; // nastaví port C 0 na pin 0 delay_ms(500); // udělá zpoždění 500 milisekund;// zavře závorku operátora hlavní programové smyčky)


Vše, nyní je kód připraven. Kliknutím na ikonu Build all Project files zkompilujeme (přeložíme do instrukcí procesoru MK) náš program. Ve složce Exe, která se nachází v našem projektu, by se měl objevit soubor s příponou hex, toto je náš soubor firmwaru pro MK. Abyste mohli nahrát náš firmware do virtuálního mikrokontroléru v Proteus, musíte dvakrát kliknout na obrázek mikrokontroléru v Proteus. Objeví se okno jako toto
klikněte na ikonu složky v poli Program File, vyberte hex - soubor našeho firmwaru a stiskněte tlačítko OK. Nyní můžeme spustit simulaci našeho obvodu. Chcete-li to provést, klikněte na tlačítko "Přehrát" v levém dolním rohu okna Proteus.

Více než jednou nebo dvakrát jsem řekl, že studium MK by mělo začít assemblerem. Tomu byl věnován celý kurz na stránkách (sice to není moc konzistentní, ale postupně to učešu do adekvátního vzhledu). Ano, je to těžké, výsledek nebude hned první den, ale naučíte se rozumět tomu, co se děje ve vašem ovladači. Budete vědět, jak to funguje, a nebudete jako opice kopírovat zdroje jiných lidí a snažit se pochopit, proč to najednou přestalo fungovat. Kromě toho je pro C mnohem snazší pohrát si s kódem dělníka, který vyleze vidlemi v tu nejméně vhodnou chvíli.

Bohužel každý chce výsledky hned. Proto jsem se rozhodl jít jinou cestou – udělat návod na C, ale s ukázkou jeho spodního prádla. Dobrý programátor embedderů vždy pevně drží svůj kus železa za škvarku, čímž mu zabrání udělat jediný krok bez dovolení. Takže co bude nejdřív C kód, pak co zrodil kompilátor a jak to celé funguje ve skutečnosti :)

Na druhou stranu, silnou stránkou C je přenositelnost kódu. Pokud samozřejmě napsat vše správně. Rozdělení pracovních algoritmů a jejich železných implementací do různých částí projektu. Poté, aby bylo možné přenést algoritmus na jiný MK, bude stačit přepsat pouze vrstvu rozhraní, kde je zapsán veškerý přístup k hardwaru, a ponechat veškerý pracovní kód tak, jak je. A samozřejmě čtivost. Zdrojový kód Sish je snazší pochopit na první pohled (i když .. například je mi jedno, na co kliknu - alespoň si, alespoň asm :)), ale znovu, pokud je vše napsáno správně. I těmto bodům budu věnovat pozornost.

Jako experimentální kus železa, na kterém bude umístěn lví podíl na všech příkladech, bude moje debugovací deska.

První C program pro AVR

Výběr kompilátoru a instalace prostředí
Existuje mnoho různých kompilátorů C pro AVR:
Za prvé, toto IAR AVR C- téměř jednoznačně uznáván jako nejlepší kompilátor pro AVR, tk. samotný ovladač byl vytvořen v úzké spolupráci mezi Atmelem a specialisty z IAR. Za všechno se ale musí platit. A tento kompilátor není jen drahý komerční software, ale má i takovou přehršel nastavení, že ho v něm musíte jen pracně zkompilovat. Opravdu jsem s ním neměl přátelství, projekt se rozpadl kvůli podivným chybám ve fázi propojení (později jsem zjistil, že to byla křivá trhlina).

Druhá jede WinAVR GCC je výkonný optimalizační kompilátor. Plně otevřený zdroj, multiplatformní, obecně všechny radosti života. Dokonale se také integruje do AVR Studia, což vám umožní ladit přímo tam, což je pekelně pohodlné. Obecně jsem si to vybral.

Také mají CodeVision AVR C je velmi oblíbený kompilátor. Stala se populární díky své jednoduchosti. Funkční program v něm získáte za pár minut – velkou měrou k tomu přispívá průvodce startovacím kódem, který razí standardy pro inicializaci případných uartů. Abych byl upřímný, chovám se k němu nějak podezřívavě - jakmile jsem musel rozebrat program napsaný tímto kompilátorem, objevila se nějaká kaše a ne kód. Strašné množství zbytečných gest a operací, což vedlo k poměrně velkému množství kódu a pomalému výkonu. Možná však došlo k chybě v DNA původního zapisovače firmwaru. Navíc chce peníze. Ne tolik jako IAR, ale znatelné. A v demo režimu vám umožňuje napsat ne více než 2 kb kódu.
Samozřejmě je tam crack, ale když kradeš, tak milion, ve smyslu IAR :)

Existuje také Image Craft AVR C a MicroC z mikroelektroniky. Ani jedno jsem nemusel použít, ale... SWG moc chválí mikropascal, říkají, strašně pohodlné programovací prostředí a knihovny. Myslím, že MicroC nebude o nic horší, ale také placený.

Jak jsem řekl, vybral jsem WinAVR ze tří důvodů: zdarma, integruje se do AVR Studia a je pro něj napsána jen hromada připraveného kódu pro všechny příležitosti.

Stáhněte si tedy WinAVR s a AVR Studio. Dále se nejprve nainstaluje studio, pak se shora sroluje WinAVR a přichytí se ke studiu ve formě zásuvného modulu. Důrazně doporučuji umístit WinAVR na krátkou cestu, něco jako C:\WinAVR, předejdete tak spoustě problémů s cestami.

Tvorba projektu
Takže studio je nachystané, C našlápnuto, je čas zkusit něco naprogramovat. Začněme tím jednoduchým, nejjednodušším. Spusťte studio, vyberte nový projekt jako kompilátor AVR GCC a zadejte název projektu.

Pracovní plocha se otevře s prázdným souborem *.c.

Nyní neuškodí nakonfigurovat zobrazení cest v záložkách studia. Chcete-li to provést, přejděte na:
Nabídka Nástroje - Možnosti - Obecné - Karty souborů a z rozevíracího seznamu vyberte možnost "Pouze název souboru". V opačném případě nebude možné pracovat - karta bude obsahovat úplnou cestu k souboru a na obrazovce nebudou více než dvě nebo tři karty.

Nastavení projektu
Obecně se za klasické považuje vytvoření souboru make, ve kterém by byly popsány všechny závislosti. A to je asi správně. Ale pro mě, který vyrostl s plně integrovanými IDE, jako uVision nebo AVR Studio tento přístup je hluboce cizí. Proto to udělám po svém, všemi prostředky studia.

Klikněte na tlačítko ozubeného kola.


Toto jsou nastavení pro váš projekt, nebo spíše nastavení pro automatické generování souboru make. Na první stránce stačí zadat frekvenci, na které bude váš MK fungovat. Záleží na pojistkových bitech, takže předpokládáme, že frekvence je 8000000Hz.
Věnujte pozornost také optimalizační linii. Nyní je zde -Os je optimalizace velikosti. Nechte to zatím tak, jak je, pak si můžete zkusit pohrát s tímto parametrem. -O0 není vůbec žádná optimalizace.

Dalším krokem je nastavení cest. Nejprve si tam přidejte adresář vašeho projektu – dáte tam knihovny třetích stran. V seznamu se objeví cesta ".\".

Vytvoří se soubor make, můžete se na něj podívat ve výchozí složce ve vašem projektu, stačí se podívat, co tam je.


To je prozatím vše. Všude klikněte na OK a přejděte ke zdroji.

Formulace problému
Prázdný štítek svádí ke ztělesnění nějakého mazaného nápadu, protože banální blikání diody již nevkládá. Okamžitě vezmeme býka za rohy a implementujeme spojení s počítačem - to je první věc, kterou dělám.

Bude to fungovat takto:
Když jednotka dorazí na COM port (kód 0x31), rozsvítíme diodu a když dorazí nula (kód 0x30), zhasneme ji. Navíc vše bude probíhat na přerušení a na pozadí bude blikat další dioda. Jednoduché a smysluplné.

Sestavení schématu
Potřebujeme připojit modul převodníku USB-USART k pinům USART mikrokontroléru. Abychom to udělali, vezmeme propojku dvou vodičů a nasadíme je na kolíky křížem. To znamená, že propojíme Rx regulátoru s Tx převodníku a Tx převodníku s Rx regulátoru.

Nakonec se ukázalo, že toto je schéma:


O zapojení zbývajících výstupů, napájení, resetu neuvažuji, to je standardní

Napíšeme kód

Okamžitě udělám rezervaci, že se nebudu ponořit konkrétně do popisu samotného jazyka C. K tomu je prostě obrovské množství materiálu, od klasického „programovacího jazyka C“ od K&R po různé příručky.

Jedna taková metoda byla nalezena v mé skrýši, kdysi jsem s ní tento jazyk studoval. Vše je krátké, jasné a k věci. Postupně to píšu a přetahuji na svůj web.

Je pravda, že tam ještě nebyly přesunuty všechny kapitoly, ale myslím, že to není na dlouho.

Je nepravděpodobné, že to popíšu lépe, proto ze školení místo podrobného vysvětlení spletitosti Cish jednoduše uvedu přímé odkazy na jednotlivé stránky této příručky.

Přidávání knihoven.
Nejprve přidáme potřebné knihovny a hlavičky s definicemi. C je přece univerzální jazyk a je potřeba vysvětlit, že pracujeme s AVR, takže do zdrojového kódu zadejte řádek:

1 #zahrnout

#zahrnout

Tento soubor je umístěn ve složce WinAVR a obsahuje popis všech registrů a portů řadiče. A tam je vše ošidné s odkazem na konkrétní řadič, přes který je překladač přenášen udělat soubor v parametru MCU a na základě této proměnné je k vašemu projektu připojen hlavičkový soubor s popisem adres všech portů a registrů pro tento konkrétní kontrolér. Jak! Bez toho můžete také, ale pak nebudete moci používat symbolická jména registrů jako SREG nebo UDR a budete si muset pamatovat adresu každého jako "0xC1", a to vám láme hlavu.

Úplně stejný tým #zahrnout<имя файла> umožňuje přidat do projektu obsah libovolného textového souboru, například soubor s popisem funkcí nebo kusem jiného kódu. A aby direktiva mohla tento soubor najít, uvedli jsme cesty k našemu projektu (adresář WinAVR je zde již ve výchozím nastavení registrován).

hlavní funkce.
C program je o funkcích. Mohou být vnořeny a volány jeden od druhého v libovolném pořadí a mnoha různými způsoby. Každá funkce má tři požadované parametry:

  • Návratová hodnota, např. hřích(x) vrátí hodnotu sinusu x. Zkrátka jako v matematice.
  • Přenesené parametry, stejné x.
  • Funkční tělo.

Všechny předané a vrácené hodnoty musí být určitého typu v závislosti na datech.

Každý program v C musí obsahovat funkci hlavní jako vstupní bod do hlavního programu, jinak to vůbec není C :). Přítomností hlavního ve zdroji milionu souborů někoho jiného můžete pochopit, že toto je hlavní část programu, kde vše začíná. Zde nastavíme:

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

int main(void) ( return 0; )

To je vše, první nejjednodušší program byl napsán, je jedno, že nic nedělá, teprve jsme začali.

Podívejme se, co jsme udělali.
int je datový typ, který vrací hlavní funkce.

Samozřejmě v mikrokontroléru hlavní v zásadě nelze nic vrátit a teoreticky by mělo void main (void), ale GCC je originálně doostřené na PC a tam může program po dokončení vrátit hodnotu operačnímu systému. Proto GCC zapnuto void main (void) přísahá Varováním.

To není chyba, to půjde, ale nemám rád varování.

prázdnota v tomto případě jde o typ dat, která funkci předáváme hlavní také nemůže přijmout nic zvenčí, básník prázdnota- prázdný. Útržek se používá, když není třeba nic předat nebo vrátit.

Zde jsou tyto { } složené závorky je programový blok, v tomto případě tělo funkce hlavní, bude tam kód umístěn.

vrátit se- toto je návratová hodnota, kterou funkce main dá po dokončení, protože máme int, tedy číslo, musíme vrátit číslo. I když to stále nedává smysl, protože. na mikrokontroléru z hlavního, můžeme jen nikam jít. Vracím nula. Pro nefig. A kompilátor je obvykle chytrý a negeneruje kód pro tento případ.
I když, když zvrácený, tak z hlavní můžete přejít na MK - například vypadnout do sekce bootloader a spustit jej, ale zde již budete potřebovat nízkoúrovňový výběr firmwaru, abyste mohli opravit přechodové adresy. Níže uvidíte a pochopíte, jak na to. za co? To je další otázka, v 99,999% případů to není nutné :)

Hotovo, pokračuj. Přidejme proměnnou, vlastně ji nepotřebujeme a bez ní bychom neměli zavádět proměnné, ale učíme se. Pokud jsou proměnné přidány do těla funkce, pak jsou lokální a existují pouze v této funkci. Když funkci ukončíte, tyto proměnné se vymažou a paměť RAM je přidělena důležitějším potřebám. .

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

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

nepodepsaný znamená nepodepsaný. Faktem je, že v binární reprezentaci je nejvýznamnější bit přiřazen znaménku, což znamená, že číslo +127/-128 se vejde do jednoho bajtu (char), ale pokud se znaménko zahodí, vejde se od 0 do 255. Obvykle znak není potřeba. Aby nepodepsaný.
i je pouze název proměnné. Už ne.

Nyní musíme inicializovat porty a UART. Samozřejmě můžete vzít a připojit knihovnu a zavolat nějaký UartInit (9600); ale pak nebudete vědět, co se vlastně stalo.

Děláme toto:

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(přenosová jednotka) ; UBRRH = HI(přenosový dělič) ; 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 (přenosový dělič); UBRRH = HI (přenosový dělič); UCSRA = 0; UCSRB = 1<

děsivé? Ve skutečnosti existuje pouze pět posledních řádků skutečného kódu. Všechno, to #definovat je to preprocesorový makro jazyk. Téměř stejné vrcholy jako v Assembleru, ale syntaxe je poněkud odlišná.

Usnadní vám rutinní operace pro výpočet požadovaných koeficientů. V prvním řádku říkáme, že místo XTAL můžete bezpečně nahradit 8000000 a L- označení typu, říkají long je hodinová frekvence procesoru. Stejný přenosová rychlost- frekvence přenosu dat přes UART.

přenosový dělič již složitější, místo něj se dosadí výraz vypočítaný vzorcem z předchozích dvou.
Dobře a HLE a AHOJ z tohoto výsledku budou převzaty nízké a vysoké bajty, protože evidentně se nevejde do jednoho bajtu. V AHOJ x se posune (vstupní parametr makra) osmkrát doprava, v důsledku toho z něj zůstane pouze horní bajt. A dovnitř HLE uděláme bitový AND s číslem 00FF, ve výsledku ponecháme pouze nízký bajt.

Takže všechno, co se dělá, je jako #definovat můžete to klidně vyhodit a na kalkulačce si spočítat potřebná čísla a hned je zadat do řádků UBBRL = .... a UBBRH=…..

Umět. Ale! Udělej tohle PŘÍSNĚ NEMOŽNÉ!

Bude to fungovat tak a tak, ale budete mít tzv magická čísla- hodnoty převzaté odnikud a není jasné proč, a pokud takový projekt otevřete za pár let, bude zatraceně těžké pochopit, co tyto hodnoty jsou. A teď, když chceš změnit rychlost, nebo změnit frekvenci quartzu a budeš muset vše přepočítat, tak jsi změnil pár čísel v kódu a je to. Obecně platí, že pokud nechcete být považováni za špatného kodéra, udělejte kód tak, aby byl dobře čitelný, srozumitelný a snadno upravitelný.

Pak je vše jednoduché:
Všechny tyto "UBRLL and Co" jsou konfigurační registry vysílače UART, se kterými budeme komunikovat se světem. A nyní jsme jim přiřadili potřebné hodnoty, nastavili je na požadovanou rychlost a požadovaný režim.

Zobrazit záznam 1< Znamená následující: vezměte 1 a vložte jej na své místo RXEN v byte. RXEN toto je 4. bit registru UCSRB, tak 1< tvoří binární číslo 00010000, TXEN je 3. bit a 1< dá 00001000. Jediné "|" je to bitové NEBO, takže 00010000 | 00001000 = 00011000. Stejným způsobem se nastaví zbývající potřebné konfigurační bity a přidají se do společné haldy. Výsledkem je, že shromážděné číslo je zapsáno do UCSRB. Podrobněji je to popsáno v datasheetu na MK v sekci USART. Nenechte se tedy rozptylovat technickými detaily.

Hotovo, je čas podívat se, co se stane. Klikněte na kompilaci a spusťte emulaci (Ctrl+F7).

Ladění
Proběhly nejrůznější ukazatele průběhu, studio se změnilo a u vchodu do hlavní funkce se objevila žlutá šipka. Zde se právě nachází procesor a simulace je pozastavena.

Faktem je, že zpočátku to ve skutečnosti bylo na řádku UBRRL = LO(bauddivider); Koneckonců, to, co definujeme, není kód, ale pouhé předběžné výpočty, takže simulátor je trochu nudný. Ale teď si uvědomil, že první pokyn byl splněn a jestli vylezeš na strom Zobrazení I/O, do sekce USART a podívejte se tam na bajt UBBRL, uvidíte, že už tam nějaká hodnota je! 0x33.

Udělejte ještě jeden krok. Podívejte se, jak se změní obsah jiného registru. Projděte si je tedy všechny, věnujte pozornost tomu, že všechny uvedené bity jsou nastaveny tak, jak jsem vám řekl, a jsou nastaveny současně pro celý bajt. Věci nepůjdou dále než Návrat – program je u konce.

Otevírací
Nyní resetujte simulaci na nulu. Klikněte tam Resetovat (Shift+F5). Otevřete rozložený výpis, nyní uvidíte, co se v ovladači skutečně děje. Zobrazit -> Disassembler. A ne YYAAAA!!! Assembler!!! HROZNÝ!!! ALE MUSÍTE. Abyste později, až se něco pokazí, nezblbli v kódu a nekladli na fórech hloupé otázky, ale okamžitě se pustili do drob a podívali se, kde máte zástrčku. Není tam nic hrozného.

Nejprve budou topy ze série:

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 0x00000034 Jump +00000006: 940C0034 JMP 0x00000034 Jump +00000008: 940C0034 JMP 0x00000034 Jump +0000000A: 940C0034 JMP 0x00000034 Jump +0000000C: 940C0034 JMP 0x00000034 Jump + 0000000E: 940C0034 JMP 0x00000034 Jump +00000010: 940C0034 JMP 0x00000034 Jump +00000012: 940C0034 JMP 0x00000034 Jump +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 0x00000034 Jump +00000024: 940C0034 JMP 0x00000034 Jump +00000026: 940C0034 JMP 0x00000034 Jump +00000028: 940C0034 JMP 0x00000034 Jump

00000000: 940C002A JMP 0x0000002A Jump +00000002: 940C0034 JMP 0x00000034 Jump +00000004: 940C0034 JMP 0x00000034 Jump +00000006: 940C0034 JMP 0x00000034 Jump +00000008: 940C0034 JMP 0x00000034 Jump +0000000A: 940C0034 JMP 0x00000034 Jump +0000000C: 940C0034 JMP 0x00000034 Jump +0000000E : 940C0034 JMP 0x00000034 Jump +00000010: 940C0034 JMP 0x00000034 Jump +00000012: 940C0034 JMP 0x00000034 Jump +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 0x00000034 Jump +00000024: 940C0034 JMP 0x00000034 Jump +00000026: 940C0034 JMP 0x00000034 Jump +00000028: 940C0034 JMP 0x00000034 Jump

Toto je tabulka vektorů přerušení. Vrátíme se k tomu později, zatím, jen se podívejte a zapamatujte si, že tam je. První sloupec je adresa flash buňky, ve které se příkaz nachází, druhý je kód příkazu, třetí mnemotechnická pomůcka příkazu, stejná instrukce assembleru, třetí operandy příkazu. Jo a automatický komentář.
Takže, když se podíváte, pak tam jsou nepřetržité přechody. A příkazový kód JMP je čtyřbajtový, obsahuje adresu skoku zapsanou pozpátku - dolní bajt na nízké adrese a kód příkazu skoku 940C

0000002B: BE1F OUT 0x3F,R1 Out to I/O umístění

Zapište tuto nulu na adresu 0x3F. Pokud se podíváte do sloupce zobrazení I/O, uvidíte, že adresa 0x3F je adresa registru SREG - příznakového registru řadiče. Tito. resetujeme SREG, aby se program spustil při nulových podmínkách.

1 2 3 4 +0000002C: E5CF LDI R28,0x5F Okamžité načtení +0000002D: E0D4 LDI R29,0x04 Okamžité načtení +0000002E: BFDE OUT 0x3E,R29 Out to I/O umístění +0000002F: BFCD IROUT/O0x umístění Out33 IROUT/00x

0000002C: E5CF LDI R28,0x5F Okamžité načtení +0000002D: E0D4 LDI R29,0x04 Okamžité načtení +0000002E: BFDE OUT 0x3E,R29 Out to I/O umístění +0000002F: BFCD OUT8/O0x umístění BFCD IR29,0x04

Tím se načítá ukazatel zásobníku. Registry nelze načíst přímo do I/O, pouze prostřednictvím přechodného registru. Proto nejprve LDI na střední a poté OUT na I/O. Také vám řeknu více o zásobníku. Mezitím vězte, že je to taková dynamická paměťová oblast, která visí na konci RAM a ukládá do sebe adresy a meziproměnné. Nyní jsme uvedli, odkud bude zásobník začínat.

00000032: 940C0041 JMP 0x00000041 Skok

Skok na saaaaamy konec programu a tam máme přerušení deaktivovaná a pevně smyčkovaná:

1 2 +00000041: 94F8 CLI Global Interrupt Disable +00000042: CFFF RJMP PC-0x0000 Relativní skok

00000041: 94F8 CLI Global Interrupt Disable +00000042: CFFF RJMP PC-0x0000 Relativní skok

To v případě nepředvídaných okolností, jako je opuštění hlavní funkce. Regulátor lze z takové smyčky vyvést buď hardwarovým resetem, nebo pravděpodobněji resetem z hlídacího psa. No, nebo, jak jsem řekl výše, opravit tato místa v hex editoru a jezdit, kam chceme. Všimněte si také, že existují dva typy skoků JMP a RJMP, první je přímý skok na adresu. Zabírá čtyři bajty a umí přímý skok přes celou oblast paměti. Druhý typ přechodu - RJMP - je relativní. Jeho příkaz zabere dva bajty, ale z aktuální pozice (adresy) skočí o 1024 kroků dopředu nebo dozadu. A jeho parametry udávají posun od aktuálního bodu. Používá se častěji, tk. zabírá polovinu místa v blesku a dlouhé přechody jsou potřeba jen zřídka.

1 +00000034: 940C0000 JMP 0x00000000 Skok

00000034: 940C0000 JMP 0x00000000 Skok

A to je skok na úplný začátek kódu. Nějaký restart. Zde můžete zkontrolovat, zda všechny vektory přeskakují. Z tohoto závěru - pokud nyní povolíte přerušení (ve výchozím nastavení jsou zakázána) a máte přerušení, ale není tam žádný handler, pak dojde k softwarovému resetu - program se vrhne na úplný začátek.

hlavní funkce. Všechno je stejné, nedá se to ani popsat. Podívejte se jen do registrů, je zadáno již vypočítané číslo. Preprocesor kompilátoru skály!!! Takže žádná „magická“ čísla!

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

00000036: E383 LDI R24,0x33 Okamžité načtení +00000037: B989 OUT 0x09,R24 Out to I/O umístění 15: UBRRH = HI(bauddivider); +00000038: BC10 OUT 0x20,R1 Out to I/O umístění 16: UCSRA = 0; +00000039: B81B OUT 0x0B,R1 Výstup do I/O umístění 17: UCSRB = 1<

A tady je zásek:

1 2 3 +0000003E: E080 LDI R24,0x00 Okamžité načtení +0000003F: E090 LDI R25,0x00 Okamžité načtení +00000040: 9508 Návrat podprogramu RET

0000003E: E080 LDI R24,0x00 Okamžité načtení +0000003F: E090 LDI R25,0x00 Okamžité načtení +00000040: 9508 Návrat podprogramu RET

Otázkou je, proč kompilátor přidává takové vrcholy? A to není nic jiného než Return 0, pak jsme definovali funkci jako int main (void), takže jsme posrali další čtyři bajty, nechápu co :) A když uděláš void main (void), tak zůstane jen RET, ale objeví se varování, že prý naše hlavní funkce nic nevrací. Obecně si dělej, co chceš :)

Složitý? Zdá se, že ne. Klikněte na spouštění krok za krokem v režimu disassembleru a podívejte se, jak procesor provádí jednotlivé instrukce, což se děje s registry. Jak probíhá pohyb po příkazech a závěrečná smyčka.

Pokračování za pár dní...

Mimo:
Alexej78 Vytvořil jsem plugin pro firefox, který usnadňuje navigaci na mém webu a fóru.
Diskuse a stahování,

Pro mikrokontroléry AVR existují různé programovací jazyky, ale assembler a C jsou možná nejvhodnější, protože tyto jazyky poskytují nejlepší implementaci všech nezbytných schopností pro ovládání hardwaru mikrokontroléru.

Assembler je nízkoúrovňový programovací jazyk, který využívá přímou instrukční sadu mikrokontroléru. Vytvoření programu v tomto jazyce vyžaduje dobrou znalost příkazového systému programovatelného čipu a dostatek času na vývoj programu. Assembler ztrácí na C, pokud jde o rychlost a pohodlí vývoje programu, ale má znatelné výhody ve velikosti konečného spustitelného kódu, a tedy v rychlosti jeho provádění.

C vám umožňuje vytvářet programy s mnohem větším pohodlím a poskytuje vývojářům všechny výhody jazyka na vysoké úrovni.
Ještě jednou je třeba poznamenat, že architektura a příkazový systém AVR byla vytvořena za přímé účasti vývojářů kompilátoru C a zohledňuje vlastnosti tohoto jazyka. Kompilace zdrojového kódu napsaného v C je rychlá a vytváří kompaktní a efektivní kód.

Hlavní výhody C oproti assembleru jsou: vysoká rychlost vývoje programu; všestrannost, která nevyžaduje důkladné studium architektury mikrokontroléru; lepší dokumentovatelnost a čitelnost algoritmu; dostupnost knihoven funkcí; podpora výpočtů s pohyblivou řádovou čárkou.

Jazyk C harmonicky kombinuje možnosti nízkoúrovňového programování s funkcemi vysokoúrovňového jazyka. Schopnost nízkoúrovňového programování usnadňuje ovládání přímo na hardwaru a vlastnosti vysokoúrovňového jazyka umožňují vytvářet snadno čitelný a upravitelný programový kód. Kromě toho mají téměř všechny kompilátory jazyka C schopnost používat vložky assembleru k zápisu kritických částí programu z hlediska doby provádění a zdrojů.

Jedním slovem, C je nejvhodnější jazyk pro začátečníky, aby se seznámili s mikrokontroléry AVR, i seriózní vývojáře.

Kompilátory se používají k převodu zdrojového kódu programu do souboru firmwaru mikrokontroléru.

Atmel poskytuje výkonný kompilátor assembleru, který je součástí vývojového prostředí Atmel Studio pro Windows. Spolu s kompilátorem obsahuje vývojové prostředí debugger a emulátor.
Atmel Studio je zcela zdarma a dostupné na webových stránkách Atmel.

V současné době existuje poměrně málo kompilátorů C pro AVR. Nejvýkonnějším z nich je překladač IAR Systems ze Stockholmu. Právě její zaměstnanci se v polovině 90. let podíleli na vývoji velitelského systému AVR. IAR C Compiler má rozsáhlé možnosti optimalizace kódu a přichází jako součást integrovaného vývojového prostředí IAR Embedded Workbench (EWB), které také zahrnuje kompilátor assembleru, linker, správce projektů a knihoven a debugger. Cena plné verze balíčku je 2820 EUR. Na webu společnosti si můžete zdarma stáhnout zkušební verzi na 30 dní nebo neomezenou verzi s limitem velikosti kódu 4 KB.

Americká společnost Image Craft z Palo Alto v Kalifornii vyrábí překladač pro jazyk C, který si získal poměrně širokou oblibu. JumpStart C pro AVR má přijatelnou optimalizaci kódu a není příliš drahý (od 50 do 499 USD v závislosti na verzi). Demoverze JumpStart C pro AVR je plně funkční po dobu 45 dnů.

Neméně oblibu si získal rumunský Code Vision AVR C Compiler, cena plné verze tohoto kompilátoru je poměrně nízká a činí 150 EUR. Kompilátor je dodáván s integrovaným vývojovým prostředím, které kromě standardních funkcí obsahuje poměrně zajímavou funkci - CodeWizardAVR Automatic Program Generator. Přítomnost sériového terminálu ve vývojovém prostředí umožňuje ladění programů pomocí sériového portu mikrokontroléru. Vývojáři si mohou zdarma stáhnout zkušební verzi s limitem velikosti kódu 4 KB a zakázaným ukládáním vygenerovaného zdrojového kódu C.

MikroElektronika, sídlící v srbském městě Bělehrad, vyrábí celou rodinu kompilátorů pro mikrokontroléry AVR. Kompilátor C s názvem mikroC PRO pro AVR stojí 249 $. Existují také mikroBasic a mikroPascal za stejnou cenu. Na webu vývojáře jsou ukázky s limitem velikosti kódu 4096 bajtů. Výhodou této rodiny kompilátorů je jednotná platforma a jednotná ideologie, která může zajistit snadný přechod nejen mezi jazyky, ale i mezi mikrokontroléry (existují verze kompilátorů pro PIC, STM32, 8051 ...).

Integrované vývojové prostředí se stalo skutečně ikonickým. Obsahuje výkonné kompilátory jazyka C a assembler, programátor AVRDUDE, debugger, simulátor a mnoho dalších podpůrných programů a utilit. WinAVR se dokonale integruje s vývojovým prostředím Atmel AVR Studio. Assembler je ve vstupním kódu identický s assemblerem AVR Studio. Kompilátory C a assembleru mají schopnost vytvářet ladicí soubory ve formátu COFF, což umožňuje používat nejen vestavěné nástroje, ale také používat výkonný simulátor AVR Studio. Dalším důležitým plusem je, že WinAVR je distribuován zdarma bez omezení (výrobci podporují GNU General Public License).

Stručně řečeno, WinAVR je ideální volbou pro ty, kteří začínají ovládat mikrokontroléry AVR. Právě toto vývojové prostředí je v tomto kurzu považováno za hlavní.

Bitové operace jsou založeny na logických operacích, které jsme již probrali dříve. Hrají klíčovou roli při programování mikrokontrolérů AVR a dalších typů. Téměř žádný program se neobejde bez použití bitových operací. Dosud jsme se jim záměrně vyhýbali, abychom si usnadnili osvojení programování MK.

Ve všech předchozích článcích jsme pouze programovali I/O porty a nepoužívali jsme další vestavěné uzly, jako jsou časovače, analogově-digitální převodníky, přerušení a další interní zařízení, bez kterých MK ztrácí veškerou svou energii.

Než přejdete k ovládání vestavěných zařízení MK, musíte se naučit ovládat nebo kontrolovat jednotlivé bity registrů AVR MK. Dříve jsme prováděli kontrolu nebo nastavovali bity celého registru najednou. Podívejme se, jaký je rozdíl, a pak pokračujte dále.

Bitové operace

Nejčastěji jsme jej používali při programování mikrokontrolérů AVR, protože je přehlednější než začínající programátory MK a je dobře srozumitelný. Potřebujeme například nastavit pouze 3. bit portu D. K tomu, jak již víme, můžeme použít následující binární kód:

PORTD = 0b00001000;

Tímto příkazem však nastavíme 3. bit na jedničku a všechny ostatní (0, 1, 2, 4, 5, 6 a 7) vynulujeme. A nyní si představme situaci, že 6. a 7. číslice jsou použity jako vstupy ADC a v tuto chvíli přichází na odpovídající výstupy MK signál z nějakého zařízení a tyto signály resetujeme příkazem výše. V důsledku toho je mikrokontrolér nevidí a věří, že signály nepřišly. Místo takového příkazu bychom tedy měli použít jiný, který by nastavil pouze 3. bit na jedničku, přičemž zbytek bitů neovlivnil. K tomu se obvykle používá následující bitová operace:

PORT |= (1<<3);

Jeho syntaxi podrobně rozebereme níže. A teď další příklad. Řekněme, že potřebujeme zkontrolovat stav 3. bitu registru PIND, čímž zkontrolujeme stav tlačítka. Pokud je tento bit vynulován, pak víme, že je tlačítko stisknuto a následně je proveden příkazový kód, který odpovídá stavu stisknutého tlačítka. Dříve jsme používali následující zápis:

if (pind == 0b00000000)

(jakýkoli kód)

S jeho pomocí však nekontrolujeme ani jeden, - 3., ale všechny bity registru PIND najednou. Proto, i když je tlačítko stisknuto a požadovaný bit je resetován, ale v tu chvíli je přijat signál na jakémkoli jiném pinu portu D, odpovídající bit bude nastaven na jedničku a podmínka v závorkách bude nepravdivá. V důsledku toho se kód ve složených závorkách nespustí ani po stisknutí tlačítka. Pro kontrolu stavu jednotlivého 3. bitu registru PIND by se tedy měla použít bitová operace:

jestliže (~PIND & (1<<3))

(jakýkoli kód)

Pro práci s jednotlivými bity mikrokontroléru má ve svém arzenálu programovací jazyk C, pomocí kterého můžete měnit nebo kontrolovat stav jednoho nebo více jednotlivých bitů najednou.

Nastavení jednoho bitu

K nastavení jednoho bitu, jako je port D, se používá bitová operace OR. To jsme použili na začátku článku.

PORTD = 0b00011100; // počáteční hodnota

PORTD = PORTD | (jeden<<0); применяем побитовую ИЛИ

PORT |= (1<<0); // сокращенная форма записи

PORTD == 0b00011101; // výsledek

Tento příkaz nastaví bit na nulu a zbytek ponechá beze změny.

Nastavíme například 6. bit portu D.

PORTD = 0b00011100; // počáteční stav portu

PORT |= (1<<6); //

PORTD == 0b01011100; // výsledek

Chcete-li zapsat jeden až několik samostatných bitů najednou, například nula, šestý a sedmý port B platí následující označení.

PORTB = 0b00011100; // počáteční hodnota

PORTB |= (1<<0) | (1<<6) | (1<<7); //

PORTB == 0b1011101; // výsledek

Nulování (nulování) jednotlivých bitů

K resetování jednoho bitu se současně používají tři dříve popsané příkazy: .

Resetujme 3. bit registru PORTC a zbytek necháme beze změny.

PORTC = 0b00011100;

PORTC &= ~(1<<3);

PORTC == 0b00010100;

Proveďme podobné akce pro 2. a 4. číslici:

PORTC = 0b00111110;

PORTC &= ~((1<<2) | (1<<4));

PORTC == 0b00101010;

Přepínání rytmu

Kromě nastavení a nulování se používá i užitečný příkaz, který přepne jediný bit do opačného stavu: jednička na nulu a naopak. Tato logická operace je široce používána při stavbě různých světelných efektů, například jako novoroční girlanda. Vezměme si příklad PORTA

PORTA = 0b00011111;

PORTA ^= (1<<2);

PORTA == 0b00011011;

Změňte stav nulového, druhého a šestého bitu:

PORTA = 0b00011111;

PORTA ^= (1<<0) | (1<<2) | (1<<6);

PORTA == 0b01011010;

Kontrola stavu jednotlivého bitu. Připomínám, že kontrola (na rozdíl od zápisu) I/O portu se provádí čtením dat z registru PIN.

Nejběžnější test se provádí jedním ze dvou příkazů cyklu: if a while. Tyto operátory známe již dříve.

Kontrola výboje na přítomnost logické nuly (reset) s -li

if (0==(PIND & (1<<3)))

Pokud je vymazán třetí bit portu D, provede se Code1. Jinak se provede Code2.

Podobné akce se provádějí s a v této formě záznamu:

jestliže (~PIND & (1<<3))

Kontrola výboje na přítomnost logické jednotky (nastavení) s -li

if (0 != (PIND & (1<<3)))

pokud (PIND & (1<<3))

Výše uvedené dvě smyčky fungují podobně, ale vzhledem k flexibilitě programovacího jazyka C je lze zapsat odlišně. Operace != znamená nerovná se. Pokud je nastaven třetí bit I/O portu PD (jedna), provede se Code1, pokud ne, Code2.

Čeká se na trochu reset s zatímco

zatímco (PIND & (1<<5))

Kód1 se bude provádět tak dlouho, dokud je nastaven 5. bit registru PIND. Resetováním se spustí provádění Code2.

Čekání na nastavení bitu zatímco

Zde vám syntaxe jazyka C umožňuje psát kód dvěma nejběžnějšími způsoby. V praxi se používají oba typy záznamu.