Cuprins:

Tutorial AVR Assembler 1: 5 pași
Tutorial AVR Assembler 1: 5 pași

Video: Tutorial AVR Assembler 1: 5 pași

Video: Tutorial AVR Assembler 1: 5 pași
Video: AVR Ассемблер. Урок 1. Вводный. AVR Assembler. Lesson 1. Promo. 2024, Iulie
Anonim
Tutorial AVR Assembler 1
Tutorial AVR Assembler 1

Am decis să scriu o serie de tutoriale despre cum să scriu programe de limbaj de asamblare pentru Atmega328p, care este microcontrolerul utilizat în Arduino. Dacă oamenii rămân interesați, voi continua să renunț la unul pe săptămână sau cam așa până când termin timpul liber sau altfel oamenii nu vor mai citi.

Execut Arch linux și lucrez la un atmega328p-pu configurat pe o panou de testare. O poți face la fel ca mine sau poți pur și simplu să conectezi un arduino la computer și să lucrezi la microcontroler în acest fel.

Vom scrie programe pentru 328p, cum ar fi cel care este în majoritatea arduino, dar ar trebui să rețineți că aceleași programe și tehnici vor funcționa și pentru oricare dintre microcontrolerele Atmel și mai târziu (dacă există interes) vom lucra cu unele dintre și celelalte. Detaliile microcontrolerului pot fi găsite în fișele tehnice Atmel și în manualul de instrucțiuni. Îi atașez la acest instructabil.

Iată de ce veți avea nevoie:

1. O placă de măsurare

2. Un Arduino, sau doar microcontrolerul

3. Un computer care rulează Linux

4. Asamblorul avra folosind git: git clone https://github.com/Ro5bert/avra.git sau dacă utilizați ubuntu sau un sistem bazat pe debian, tastați „sudo apt install avra” și veți obține atât asamblorul avr și avrdude. Oricum, dacă obțineți cea mai recentă versiune folosind github, veți primi și toate fișierele de includere necesare, cu alte cuvinte, acesta are deja fișierele m328Pdef.inc și tn85def.inc.

5. avrdude

Setul complet de tutoriale ale ansamblorului meu AVR poate fi găsit aici:

Pasul 1: Construiți o placă de testare

Construiți o placă de testare
Construiți o placă de testare

Puteți pur și simplu să utilizați arduino și să faceți totul în aceste tutoriale, dacă doriți. Cu toate acestea, din moment ce vorbim despre codificare în limbaj de asamblare, filozofia noastră este inerent de a elimina toate perifericele și de a interacționa direct cu microcontrolerul în sine. Deci nu crezi că ar fi mai distractiv să o faci așa?

Pentru aceia dintre voi care sunt de acord, puteți scoate microcontrolerul din arduino și apoi începeți prin construirea unui "Breadboard Arduino" urmând instrucțiunile de aici:

În imagine vă prezint setul care constă din două Atmega328p independente pe o placă mare (vreau să pot păstra tutorialul anterior cablat și încărcat pe un microcontroler în timp ce lucrez la următorul). Am configurat sursa de alimentare astfel încât șina de sus să fie de 9V și toate celelalte să fie la 5V de la regulatorul de tensiune. De asemenea, folosesc o placă FT232R breakout pentru a programa cipurile. Le-am cumpărat și le-am pus încărcătoare de încărcare pe ele însele, dar dacă ai scos unul dintr-un Arduino, atunci este deja bine.

Rețineți că, dacă încercați acest lucru cu un ATtiny85, puteți obține programatorul Sparkfun Tiny aici: https://www.sparkfun.com/products/11801# și apoi pur și simplu conectați-l la portul USB de pe computer. Va trebui mai întâi să instalați un bootloader pe Attiny85 și cel mai simplu mod este doar să utilizați Arduino IDE. Cu toate acestea, va trebui să faceți clic pe fișier și preferințe, apoi să adăugați această adresă URL a plăcilor noi: https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json care va vă permite să instalați bootloader-ul (dacă ATtiny85 nu a venit deja cu unul.)

Pasul 2: Instalați Assembler și Avrdude

Acum puteți descărca și instala asamblorul și avrdude din linkurile date în primul pas al acestui tutorial. Este probabil că, dacă ați lucrat deja cu Arduino, atunci aveți deja instalat avrdude.

După ce ați instalat avra, veți observa că există un subdirector care vine cu acesta numit „surse” și în interiorul acelui director sunt o grămadă de fișiere include. Acestea sunt toate microcontrolerele pe care le puteți programa cu avra. Veți observa imediat că nu există fișier pentru 328p pe care îl folosim aici. Am atașat unul. Fișierul ar trebui să se numească m328Pdef.inc și ar trebui să îl introduceți în directorul include sau în orice alt loc doriți. Îl vom include în programele noastre de limbaj de asamblare. Tot ce face este să ofere fiecăruia dintre registrele din numele microcontrolerelor din foaia de date, astfel încât să nu trebuiască să le folosim numele hexidecimale. Fișierul de mai sus conține „directive pragma”, deoarece a fost conceput pentru programarea C și C ++. Dacă te-ai săturat să vezi că asamblorul scuipă plângerile „ignorând directiva pragmei”, intră în fișier și șterge sau comentează toate liniile care încep cu #pragma

Bine, acum că aveți microcontrolerul pregătit, ansamblul dvs. și programatorul pregătit, putem scrie primul nostru program.

Notă: Dacă utilizați ATtiny85 în loc de ATmega328P, atunci aveți nevoie de un fișier de includere diferit numit tn85def.inc. Îl voi atașa, de asemenea (rețineți că a trebuit să-l numesc tn85def.inc.txt, astfel încât Instructables să-mi permită să-l încarc.) Oricum, dacă aveți asamblorul avra de la github, aveți deja ambele fișiere cu el. Așadar, vă recomand să îl obțineți și să îl compilați singur: git clone

Pasul 3: Hello World

Scopul acestui prim tutorial este de a construi primul program standard pe care îl scriem atunci când învățăm orice limbă nouă sau explorăm orice nouă platformă electronică. "Salut Lume!." În cazul nostru, dorim pur și simplu să scriem un program de limbaj de asamblare, să-l asamblăm și să-l încărcăm pe microcontrolerul nostru. Programul va face să se aprindă un LED. A face ca un LED să „clipească” așa cum se întâmplă pentru programul normal Arduino hello world este de fapt un program mult mai complicat în limbajul de asamblare și așa că nu vom face asta încă. Vom scrie cel mai simplu cod „oase goale” cu puf minim inutil.

Conectați mai întâi un LED de la PB5 (a se vedea diagrama pinout), care se mai numește Digital Out 13 pe un arduino, la un rezistor de 220 ohmi, apoi la GND. Adică

PB5 - LED - R (220 ohm) - GND

Acum, pentru a scrie programul. Deschideți editorul de text preferat și creați un fișier numit „hello.asm”

; salut.asm

; pornește un LED care este conectat la PB5 (ieșire digitală 13). include "./m328Pdef.inc" ldi r16, 0b00100000 ieșire DDRB, ieșire r16 PortB, r16 Start: rjmp Start

Cel de mai sus este codul. O vom parcurge linia cu linia într-un minut, dar mai întâi să ne asigurăm că o putem face să funcționeze pe dispozitivul dvs.

După ce ați creat fișierul, atunci într-un terminal îl asamblați după cum urmează:

avra salut.asm

aceasta vă va asambla codul și va crea un fișier numit hello.hex pe care îl putem încărca după cum urmează:

avrdude -p m328p -c stk500v1 -b 57600 -P / dev / ttyUSB0 -U bliț: w: hello.hex

dacă utilizați un arduino pentru panou de calcul, va trebui să apăsați butonul de resetare pe arduino pentru panoul de calcul, chiar înainte de a executa comanda de mai sus. Rețineți că poate fi necesar să adăugați un sudo în față sau să îl executați ca root. De asemenea, rețineți că pe unele arduino (cum ar fi Arduino UNO) va trebui probabil să schimbați rata de biți la -b 115200 și portul -P / dev / ttyACM0 (dacă primiți o eroare de la avrdude despre o semnătură invalidă a dispozitivului, adăugați doar un - F la comandă)

Dacă totul a funcționat așa cum ar trebui, veți avea acum un LED aprins … "Hello World!"

Dacă utilizați ATtiny85, atunci comanda avrdude va fi:

avrdude -p attiny85 -c usbtiny -U flash: w: hello.hex

Pasul 4: Hello.asm Linie cu linie

Pentru a finaliza acest tutorial introductiv, vom parcurge programul hello.asm rând cu rând pentru a vedea cum funcționează.

; salut.asm

; pornește un LED care este conectat la PB5 (ieșire digitală 13)

Totul după un punct și virgulă este ignorat de asamblare și, prin urmare, aceste două linii sunt pur și simplu „comentarii” care explică ce face programul.

.includeți „./m328Pdef.inc”

Această linie spune ansamblorului să includă fișierul m328Pdef.inc pe care l-ați descărcat. Poate doriți să puneți acest lucru într-un director cu fișiere de includere similare și apoi să schimbați linia de mai sus pentru a indica acolo.

ldi r16, 0b00100000

ldi înseamnă „încărcare imediată” și îi spune asamblorului să ia un registru de lucru, r16 în acest caz și să încarce un număr binar în el, 0b00100000 în acest caz. 0b din față spune că numărul nostru este în binar. Dacă am vrea, am fi putut alege o altă bază, cum ar fi hexidecimală. În acest caz, numărul nostru ar fi fost 0x20, care este hexidecimal pentru 0b00100000. Sau am fi putut folosi 32, care este baza 10 zecimale pentru același număr.

Exercițiul 1: Încercați să schimbați numărul din linia de mai sus în hexidecimal și apoi în zecimal în codul dvs. și verificați dacă acesta funcționează în continuare în fiecare caz.

Utilizarea binară este cea mai simplă, totuși, din cauza modului în care funcționează porturile și registrele. Vom discuta mai detaliat despre porturile și registrele atmega328p în viitoarele tutoriale, dar deocamdată voi spune că folosim r16 ca „registru de lucru”, ceea ce înseamnă că o vom folosi doar ca o variabilă pe care o stocăm numere din. Un „registru” este un set de 8 biți. Adică 8 puncte care pot fi 0 sau 1 („off” sau „on”). Când încărcăm numărul binar 0b00100000 în registru folosind linia de mai sus, am stocat pur și simplu acel număr în registrul r16.

afară DDRB, r16

Această linie spune compilatorului să copieze conținutul registrului r16 în registrul DDRB. DDRB înseamnă „Data Direction Register B” și setează „pinii” pe PortB. Pe harta de afișare pentru 328p puteți vedea că există 8 pini etichetați PB0, PB1,…, PB7. Acești pini reprezintă „biții” „PortB” și atunci când încărcăm numărul binar 00100000 în registrul DDRB spunem că dorim ca PB0, PB1, PB2, PB3, PB4, PB6 și PB7 să fie setate ca pini INPUT, deoarece au 0 este în ele, iar PB5 este setat ca un pin OUTPUT, deoarece am pus un 1 în acel loc.

afară PortB, r16

Acum, că am fixat direcțiile pinilor, putem seta acum tensiunile pe ele. Linia de mai sus copiază același număr binar din registrul nostru de stocare r16 în PortB. Aceasta setează toți pinii la 0 volți, cu excepția pinului PB5 la HIGH, care este de 5 volți.

Exercițiul 2: Luați un multimetru digital, conectați cablul negru la sol (GND) și apoi testați fiecare dintre pinii PB0 prin PB7 cu cablul roșu. Tensiunile de pe fiecare dintre ace sunt exact acelea care corespund punerii 0b00100000 în PortB? Dacă există unele care nu sunt, de ce crezi că este? (vezi harta pin)

Start:

rjmp Start

În cele din urmă, prima linie de mai sus este o „etichetă” care etichetează un punct din cod. În acest caz, etichetați acel loc ca „Start”. A doua linie spune „salt relativ la eticheta Start”. Rezultatul net este că computerul este plasat într-o buclă infinită care continuă să revină la pornire. Avem nevoie de acest lucru pentru că nu putem termina programul sau cădea de pe o stâncă, programul trebuie să continue să ruleze pentru ca lumina să rămână aprinsă.

Exercițiul 3: Eliminați cele două linii de mai sus din cod, astfel încât programul să cadă de pe o stâncă. Ce se întâmplă? Ar trebui să vedeți ceva care seamănă cu programul tradițional „clipire” folosit de Arduino drept „buna lume!”. De ce crezi că acționează astfel? (Gândiți-vă la ce trebuie să se întâmple când programul cade de pe o stâncă …)

Pasul 5: Concluzie

Dacă ați ajuns până aici, felicitări! Acum puteți scrie codul de asamblare, asamblați-l și încărcați-l pe microcontroler.

În acest tutorial ați învățat cum să utilizați următoarele comenzi:

ldi hregister, numărul încarcă un număr (0-255) într-un registru jumătate superior (16-31)

out ioregister, register copiază un număr dintr-un registru de lucru într-un registru I / O

eticheta rjmp sare la linia programului etichetat prin „etichetă” (care nu poate fi mai departe de 204 instrucțiuni distanță - adică salt relativ)

Acum că aceste elemente de bază sunt în afara drumului, putem continua să scriem coduri mai interesante și circuite și dispozitive mai interesante, fără a fi nevoie să discutăm despre mecanica compilării și încărcării.

Sper că v-a plăcut acest tutorial introductiv. În următorul tutorial vom adăuga o altă componentă a circuitului (un buton) și ne vom extinde codul pentru a include porturile de intrare și deciziile.

Recomandat: