categorii: Circuite de micro-controler
Număr de vizualizări: 41940
Comentarii la articol: 5
Metode de citire și gestionare a porturilor I / O Arduino
Pentru a interacționa cu lumea exterioară, trebuie să configurați ieșirile microcontrolerului pentru a primi sau transmite un semnal. Drept urmare, fiecare pin va funcționa în modul de intrare și ieșire. Există două moduri de a face acest lucru pe fiecare placă Arduino pe care o iubești, exact cum înveți din acest articol.

Metoda 1 - Limba standard pentru IDE Arduino
Toată lumea știe asta Arduino Este programat în C ++ cu unele adaptări și simplificări pentru începători. Se numește Cablare. Inițial, toate porturile arduino sunt definite ca intrări și nu este necesară specificarea acestui lucru în cod.
Porturile sunt de obicei scrise în funcția de inițializare variabilă:
void setup ()
{
// cod
}
Comanda pinMode este folosită pentru aceasta, are o sintaxă destul de simplă, mai întâi este indicat numărul portului, apoi rolul său este separat prin virgule.
pinMode (nomer_porta, naznachenie)
Cu această comandă, circuitul intern al microcontrolerului este configurat într-un mod specific.
Există trei moduri în care portul poate funcționa: INPUT - intrare, în acest mod apare citirea datelor de la senzori, starea butonului, semnal analogic și digital. Portul este situat în așa-numitele stare de înaltă impedanță, în cuvinte simple - intrarea are o rezistență ridicată. Această valoare este setată, de exemplu, 13 pini ai plăcii, dacă este necesar, după cum urmează:
pinMode (13, INPUT);
OUTPUT - ieșire, în funcție de comanda prescrisă în cod, portul ia o valoare de unu sau zero. Ieșirea devine un fel de sursă de putere controlată și produce un curent maxim (în cazul nostru, 20 mA și 40 mA la vârf) conectat la sarcină. Pentru a atribui un port ca ieșire Arduino trebuie să introduceți:
pinMode (13, OUTPUT);
INPUT_PULLUP - portul funcționează ca o intrare, dar așa-numitul se conectează la el. Rezistență de tragere de 20 kΩ.
Circuitul intern condițional al portului în această stare este prezentat mai jos. O caracteristică a acestei intrări este că semnalul de intrare este perceput ca inversat („unitatea” la intrare este percepută de microcontroler ca „zero”). În acest mod, nu puteți utiliza rezistențe exterioare de extragere atunci când lucrați cu butoane.
pinMode (13, INPUT_PULLUP);

Datele sunt primite din porturi și transmise acestora prin comenzile:
-
digitalWrite (pin, valoare) - convertește pinul de ieșire în 1 sau 0, respectiv, tensiunea de 5V apare sau dispare la ieșire, de exemplu digitalWrite (13, HIGH) - furnizează 5 volți (unitate logică) în 13 pini și digitalWrite (13, scăzut) ) - traduce 13 pini într-o stare de zero logică (0 volți);
-
digitalRead (pin) - citește valoarea de la intrare, de exemplu digitalRead (10), citește semnalul de la 10 pini;
-
analogRead (pin) - citește un semnal analog dintr-un port analog, obțineți o valoare în intervalul de la 0 la 1023 (într-un ADC de 10 biți), un exemplu este analogRead (3).
Metoda a doua - gestiona porturile prin registrele Atmega și accelerează codul
Un astfel de control este desigur simplu, dar în acest caz există două dezavantaje - un consum mai mare de memorie și performanțe slabe atunci când lucrați cu porturi. Dar vă amintiți ce este Arduino, indiferent de placa de opțiuni (uno, micro, nano)? În primul rând, asta microcontroler AVR familie ATMEGA, recent utilizat MK atmega328.
În IDE Arduino, puteți programa în limba maternă pentru această familie de C AVR, de parcă lucrați cu un microcontroller separat. Dar primele lucruri în primul rând. Pentru a gestiona în acest fel porturile Arduino, trebuie să luați în considerare cu atenție următoarea ilustrație.
Poate că cineva va examina mai clar porturile sub această formă (aceeași în figură, dar într-un design diferit):

Aici vedeți corespondența concluziilor lui Arduino și numele porturilor Atmega. Deci, avem 3 porturi:
-
PORTB;
-
PORTC;
-
PORTD.
Pe baza imaginilor prezentate, am compilat un tabel de corespondență între porturile Arduino și Atmega, care vă va fi util în viitor.

Atmega are trei registre pe 8 biți care controlează starea porturilor, de exemplu, portul B își va da seama de scopul lor prin desenarea analogiilor cu instrumentele de cablare standard descrise la începutul acestui articol:
-
PORTBOL - Gestionează starea de ieșire. Dacă pinul este în modul „Ieșire”, atunci 1 și 0 determină prezența acelorași semnale la ieșire. Dacă pinul este în modul „Intrare”, atunci 1 conectează o rezistență de tragere (aceeași ca INPUT_PULLUP discutată mai sus), dacă 0 este o stare cu impedanță ridicată (analogul INPUT);
-
PINB este un registru citit. În consecință, conține informații despre starea curentă a pinilor portului (unitate logică sau zero).
-
DDRB - registru de direcție port. Cu acesta, indicați microcontrolerului dacă portul este o intrare sau o ieșire, cu „1” o ieșire și „0” o intrare.
În locul literei „B”, poate exista oricare alta în funcție de numele porturilor, de exemplu, alte comenzi PORTD sau PORTC funcționează în mod similar.
Clipește LED-ul, înlocuim funcția standard digitalWrite (). În primul rând, să amintim cum arată exemplul original din biblioteca Arduino IDE.

Acesta este codul binecunoscutului „clipit”, care arată clipirea LED-ului încorporat pe placă.

Comentariile explică codul. Logica acestei lucrări este următoarea.
Comanda PORTB B00100000 pune PB5 în starea unei unități logice, aspect, iar acele imagini și tabelul care sunt situate mai jos și vedeți că PB5 corespunde la 13 pini de Arduina.
Litera "B" din fața numerelor indică faptul că scriem valorile în formă binară. Numerotarea în binar merge de la dreapta la stânga, adică aici unitatea se află în al șaselea bit de la marginea din dreapta a bitului, ceea ce spune microcontrolerului despre interacțiunea cu starea celui de-al șaselea bit al registrului port B (PB5). Tabelul de mai jos arată structura portului D, este similară și este prezentată ca exemplu.

Puteți seta valoarea nu în mod binar, ci în formă hexadecimală, de exemplu, pentru aceasta deschidem calculatorul Windows și în modul „VIZIONĂ”, selectăm opțiunea „Programator”.

Introduceți numărul dorit:

Și faceți clic pe HEX:

În acest caz, transferăm toate acestea către IDE Arduino, dar în locul prefixului „B” va fi „0x”.

Dar cu această intrare există o problemă. Dacă aveți ceva conectat la alți pini, atunci introduceți o comandă precum B00010000 - veți reseta toate pinii cu excepția 13 (PB5). Puteți introduce date pentru fiecare pin individual. Va arăta astfel:

O astfel de înregistrare poate părea de neînțeles, să ne dăm seama.

Aceasta este o operație de adăugare logică, | = înseamnă adăugarea a ceva în conținutul portului.

Acest lucru înseamnă că trebuie să adăugați un cuvânt de 8 biți în registru cu o unitate schimbată cu 5 biți - ca urmare, dacă 11000010 se dovedește a fi 110.110.010. În acest exemplu, se poate observa că doar PB5 s-a schimbat, biții rămași ai acestui registru au rămas neschimbați, precum și Starea pinilor microcontrolatorului a rămas neschimbată.
Dar, cu adăugarea logică, apare o problemă - nu puteți transforma unitatea în zero, deoarece:
0+0=1
1+0=1
0+1=1
Înmulțirea și inversarea logică ne vor veni în ajutor:

& = înseamnă să înmulțiți conținutul portului cu un număr specific.

Și acesta este numărul cu care înmulțim. Semnul „~” indică inversarea. În cazul nostru, unitatea inversată este zero. Adică multiplicăm conținutul portului cu zero, deplasat cu 5 biți. De exemplu, a fost 10110001, a devenit 10100001. Biți rămași au rămas neschimbați.

Același lucru se poate face folosind operația inversă (^):
Citind din porturi, analogul digitalRead () se realizează folosind registrul PIN, în practică arată astfel:

Aici verificăm dacă expresia dintre paranteze este egală cu starea reală a porturilor, adică. în mod similar, dacă am fi scris dacă (digitalRead (12) == 1).
concluzie
De ce există astfel de dificultăți în gestionarea portului dacă puteți utiliza funcții standard convenabile? Totul ține de viteză și dimensiunea codului. Când folosiți a doua metodă, discutată în articol, dimensiunea codului este redusă semnificativ, iar viteza crește cu mai multe ordine de mărime. DigitalWrite standard () a fost efectuat în 1800 μs și înregistrarea directă în port în 0,2 μs și digitalRead () în 1900 μs și a devenit de asemenea în 0,2 μs. Această metodă de control a fost găsită pe spațiile deschise ale rețelei și este adesea găsită în cod. proiecte terminate.
Consultați și la electro-ro.tomathouse.com
: