Obsah:

AVR Assembler Tutorial 2: 4 Steps
AVR Assembler Tutorial 2: 4 Steps

Video: AVR Assembler Tutorial 2: 4 Steps

Video: AVR Assembler Tutorial 2: 4 Steps
Video: AVR Assembly Tutorial: Part 1 (Basic Commands) 2024, Júl
Anonim
Výučba montéra AVR 2
Výučba montéra AVR 2

Tento tutoriál je pokračovaním „Výučby AVR Assembler 1“

Ak ste neprešli výukovým programom 1, mali by ste teraz prestať a urobiť ten.

V tomto tutoriáli budeme pokračovať v štúdiu programovania v jazyku montáže atmega328p používaného v Arduino.

Budete potrebovať:

  1. breadboard Arduino alebo len normálne Arduino ako v návode 1
  2. LED dióda
  3. odpor 220 ohmov
  4. tlačidlo
  5. prepojovacie vodiče na vytvorenie obvodu na vašej doske
  6. Manuál inštalačnej sady: www.atmel.com/images/atmel-0856-avr-instruction-s…
  7. Dátový list: www.atmel.com/images/Atmel-8271-8-bit-AVR-Microco…

Kompletnú zbierku mojich návodov nájdete tu:

Krok 1: Budovanie obvodu

Budovanie okruhu
Budovanie okruhu

Najprv musíte zostrojiť obvod, ktorý budeme v tomto návode študovať.

Tu je spôsob pripojenia:

PB0 (digitálny kolík 8) - LED - R (220 ohmov) - 5V

PD0 (digitálny kolík 0) - tlačidlo - GND

Správnu orientáciu LED diódy môžete skontrolovať pripojením k GND namiesto PB0. Ak sa nič nestane, otočte orientáciu a svetlo sa rozsvieti. Potom ho znova pripojte k PB0 a pokračujte. Obrázok ukazuje, ako je moje arduino na chlebovom plechu prepojené.

Krok 2: Spísanie kódexu zhromaždenia

Spísanie kódexu zhromaždenia
Spísanie kódexu zhromaždenia

Napíšte nasledujúci kód do textového súboru s názvom pushbutton.asm a skompilovajte ho s avra tak, ako ste to urobili v návode 1.

Všimnite si, že v tomto kóde máme veľa komentárov. Zakaždým, keď assembler uvidí bodkočiarku, preskočí zvyšok riadku a prejde na ďalší riadok. Je dobrou programátorskou praxou (obzvlášť v assembleri!), Aby ste silne komentovali svoj kód, aby ste sa v budúcnosti k nemu vrátili a vedeli, čo ste robili. V prvých tutoriáloch sa chystám veľa vecí komentovať, aby sme presne vedeli, čo sa deje a prečo. Neskôr, keď sa staneme o niečo lepšími v kódovaní zostavy, budem veci komentovať o niečo menej podrobne.

;************************************

; napísal: 1o_o7; dátum: 23. októbra 2014; **********************************

.nolist

.include "m328Pdef.inc".list.def temp = r16; určiť pracovný register r16 ako temp rjmp Init; vykonaný prvý riadok

Začiatok:

ser temp; nastavte všetky bity na teplotu 1 s. out DDRB, temp; nastavenie trochu ako 1 na I/O smeru dát; zaregistrujte sa pre PortB, čo je DDRB, to nastavuje; pin ako výstup, 0 by nastavilo tento pin ako vstup; takže tu sú všetky piny PortB výstupy (nastavené na 1) ldi temp, 0b11111110; načítajte „okamžité“číslo do dočasného registra; keby to bolo len ld, potom druhý argument; muselo by byť miesto v pamäti mimo DDRD, temp; mv temp na DDRD, výsledkom je, že je vstupný PD0; a ostatné sú výstupy clr temp; všetky bity v temp sú nastavené na 0 z PortB, temp; nastavte všetky bity (t.j. piny) v PortB na 0V ldi temp, 0b00000001; načítať okamžité číslo na vypnutie PortD, temp; presunúť teplotu do PortD. PD0 má pull up odpor; (t.j. nastavený na 5V), pretože má 1 v tomto bite; ostatné sú od 0 rokov 0V.

Hlavná:

pri teplote, PinD; PinD uchováva stav PortD, skopírujte ho do temp; ak je tlačidlo pripojené k PD0, bude to; 0 pri stlačení tlačidla, 1 inak od; PD0 má pull up odpor, je to normálne na 5V výstupe PortB, teplota; vyšle vyššie uvedené 0 a 1 na PortB; to znamená, že chceme, aby bola dióda LED pripojená k PB0; keď je PD0 LOW, nastaví PB0 na LOW a otočí sa; na LED (pretože druhá strana LED je; pripojené k 5V a tým sa nastaví PB0 na 0V tak; prúd bude prúdiť) rjmp Main; slučky späť na začiatok Main

Všimnite si, že tentoraz máme v kóde nielen veľa ďalších komentárov, ale máme aj sekciu hlavičky, ktorá poskytuje niekoľko informácií o tom, kto ho napísal a kedy bol napísaný. Zvyšok kódu je tiež rozdelený na sekcie.

Potom, čo ste skompilovali vyššie uvedený kód, mali by ste ho načítať do mikrokontroléra a zistiť, že funguje. LED dióda by sa mala rozsvietiť počas stlačenia tlačidla a potom sa znova vypnúť, keď ju pustíte. Na obrázku som ukázal, ako to vyzerá.

Krok 3: Analýza kódu po riadkoch

Preskočím riadky, ktoré sú iba komentármi, pretože ich účel je evidentný.

.nolist

.include "m328Pdef.inc".list

Tieto tri riadky obsahujú súbor obsahujúci definície Register a Bit pre ATmega328P, ktoré programujeme. Príkaz.nolist hovorí assembleru, aby tento súbor nezahrnoval do súboru pushbutton.lst, ktorý vytvorí, keď ho zostavíte. Vypne možnosť záznamu. Po zahrnutí súboru znova zapneme možnosť výpisu pomocou príkazu.list. Dôvod, prečo to robíme, je ten, že súbor m328Pdef.inc je dosť dlhý a skutočne ho nepotrebujeme vidieť v súbore zoznamu. Náš assembler, avra, automaticky nevygeneruje súbor so zoznamom a ak by sme ho chceli, zostavili by sme ho pomocou nasledujúceho príkazu:

avra -l tlačidlo.lst tlačidlo.asm

Ak to urobíte, vygeneruje sa súbor s názvom pushbutton.lst a ak ho preskúmate, zistíte, že ukazuje kód programu spolu s ďalšími informáciami. Ak sa pozriete na ďalšie informácie, uvidíte, že riadky začínajú znakom C: za ktorým nasleduje relatívna adresa v hexadecimálnom formáte, kde je kód umiestnený v pamäti. V zásade to začína o 000000 prvým príkazom a odtiaľ sa zvyšuje s každým ďalším príkazom. Druhý stĺpec za relatívnym miestom v pamäti je hexadecimálny kód príkazu, za ktorým nasleduje hexadecimálny kód argumentu príkazu. Súbory zoznamu budeme ďalej diskutovať v budúcich návodoch.

.def temp = r16; určiť pracovný register r16 ako tepl

V tomto riadku používame smernicu assembleru „.def“na definovanie premennej „temp“rovnajúcej sa „pracovnému registru“r16. Register r16 použijeme ako ten, ktorý ukladá čísla, ktoré chceme kopírovať, do rôznych portov a registrov (do ktorých sa nedá priamo zapisovať).

Cvičenie 1: Skúste skopírovať binárne číslo priamo do portu alebo špeciálneho registra, ako je DDRB, a zistite, čo sa stane, keď sa pokúsite zostaviť kód.

Register obsahuje bajt (8 bitov) informácií. V zásade ide spravidla o zbierku západiek SR, z ktorých každá je „kúsok“a obsahuje 1 alebo 0. O tomto (a dokonca ho vytvoríme!) Môžeme diskutovať neskôr v tejto sérii. Možno sa pýtate, čo je to „pracovný register“a prečo sme vybrali r16. O tom budeme diskutovať v budúcom návode, keď sa ponoríme do bahna vnútorných prvkov čipu. Teraz chcem, aby ste rozumeli tomu, ako je písať kód a programovať fyzický hardvér. Potom budete mať z tejto skúsenosti referenčný rámec, ktorý uľahčí pochopenie vlastností pamäte a registra mikrokontroléra. Uvedomujem si, že väčšina úvodných učebníc a diskusií to robí naopak, ale zistil som, že chvíľu si najskôr zahrať videohru, aby ste získali globálny pohľad, než si prečítate návod na použitie, je oveľa jednoduchšie, ako si najskôr prečítať manuál.

rjmp Init; vykonaný prvý riadok

Tento riadok je „relatívnym skokom“k označeniu „Init“a nie je tu skutočne potrebný, pretože nasledujúci príkaz je už v programe Init, ale zahrňujeme ho pre budúce použitie.

Začiatok:

ser temp; nastavte všetky bity na teplotu 1 s.

Za štítkom Init vykonáme príkaz „set register“. Tým sa nastaví všetkých 8 bitov v registri „temp“(ktorý si pamätáte je r16) na 1. Teplota teda teraz obsahuje 0b11111111.

out DDRB, temp; nastavenie trochu ako 1 na I/O registri Data Direction

; pre PortB, čo je DDRB, nastaví tento pin ako výstup; a 0 by nastavil tento pin ako vstup; takže tu sú všetky piny PortB výstupy (nastavené na 1)

Register DDRB (Data Direction Register for PortB) udáva, ktoré piny na PortB (t.j. PB0 až PB7) sú označené ako vstupné a ktoré sú určené ako výstupné. Pretože máme pin PB0 pripojený k našej LED a zvyšok nie je pripojený k ničomu, nastavíme všetky bity na 1, čo znamená, že sú to všetky výstupy.

ldi temp, 0b11111110; načítajte „okamžité“číslo do dočasného registra

; keby to bolo len ld, potom by druhý argument; musí to byť miesto v pamäti

Tento riadok načíta binárne číslo 0b11111110 do dočasného registra.

out DDRD, temp; mv temp na DDRD, výsledkom je, že PD0 je vstup a

; zvyšok sú výstupy

Teraz nastavíme register smeru údajov pre PortD z teploty, pretože teplota stále obsahuje 0b11111110, vidíme, že PD0 bude označený ako vstupný kolík (pretože na pravom mieste je 0) a ostatné sú označené ako výstupy, pretože existujú 1 na týchto miestach.

teplota clr; všetky bity pri teplote sú nastavené na 0

out PortB, temp; nastavte všetky bity (t.j. piny) v PortB na 0V

Najprv "vyčistíme" teplotu registra, čo znamená nastavenie všetkých bitov na nulu. Potom to skopírujeme do registra PortB, ktorý nastaví 0V na všetkých týchto kolíkoch. Nula na bite PortB znamená, že procesor bude udržiavať tento pin na 0V, jeden na bite spôsobí, že tento pin bude nastavený na 5V.

Cvičenie 2: Pomocou multimetra skontrolujte, či sú všetky piny na PortB skutočne nulové. Deje sa s PB1 niečo zvláštne? Máte predstavu, prečo by to mohlo byť? (Podobne ako cvičenie 4 nižšie a potom postupujte podľa kódu …) Cvičenie 3: Odstráňte z kódu dva vyššie uvedené riadky. Beží program stále správne? Prečo?

ldi teplota, 0b00000001; načítať okamžité číslo na teplotu

out PortD, temp; presunúť teplotu do PortD. PD0 je na 5V (má výsuvný odpor); pretože má 1 v tomto bite, ostatné sú 0V. Cvičenie 4: Odstráňte vyššie uvedené dva riadky z kódu. Beží program stále správne? Prečo? (To sa líši od cvičenia 3 vyššie. Pozrite si diagram zapojenia. Aké je predvolené nastavenie DDRD pre PD0? (Pozri stranu 90 technického listu)

Najprv „načítame okamžite“číslo 0b00000001 na teplotu. „Okamžitá“časť je tu, pretože načítavame priame číslo na teplotu, a nie ukazovateľ na miesto v pamäti, ktoré obsahuje číslo, ktoré sa má načítať. V takom prípade by sme jednoducho použili „ld“namiesto „ldi“. Potom pošleme toto číslo na PortD, ktorý nastaví PD0 na 5V a zvyšok na 0V.

Teraz sme nastavili piny ako vstup alebo výstup a nastavili sme ich počiatočné stavy buď na 0 V alebo 5 V (LOW alebo HIGH), a tak teraz vstupujeme do našej programovej „slučky“.

Hlavné: pri teplote, PinD; PinD uchováva stav PortD, skopírujte ho do temp

; ak je tlačidlo pripojené k PD0, potom to bude; a 0 pri stlačení tlačidla, 1 inak od; PD0 má vyťahovací odpor, obvykle je na 5V

Register PinD obsahuje aktuálny stav pinov PortD. Napríklad, ak ste k PD3 pripojili 5V vodič, potom v nasledujúcom taktovacím cykle (čo sa deje 16 miliónov krát za sekundu, pretože máme mikrokontrolér napojený na hodinový signál 16 MHz) bit PinD3 (zo súčasného stavu PD3) by sa stalo 1 namiesto 0. Takže v tomto riadku skopírujeme aktuálny stav pinov na temp.

out PortB, temp; vyšle vyššie uvedené 0 a 1 na PortB

; to znamená, že chceme, aby bola dióda LED pripojená k PB0, takže; keď je PD0 LOW, nastaví PB0 na LOW a otočí sa; na LED (druhá strana LED je pripojená; na 5V a tým sa nastaví PB0 na 0V, takže prúd prúdi)

Teraz pošleme stav pinov v PinD na výstup PortB. Účinne to znamená, že PD0 pošle 1 na PortD0, pokiaľ nestlačíte tlačidlo. V takom prípade, pretože tlačidlo je pripojené k zemi, bude tento pin na 0V a pošle 0 na PortB0. Teraz, keď sa pozriete na schému zapojenia, 0 V na PB0 znamená, že LED dióda bude svietiť, pretože jej druhá strana je na 5 V. Ak nestlačíme tlačidlo, takže 1 sa odošle do PB0, znamenalo by to, že máme 5 V na PB0 a tiež 5 V na druhej strane diódy LED, takže neexistuje žiadny potenciálny rozdiel a nebude prúdiť žiadny prúd, a tak LED dióda nebude svietiť (v tomto prípade ide o LED diódu, ktorá prúdi prúdom iba jedným smerom bez ohľadu na to, čokoľvek).

rjmp Main; sa vráti späť na Štart

Tento relatívny skok nás privádza späť k nášmu štítku Main: a znova skontrolujeme PinD a tak ďalej. Každých 16 miliónov sekúnd sa kontroluje, či je stlačené tlačidlo, a podľa toho nastavuje PB0.

Cvičenie 5: Upravte svoj kód tak, aby bola vaša LED dióda pripojená k PB3 namiesto PB0 a presvedčte sa, že funguje. Cvičenie 6: Pripojte svoju diódu LED k GND namiesto 5V a podľa toho upravte kód.

Krok 4: Záver

V tomto návode sme ďalej skúmali jazyk zostavy pre ATmega328p a naučili sme sa ovládať LED diódu pomocou tlačidla. Naučili sme sa najmä nasledujúce príkazy:

ser register nastaví všetky bity registra na 1

register clr nastaví všetky bity registra na 0

v registri i/o register skopíruje číslo z I/o registra do pracovného registra

V nasledujúcom návode sa budeme zaoberať štruktúrou ATmega328p a rôznymi registrami, operáciami a zdrojmi, ktoré sú v ňom obsiahnuté.

Než budem pokračovať v týchto tutoriáloch, počkám a zistím úroveň záujmu. Ak existuje niekoľko ľudí, ktorí sa skutočne učia kódovať programy pre tento mikroprocesor v jazyku zostavenia, budem pokračovať a zostrojiť komplikovanejšie obvody a používať robustnejší kód.

Odporúča: