Obsah:
Video: AVR Assembler Tutorial 2: 4 Steps
2024 Autor: John Day | [email protected]. Naposledy změněno: 2024-01-30 08:18
Tento tutoriál je pokračováním „AVR Assembler Tutorial 1“
Pokud jste neprošli výukovým programem 1, měli byste teď přestat a udělat to jako první.
V tomto tutoriálu budeme pokračovat ve studiu programovacího jazyka atmega328p používaného v Arduinu.
Budete potřebovat:
- prkénko Arduino nebo jen normální Arduino jako v Tutoriálu 1
- LED
- odpor 220 ohmů
- tlačítko
- propojovací vodiče pro vytvoření obvodu na vašem prkénku
- Manuál instalační sady: www.atmel.com/images/atmel-0856-avr-instruction-s…
- Datasheet: www.atmel.com/images/Atmel-8271-8-bit-AVR-Microco…
Kompletní sbírku mých návodů naleznete zde:
Krok 1: Budování obvodu
Nejprve musíte zkonstruovat obvod, který budeme v tomto tutoriálu studovat.
Zde je způsob připojení:
PB0 (digitální kolík 8) - LED - R (220 ohmů) - 5V
PD0 (digitální pin 0) - tlačítko - GND
Správnou orientaci LED můžete zkontrolovat připojením k GND místo PB0. Pokud se nic nestane, otočte orientaci a světlo by se mělo rozsvítit. Poté jej znovu připojte k PB0 a pokračujte. Obrázek ukazuje, jak je moje arduino na prkénku připojeno.
Krok 2: Napište kód sestavy
Následující kód napište do textového souboru s názvem pushbutton.asm a zkompilujte jej pomocí avra, jako jste to udělali v kurzu 1.
Všimněte si, že v tomto kódu máme spoustu komentářů. Pokaždé, když assembler uvidí středník, přeskočí zbytek řádku a přejde na další řádek. Je dobrou programovací praxí (zejména v jazyce Assembly!), Abyste svůj kód silně komentovali, takže až se k němu v budoucnu vrátíte, budete vědět, co děláte. V prvních několika tutoriálech budu hodně komentovat věci, abychom přesně věděli, co se děje a proč. Později, jakmile se staneme o něco lepšími v kódování sestavení, budu věci komentovat trochu méně podrobně.
;************************************
; napsal: 1o_o7; datum: 23. října 2014; **********************************
.nolist
.include "m328Pdef.inc".list.def temp = r16; určit pracovní registr r16 jako temp rjmp Init; první řádek spuštěn
Init:
ser temp; nastavit všechny bity v temp na 1 s. out DDRB, temp; nastavení bit jako 1 na I/O Data Direction; registr pro PortB, což je DDRB, to nastavuje; pin jako výstup, 0 by nastavilo tento pin jako vstup; takže zde jsou všechny piny PortB výstupy (nastavené na 1) ldi temp, 0b11111110; načíst `okamžité 'číslo do dočasného registru; kdyby to bylo jen ld, pak druhý argument; muselo by být místo v paměti místo DDRD, temp; mv temp na DDRD, výsledkem je vstup PD0; a zbytek jsou výstupy clr temp; všechny bity v temp jsou nastaveny na 0 out PortB, temp; nastavte všechny bity (tj. piny) v PortB na 0V ldi temp, 0b00000001; načíst okamžité číslo pro dočasný výpadek PortD, temp; přesunout teplotu na PortD. PD0 má pull up odpor; (tj. nastaveno na 5V), protože má 1 v tomto bitu; zbytek je 0V od 0.
Hlavní:
při teplotě, PinD; PinD uchovává stav PortD, zkopírujte jej do temp; pokud je tlačítko připojeno k PD0, bude to; 0 při stisknutí tlačítka, 1 jinak od; PD0 má pull up odpor, obvykle je to na 5V výstupu PortB, temp; posílá přečtené 0 a 1 na PortB; to znamená, že chceme, aby LED byla připojena k PB0; když je PD0 LOW, nastaví PB0 na LOW a otočí se; na LED (protože druhá strana LED je; připojeno k 5V a tím se nastaví PB0 na 0V tak; proud bude proudit) rjmp Main; smyčky zpět na začátek Main
Všimněte si, že tentokrát máme v našem kódu nejen mnohem více komentářů, ale máme také sekci záhlaví, která poskytuje nějaké informace o tom, kdo to napsal a kdy to bylo napsáno. Zbytek kódu je také rozdělen do sekcí.
Poté, co jste zkompilovali výše uvedený kód, měli byste jej načíst do mikrokontroléru a zjistit, že funguje. LED dioda by se měla rozsvítit, když mačkáte tlačítko, a poté znovu zhasnout, když ji pustíte. Jak to vypadá, jsem ukázal na obrázku.
Krok 3: Analýza kódu po řádcích
Přeskočím řádky, které jsou pouze komentáři, protože jejich účel je evidentní.
.nolist
.include "m328Pdef.inc".list
Tyto tři řádky obsahují soubor obsahující definice Register a Bit pro ATmega328P, které programujeme. Příkaz.nolist říká assembleru, aby tento soubor nezahrnoval do souboru pushbutton.lst, který vytvoří, když jej sestavíte. Vypne možnost výpisu. Po zahrnutí souboru znovu zapneme možnost výpisu pomocí příkazu.list. Důvod, proč to děláme, je ten, že soubor m328Pdef.inc je poměrně dlouhý a ve skutečnosti ho v souboru seznamu vidět nepotřebujeme. Náš assembler, avra, automaticky nevygeneruje soubor seznamu a pokud bychom ho chtěli, sestavili bychom jej pomocí následujícího příkazu:
avra -l tlačítko.lst tlačítko.asm
Pokud to uděláte, vygeneruje se soubor s názvem pushbutton.lst a pokud tento soubor prozkoumáte, zjistíte, že ukazuje kód vašeho programu spolu s dalšími informacemi. Pokud se podíváte na další informace, uvidíte, že řádky začínají C: následuje relativní adresa v hexadecimálním umístění místa, kde je kód umístěn v paměti. V zásadě začíná v 000000 prvním příkazem a odtud se zvyšuje s každým dalším příkazem. Druhý sloupec za relativním místem v paměti je hexadecimální kód příkazu následovaný hexadecimálním kódem argumentu příkazu. Soubory seznamu probereme dále v budoucích výukových programech.
.def temp = r16; určit pracovní registr r16 jako tepl
V tomto řádku používáme direktivu assembleru „.def“k definování proměnné „temp“jako rovné „pracovnímu registru“r16. Použijeme registr r16 jako ten, který ukládá čísla, která chceme zkopírovat do různých portů a registrů (do kterých nelze přímo zapisovat).
Cvičení 1: Zkuste zkopírovat binární číslo přímo do portu nebo speciálního registru, jako je DDRB, a uvidíte, co se stane, když se pokusíte sestavit kód.
Registr obsahuje bajt (8 bitů) informací. V zásadě se obvykle jedná o sbírku SR-západek, z nichž každá je „bit“a obsahuje 1 nebo 0. O tom (a dokonce i o vytvoření!) Můžeme diskutovat později v této sérii. Možná si říkáte, co je to „fungující registr“a proč jsme vybrali r16. Budeme o tom diskutovat v budoucím tutoriálu, když se ponoříme do bahna vnitřních částí čipu. Prozatím chci, abyste pochopili, jak dělat věci, jako je psaní kódu a programování fyzického hardwaru. Potom budete mít z této zkušenosti referenční rámec, který usnadní pochopení vlastností paměti a registru mikrokontroléru. Uvědomuji si, že většina úvodních učebnic a diskusí to dělá obráceně, ale zjistil jsem, že chvíli si nejprve zahrát videohru, abyste získali globální perspektivu, než si přečtete návod k použití, je mnohem snazší, než si nejprve přečíst manuál.
rjmp Init; první řádek spuštěn
Tento řádek je "relativním skokem" k označení "Init" a není zde opravdu nutný, protože další příkaz je již v Init, ale zahrneme jej pro budoucí použití.
Init:
ser temp; nastavit všechny bity v temp na 1 s.
Po označení Init spustíme příkaz „set register“. Tím se nastaví všech 8 bitů v registru „temp“(které si vybavíte r16) na 1. Teplota tedy nyní obsahuje 0b11111111.
out DDRB, temp; nastavení bit jako 1 na I/O registru Data Direction
; pro PortB, což je DDRB, nastaví tento pin jako výstup; a 0 by nastavilo tento pin jako vstup; takže zde jsou všechny piny PortB výstupy (nastaveny na 1)
Register DDRB (Data Direction Register for PortB) udává, které piny na PortB (tj. PB0 až PB7) jsou označeny jako vstupní a které jsou označeny jako výstupní. Protože máme pin PB0 připojený k naší LED a zbytek není připojen k ničemu, nastavíme všechny bity na 1, což znamená, že jsou to všechny výstupy.
ldi temp, 0b11111110; nahrajte `okamžité 'číslo do dočasného registru
; kdyby to bylo jen ld, pak by druhý argument; musí být paměťové místo
Tento řádek načte binární číslo 0b11111110 do dočasného registru.
out DDRD, temp; mv temp to DDRD, result is that PD0 is input and
; zbytek jsou výstupy
Nyní nastavíme Data Direction Register pro PortD z temp, protože temp stále obsahuje 0b11111110, vidíme, že PD0 bude označen jako vstupní pin (protože v pravém místě je 0) a zbytek jsou označeny jako výstupy, protože existují 1 je na těchto místech.
teplota clr; všechny bity v temp jsou nastaveny na 0
out PortB, temp; nastavte všechny bity (tj. piny) v PortB na 0V
Nejprve "vyčistíme" teplotu registru, což znamená nastavení všech bitů na nulu. Potom to zkopírujeme do registru PortB, který nastaví 0V na všech těchto pinech. Nula na bitu PortB znamená, že procesor bude udržovat tento pin na 0V, jeden na bitu způsobí, že bude tento pin nastaven na 5V.
Cvičení 2: Pomocí multimetru zkontrolujte, zda jsou všechny piny na PortB skutečně nulové. Děje se s PB1 něco divného? Máte představu, proč by to mohlo být? (podobně jako cvičení 4 níže, pak postupujte podle kódu …) Cvičení 3: Odstraňte z kódu výše uvedené dva řádky. Běží program stále správně? Proč?
ldi teplota, 0b00000001; načíst okamžité číslo na teplotu
out PortD, temp; přesunout teplotu na PortD. PD0 je na 5V (má stahovací odpor); protože má 1 v tomto bitu, zbytek je 0V. Cvičení 4: Odstraňte z kódu výše uvedené dva řádky. Běží program stále správně? Proč? (To se liší od cvičení 3 výše. Viz pin out diagram. Jaké je výchozí nastavení DDRD pro PD0? (Viz strana 90 datového listu
Nejprve „načteme okamžitě“číslo 0b00000001 na teplotu. „Okamžitá“část je tam, protože načítáme přímé číslo na teplotu, nikoli ukazatel na místo v paměti obsahující číslo, které se má načíst. V takovém případě bychom jednoduše použili „ld“místo „ldi“. Poté pošleme toto číslo na PortD, který nastaví PD0 na 5V a zbytek na 0V.
Nyní jsme nastavili piny jako vstup nebo výstup a nastavili jsme jejich počáteční stavy buď na 0V nebo 5V (LOW nebo HIGH), a tak nyní vstupujeme do naší programové „smyčky“.
Hlavní: v temp, PinD; PinD uchovává stav PortD, zkopírujte jej do temp
; pokud je tlačítko připojeno k PD0, pak to bude; a 0 při stisknutí tlačítka, 1 jinak od; PD0 má pull up odpor, obvykle je na 5V
Registr PinD obsahuje aktuální stav pinů PortD. Pokud jste například k PD3 připojili 5V vodič, pak v dalším cyklu hodin (což se děje 16 milionůkrát za sekundu, protože máme mikrokontrolér připojen k hodinovému signálu 16 MHz) bit PinD3 (ze současného stavu PD3) by se stalo 1 místo 0. Takže v tomto řádku zkopírujeme aktuální stav pinů na temp.
out PortB, temp; posílá přečtené 0 a 1 na PortB
; to znamená, že chceme, aby LED byla připojena k PB0, takže; když je PD0 LOW, nastaví PB0 na LOW a otočí se; na LED (druhá strana LED je připojena; na 5V a tím se nastaví PB0 na 0V, takže teče proud)
Nyní pošleme stav pinů v PinD na výstup PortB. Účinně to znamená, že PD0 pošle 1 na PortD0, pokud není stisknuto tlačítko. V takovém případě, protože tlačítko je připojeno k zemi, bude tento pin na 0V a pošle 0 na PortB0. Když se nyní podíváte na schéma zapojení, 0V na PB0 znamená, že LED bude svítit, protože jeho druhá strana je na 5V. Pokud nestiskneme tlačítko, takže 1 bude odesláno do PB0, znamenalo by to, že máme 5 V na PB0 a také 5 V na druhé straně LED, a tak neexistuje žádný potenciální rozdíl a nebude proudit žádný proud, takže LED nesvítí (v tomto případě se jedná o LED, která je diodou, takže proud teče pouze jedním směrem bez ohledu na to, cokoli).
rjmp Hlavní; smyčky zpět na Start
Tento relativní skok nás přivádí zpět na náš štítek Main: a znovu kontrolujeme PinD a tak dále. Každých 16 miliontin sekundy kontrolujeme, zda je stisknuto tlačítko, a podle toho nastavujeme PB0.
Cvičení 5: Upravte kód tak, aby byla vaše LED dioda připojena k PB3 místo PB0 a zjistěte, že funguje. Cvičení 6: Zapojte svou LED do GND místo 5V a upravte podle toho svůj kód.
Krok 4: Závěr
V tomto tutoriálu jsme dále zkoumali jazyk sestavení pro ATmega328p a naučili jsme se ovládat LED pomocí tlačítka. Naučili jsme se zejména následující příkazy:
ser register nastaví všechny bity registru na 1
clr registr nastaví všechny bity registru na 0
v registru i/o registr zkopíruje číslo z I/o registru do funkčního registru
V dalším kurzu prozkoumáme strukturu ATmega328p a různé registry, operace a prostředky v ní obsažené.
Než budu pokračovat v těchto výukových programech, počkám a uvidím úroveň zájmu. Pokud existuje řada lidí, kteří se skutečně baví učit se kódovat programy pro tento mikroprocesor v jazyce sestavení, budu pokračovat a budovat složitější obvody a používat robustnější kód.
Doporučuje:
AVR Assembler Tutorial 1: 5 Steps
AVR Assembler Tutorial 1: Rozhodl jsem se napsat sérii návodů, jak psát programy v assembleru pro Atmega328p, což je mikrokontrolér používaný v Arduinu. Pokud lidé zůstanou zájem, budu i nadále vydávat jeden týdně, dokud mi nedojde
AVR Assembler Tutorial 6: 3 Steps
AVR Assembler Tutorial 6: Welcome to Tutorial 6! Dnešní tutoriál bude krátký, kde vyvineme jednoduchou metodu pro komunikaci dat mezi jedním atmega328p a druhým pomocí dvou portů, které je spojují. Poté vezmeme hrací kostku z Tutoriálu 4 a Registrovat
AVR Assembler Tutorial 8: 4 Steps
AVR Assembler Tutorial 8: Welcome to Tutorial 8! V tomto krátkém tutoriálu se trochu odvrátíme od zavádění nových aspektů programování v jazyce assembleru, abychom ukázali, jak přesunout naše prototypovací komponenty do samostatného " tištěného " obvodová deska
AVR Assembler Tutorial 9: 7 Steps
AVR Assembler Tutorial 9: Welcome to Tutorial 9. Dnes si ukážeme, jak ovládat jak 7segmentový displej, tak 4místný displej pomocí našeho kódu montážního jazyka ATmega328P a AVR. V průběhu toho budeme muset udělat odbočku v tom, jak používat zásobník
AVR Assembler Tutorial 11: 5 Steps
AVR Assembler Tutorial 11: Welcome to Tutorial 11! V tomto krátkém tutoriálu konečně postavíme první část našeho finálního projektu. První věc, kterou byste měli udělat, je přejít na úplně poslední krok tohoto tutoriálu a podívat se na video. Pak se vrať sem. [pozastavení, zatímco vy