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.

Metode de citire și gestionare a porturilor I / O Arduino

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);

Rezistență de intrare

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.

Porturi de micro-controler Atmega168

Poate că cineva va examina mai clar porturile sub această formă (aceeași în figură, dar într-un design diferit):

Porturi de micro-controler Atmega328

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.

Tabelul de concordanță al porturilor Arduino și Atmega

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.

Arduino cod LED intermitent

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

Gestionarea cepurilor

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.

Structura port D

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”.

Calculator Windows

Introduceți numărul dorit:

Modul Calculator programator

Și faceți clic pe HEX:

Traducerea numerelor pe un calculator

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

Transfer de numere în Arduino IDE

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:

Introducerea datelor în fiecare pin

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

Intocmirea unei inregistrari

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

Operație de adăugare logică

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:

Înmulțirea și inversarea logică

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

 

Înmulțirea conținutului portului cu un număr

Ș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.

Înmulțiți conținutul portului cu zero modificat cu 5 biț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:

Citiți din porturi

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 i.electricianexp.com:

  • Conectarea și programarea Arduino pentru începători
  • Cum să conectați codificatorul incremental la Arduino
  • Microcontrolere PIC pentru începători
  • Telecomandă cu microcontroler: Telecomandă IR, Arduino, ESP8266, 433 ...
  • Măsurarea temperaturii și umidității pe Arduino - o selecție de moduri

  •  
     
    Comentarii:

    # 1 a scris: Kipovets | [Cite]

     
     

    "Dar, cu adăugarea logică, apare o problemă - nu puteți transforma unitatea în zero, deoarece:

    0 + 0 = 1 "(c)

    Supraveghere mică: 0 + 0 = 0.

     
    Comentarii:

    # 2 a scris: chugou | [Cite]

     
     

    Kipovets, probabil a vrut să spună:

    1 + 1 = 1

     
    Comentarii:

    # 3 a scris: | [Cite]

     
     

    Kipovets,
    Tipa banală! Vedeți cât de bine este că specialiștii stau pe portalul nostru! Trebuie să faceți numai conținut adecvat!

     
    Comentarii:

    # 4 a scris: Serg | [Cite]

     
     

    În partea finală, se spune PORTB | = 1 << 5 ... if (digitalRead (12) == 1). Dar 5 pin din portul B, este 13 pin de arduino. Sau mă înșel ?!

     
    Comentarii:

    # 5 a scris: p-a-h-o | [Cite]

     
     

    Dacă (PINB == B00010000) {} nu estesimilar cu dacă am scris dacă (digitalRead (12) == 1)
    mai degrabă analog
    (digitalRead (12) == 1) &&(digitalRead (13) == 1) &&(digitalRead (14) == 1) &&(digitalRead (15) == 1) &&(digitalRead (11) == 1) ... și deci 8 pini de port

    Aici aveți nevoie fie de acest lucru:
    dacă (
    ! (~ PORTB & (1 << PB4))) {} //se întoarce0 sau 1
    fie astfel:
    dacă (PORTB & (1 << PB4)) {} // returnează unitatea schimbată = 16, DEC
    fie astfel:
    dacă (
    bit_is_set (PORTB, 4)) {}// returnează unitatea schimbată = 16, DEC