Cuprins:

Tutorial AVR Assembler 6: 3 pași
Tutorial AVR Assembler 6: 3 pași

Video: Tutorial AVR Assembler 6: 3 pași

Video: Tutorial AVR Assembler 6: 3 pași
Video: Видеокурс по AVR микроконтроллерам - Урок 3 2024, Iulie
Anonim
Tutorial AVR Assembler 6
Tutorial AVR Assembler 6

Bine ați venit la Tutorialul 6!

Tutorialul de astăzi va fi unul scurt, în care vom dezvolta o metodă simplă de comunicare a datelor între un atmega328p și altul folosind două porturi care le conectează. Vom lua apoi rolele de zaruri din Tutorialul 4 și Registrul Analizor din Tutorialul 5, le vom conecta împreună și vom folosi metoda noastră pentru a comunica rezultatul aruncării zarurilor de la rolă la analizor. Vom imprima apoi rularea în binar folosind LED-urile pe care le-am construit pentru analizor în Tutorial 5. Odată ce vom lucra, vom putea construi următoarea piesă a proiectului nostru general în următorul tutorial.

În acest tutorial veți avea nevoie de:

  1. Placa dvs. de prototipare
  2. Rola ta de zaruri din Tutorialul 4
  3. Analizatorul dvs. de înregistrare din Tutorialul 5
  4. Două fire de conectare
  5. O copie a fișei de date complete (revizuirea 2014):

    www.atmel.com/images/Atmel-8271-8-bit-AVR-M…

  6. O copie a manualului de instrucțiuni (revizuirea 2014):

    www.atmel.com/images/atmel-0856-avr-instruc…

Iată un link către colecția completă a tutorialelor mele de asamblare AVR:

Pasul 1: Cum putem obține două microcontrolere pentru a vorbi între ele?

Cum putem obține două microcontrolere pentru a vorbi între ele?
Cum putem obține două microcontrolere pentru a vorbi între ele?

Deoarece începem să ne extindem proiectul, astfel încât produsul nostru final unic să fie format dintr-o colecție de piese mai mici, vom avea nevoie de mai mulți pini decât poate oferi un singur Atmega328P. Prin urmare, vom face fiecare parte a proiectului general pe un microcontroler separat și apoi îi vom împărtăși datele între ei. Deci, problema pe care trebuie să o rezolvăm este cum putem veni cu o metodă simplă pentru ca controlorii să vorbească între ei și să transfere date între ei? Ei bine, un lucru despre aceste controlere este că fiecare execută 16 milioane de instrucțiuni pe secundă. Acest lucru este temporizat foarte precis și astfel putem folosi acest timp pentru a transfera date. Dacă folosim întârzieri de milisecunde pentru a constitui datele, atunci nu trebuie să fim cu adevărat atât de precise, deoarece CPU execută 16 000 de instrucțiuni într-o singură milisecundă. Cu alte cuvinte, o milisecundă este o eternitate pentru CPU. Deci, să încercăm cu aruncarea zarurilor. Vreau să transmit rezultatul unei aruncări de zaruri de la cipul cu role de zaruri la cipul de analizor. Să presupunem că stai de-a lungul străzii și am vrut să-ți semnalez rezultatul aruncării mele de o pereche de zaruri. Un lucru pe care aș putea să-l fac, dacă am avea amândoi un ceas, este să pot aprinde o lanternă, atunci când sunteți gata să primiți datele, porniți lanterna și amândoi ne pornim ceasurile. Apoi îmi păstrez lanterna aprinsă pentru numărul exact de milisecunde pe măsură ce zarurile se rostogolesc și apoi o opresc. Așadar, dacă aș roti un 12, mi-aș păstra lumina aprinsă timp de 12 milisecunde. Acum problema cu cele de mai sus este că, pentru dvs. și pentru mine, nu există nicio modalitate în care am fi capabili să cronometrăm lucrurile suficient de precis pentru a distinge între 5 milisecunde și 12. milisecunde. Dar ce zici de asta: Să presupunem că am decis că îmi voi păstra lumina aprinsă timp de un an pentru fiecare număr de pe zaruri? Apoi, dacă aruncă un 12, aș străluci lumina către tine timp de 12 ani și cred că vei fi de acord că nu există nicio posibilitate să faci o greșeală în a afla numărul corect? Ai putea să faci o pauză și să te joci la baseball, ai putea chiar să te joci la craps la Vegas timp de 6 luni, atâta timp cât la un moment dat al anului să arunci o privire peste stradă pentru a vedea dacă lumina este aprinsă, nu ți-ar fi dor să contezi. Ei bine, exact asta facem pentru microcontrolere! O singură milisecundă pentru CPU este ca un an. Deci, dacă pornesc semnalul timp de 12 milisecunde, nu există aproape nicio șansă ca celălalt microcontroler să-l confunde timp de 10 sau 11, indiferent de ceea ce întrerupe și ce nu se întâmplă între timp. Pentru microcontrolere, o milisecundă este o eternitate, deci iată ce vom face. Mai întâi vom alege două porturi pe controler pentru a fi porturile noastre de comunicații. Voi folosi PD6 pentru primirea datelor (l-am putea numi Rx dacă ne place) și voi alege PD7 pentru transmiterea datelor (l-am putea numi Tx dacă ne place). Cipul analizorului va verifica periodic pinul Rx și, dacă vede un semnal, va cădea într-un „subrutină de comunicații” și va transmite apoi un semnal de întoarcere la rola de zaruri spunând că este gata să primească. Ambii vor începe sincronizarea, iar rola de zaruri va transmite un semnal (adică 5V) pentru o milisecundă pe număr pe zaruri. Deci, dacă aruncarea ar fi dublă șase sau 12, atunci rolul de zaruri ar seta PD7 la 5V timp de 12 milisecunde și apoi l-ar regăsi la 0V. Analizorul își va verifica pinul PD6 la fiecare milisecundă, numărând de fiecare dată, iar când revine la 0V, apoi va afișa numărul rezultat pe afișajul analizorului, arătând un număr de douăsprezece în binar pe LED-uri. Deci acesta este planul. Să vedem dacă îl putem implementa.

Pasul 2: Subrutine de comunicații

Primul lucru pe care trebuie să-l facem este să conectăm cele două controlere. Deci, luați un fir de la PD6 pe unul și conectați-l la PD7 pe celălalt și invers. Apoi inițializați-le setând PD7 pe OUTPUT pe ambele și PD6 pe INPUT pe ambele. În cele din urmă, setați-le pe toate la 0V. Mai exact, adăugați următoarele la secțiunea Init, sau Resetare a codului de pe fiecare microcontroler:

sbi DDRD, 7; PD7 setat la ieșire

cbi PortD, 7; PD7 inițial 0V cbi DDRD, 6; PD6 setat la intrarea cbi PortD, 6; PD6 inițial 0V clr total; total pe zaruri inițial 0

Acum să configurăm subrutina de comunicații pe cipul cu role de zaruri. Mai întâi definiți o nouă variabilă în partea de sus numită „total”, care va stoca numărul total aruncat pe perechea de zaruri și îl va inițializa la zero.

Apoi scrieți un subrutină pentru a comunica cu analizorul:

comunica:

cbi PortD, 7 sbi PortD, 7; Trimiteți semnalul gata așteptați: sbic PinD, 6; citiți PinD și săriți dacă 0V rjmp așteptați întârzierea 8; întârziere pentru sincronizare (găsită experimental) trimite: dec total delay 2; întârziere pentru fiecare număr de matrițe cpi total, 0; 0 aici înseamnă că numărul total de întârzieri au fost trimise breq PC + 2 rjmp send cbi PortD, 7; PD7 până la 0V clr total; resetați totalul zarurilor la 0 ret

În analizor adăugăm un apel de la rutina principală la subrutina de comunicare:

analizor clr; pregătește-te pentru un număr nou

sbic PinD, 6; verificați PD6 pentru un semnal de 5V pentru a comunica; dacă 5V merg să comunice analizorul de mov, total; ieșire la afișaj analizor analizor rcall

și apoi scrieți subrutina de comunicare după cum urmează:

comunica:

clr total; resetare totală la 0 întârziere 10; întârziere pentru a scăpa de bounces sbi PortD, 7; setați PB7 la 5V pentru a semnaliza recepția gata: întârziere 2; așteptați numărul următor în total; increment total sbic PinD, 6; dacă PD6 revine la 0V, am terminat de primit rjmp; în caz contrar, faceți o copie de rezervă pentru mai multe date cbi PortD, 7; resetați PD7 când ați terminat ret

Gata! Acum fiecare microcontroler este configurat pentru a comunica rezultatul aruncării zarurilor și apoi pentru a-l afișa pe analizor.

Vom implementa un mod mult mai eficient de comunicare mai târziu, atunci când trebuie să transferăm conținutul unui registru între controlere în loc de doar o aruncare de zaruri. În acest caz, vom folosi în continuare doar două fire care le conectează, dar vom folosi 1, 1 pentru a însemna „începe transmisia”; 0, 1 înseamnă "1"; 1, 0 înseamnă "0"; și în cele din urmă 0, 0 pentru a însemna "transmisie finală".

Exercițiul 1: vedeți dacă puteți implementa metoda mai bună și utilizați-o pentru a transfera aruncarea zarurilor ca un număr binar de 8 biți.

Voi atașa un videoclip care îl arată pe al meu în funcțiune.

Pasul 3: Concluzie

Concluzie
Concluzie

Am atașat codul complet pentru referință. Nu este atât de curat și ordonat aș vrea, dar îl voi curăța pe măsură ce îl vom extinde în viitoarele tutoriale.

De acum înainte voi atașa fișierele care conțin cod, mai degrabă decât să le scriu aici. Vom scrie doar secțiunile pe care ne interesează să le discutăm.

Acesta a fost un scurt tutorial în care am venit cu o metodă simplă de a spune microcontrolerului analizorului nostru care este rezultatul aruncării zarurilor noastre din microcontrolerul nostru cu role de zaruri, folosind doar două porturi.

Exercițiul 2: În loc să utilizați un semnal gata pentru a arăta când ruloul de zaruri este gata să transmită și un altul când analizorul este gata să recepționeze, utilizați o „întrerupere externă” numită „întrerupere schimbare pin”. Pinii de pe atmega328p pot fi folosiți în acest fel, motiv pentru care au PCINT0 prin PCINT23 alături în diagrama pinout. Puteți implementa acest lucru ca întrerupere într-un mod similar, așa cum am făcut cu întreruperea de revărsare a temporizatorului. În acest caz, „manipulatorul” de întrerupere va fi subrutina care comunică cu rolele de zaruri. În acest fel, nu este nevoie să apelați subrutina de comunicații de la main: va merge acolo de fiecare dată când va exista o întrerupere provenită de la o schimbare de stare pe acel pin.

Exercițiul 3: O modalitate mult mai bună de comunicare și transfer a datelor între un microcontroler către o colecție de altele este utilizarea interfeței seriale încorporate cu 2 fire pe microcontrolerul însuși. Încercați să citiți secțiunea 22 a fișei tehnice și să vedeți dacă puteți afla cum să o implementați.

Vom folosi aceste tehnici mai sofisticate în viitor atunci când vom adăuga controlere suplimentare.

Faptul că tot ce am făcut cu analizorul nostru este să luăm totalul aruncării zarurilor și apoi să îl imprimăm în binar folosind LED-uri, nu este important. Faptul este că acum analizatorul nostru „știe” ce este aruncarea zarurilor și o poate folosi în consecință.

În următorul tutorial vom schimba scopul „analizatorului” nostru, vom introduce câteva elemente de circuit și vom folosi aruncarea zarurilor într-un mod mai interesant.

Pana data viitoare…

Recomandat: