Kategorie: Obwody mikrokontrolera
Liczba wyświetleń: 41940
Komentarze do artykułu: 5

Metody odczytu i zarządzania portami we / wy Arduino

 

Aby wchodzić w interakcje ze światem zewnętrznym, musisz skonfigurować wyjścia mikrokontrolera, aby odbierać lub przesyłać sygnał. W rezultacie każdy pin będzie działał w trybie wejścia i wyjścia. Istnieją dwa sposoby, aby to zrobić na każdej planszy Arduino, którą kochasz, dokładnie tak, jak uczysz się z tego artykułu.

Metody odczytu i zarządzania portami we / wy Arduino

Metoda pierwsza - standardowy język dla Arduino IDE

Wszyscy to wiedzą Arduino Jest programowany w C ++ z pewnymi adaptacjami i uproszczeniami dla początkujących. To się nazywa okablowanie. Początkowo wszystkie porty arduino są zdefiniowane jako dane wejściowe i nie ma potrzeby określania tego w kodzie.

Porty są zwykle zapisywane w funkcji inicjalizacji zmiennych:

void setup ()
{
// kod
}

Służy do tego polecenie pinMode, ma dość prostą składnię, najpierw wskazywany jest numer portu, a następnie jego rola jest oddzielana przecinkami.

pinMode (nomer_porta, naznachenie)

Za pomocą tego polecenia wewnętrzny obwód mikrokontrolera jest konfigurowany w określony sposób.

Istnieją trzy tryby działania portu: INPUT - wejście, w tym trybie występuje odczyt danych z czujników, status przycisku, sygnał analogowy i cyfrowy. Port znajduje się w tzw stan wysokiej impedancji, krótko mówiąc - wejście ma wysoką rezystancję. Ta wartość jest ustawiana, na przykład, 13-pinowa tablica, jeśli to konieczne, w następujący sposób:

pinMode (13, WEJŚCIE);

WYJŚCIE - wyjście, w zależności od polecenia określonego w kodzie, port przyjmuje wartość jeden lub zero. Wyjście staje się rodzajem kontrolowanego źródła zasilania i wytwarza maksymalny prąd (w naszym przypadku 20 mA i 40 mA w szczycie) do podłączonego obciążenia. Aby przypisać port jako wyjście dla Arduino, musisz wprowadzić:

pinMode (13, WYJŚCIE);

INPUT_PULLUP - port działa jako wejście, ale tzw. Łączy się z nim. Rezystor podciągający 20 kΩ.

Warunkowe wewnętrzne obwody portu w tym stanie pokazano poniżej. Cechą tego wejścia jest to, że sygnał wejściowy jest postrzegany jako odwrócony („jednostka” na wejściu jest postrzegana przez mikrokontroler jako „zero”). W tym trybie nie można używać zewnętrznych rezystorów podciągających podczas pracy z przyciskami.

pinMode (13, INPUT_PULLUP);

Wejściowy rezystor podciągający

Dane są odbierane z portów i przesyłane do nich za pomocą poleceń:

  • digitalWrite (pin, wartość) - konwertuje pin wyjściowy odpowiednio na logiczny 1 lub 0, napięcie 5 V pojawia się lub znika na wyjściu, na przykład digitalWrite (13, WYSOKI) - dostarcza 5 woltów (jednostka logiczna) na 13 pinów, a digitalWrite (13, niski ) - przekształca 13 pinów w stan logicznego zera (0 woltów);

  • digitalRead (pin) - odczytuje wartość z wejścia, na przykład digitalRead (10), odczytuje sygnał z 10 pinów;

  • analogRead (pin) - odczytuje sygnał analogowy z portu analogowego, otrzymujesz wartość z zakresu od 0 do 1023 (w 10-bitowym ADC), przykładem jest analogRead (3).


Metoda druga - zarządzanie portami poprzez rejestry Atmega i przyspieszenie kodu

Taka kontrola jest oczywiście prosta, ale w tym przypadku występują dwie wady - większe zużycie pamięci i słaba wydajność podczas pracy z portami. Ale pamiętaj, czym jest Arduino, niezależnie od karty opcji (uno, micro, nano)? Przede wszystkim to mikrokontroler Rodzina AVR ATMEGA, ostatnio używany MK atmega328.

W Arduino IDE możesz zaprogramować język C AVR natywny dla tej rodziny, tak jakbyś pracował z oddzielnym mikrokontrolerem. Ale przede wszystkim. Aby w ten sposób zarządzać portami Arduino, musisz najpierw dokładnie rozważyć następującą ilustrację.

Porty mikrokontrolera Atmega168

Być może ktoś dokładniej zbada porty w tej formie (to samo na rysunku, ale w innym projekcie):

Porty mikrokontrolera Atmega328

Tutaj widzisz zgodność wniosków Arduino i nazw portów Atmega. Mamy więc 3 porty:

  • PORTB;

  • PORTC;

  • PORTD.

Na podstawie pokazanych zdjęć skompilowałem tabelę korespondencji między portami Arduino i Atmega, przyda ci się w przyszłości.

Tabela zgodności portów Arduino i Atmega

Atmega ma trzy 8-bitowe rejestry, które kontrolują stan portów, na przykład port B odkryje swój cel, rysując analogie ze standardowymi narzędziami do okablowania opisanymi na początku tego artykułu:

  • PORTB - Zarządzaj statusem wyjściowym. Jeśli pin jest w trybie „Wyjście”, wówczas 1 i 0 określają obecność tych samych sygnałów na wyjściu. Jeśli pin znajduje się w trybie „Wejściowym”, wówczas 1 łączy rezystor podciągający (taki sam jak omówiony powyżej INPUT_PULLUP), jeśli 0 jest stanem wysokiej impedancji (analog INPUT);

  • PINB to rejestr odczytu. Odpowiednio zawiera informacje o aktualnym stanie pinów portu (jednostka logiczna lub zero).

  • DDRB - rejestr kierunku portu. Za jego pomocą wskażesz mikrokontrolerowi, co to jest port jako wejście lub wyjście, a „1” to wyjście, a „0” to wejście.

Zamiast litery „B” mogą być dowolne inne zgodnie z nazwami portów, na przykład PORTD lub PORTC inne polecenia działają podobnie.

Mrugamy diodą LED, zastępujemy standardową funkcję digitalWrite (). Najpierw przypomnijmy sobie, jak wygląda oryginalny przykład z biblioteki IDE Arduino.

Kod błyskowy Arduino LED

Jest to kod znanego „mrugnięcia”, który pokazuje mruganie diody LED wbudowanej w płytkę.

Zarządzanie pinami

Komentarze wyjaśniają kod. Logika tej pracy jest następująca.

Polecenie PORTB B00100000 wprowadza PB5 w stan jednostki logicznej, spójrz, a te zdjęcia i tabela poniżej znajdują się i widzimy, że PB5 odpowiada 13 pinom Arduiny.

Litera „B” przed cyframi oznacza, że ​​zapisujemy wartości w formie binarnej. Numeracja binarna przechodzi od prawej do lewej, tj. tutaj jednostka znajduje się w szóstym bicie od prawej krawędzi bitu, co informuje mikrokontroler o interakcji ze stanem szóstego bitu rejestru B portu (PB5). Poniższa tabela pokazuje strukturę portu D, jest on podobny i podano go jako przykład.

Struktura portu D.

Możesz ustawić wartość nie w postaci binarnej, ale w postaci szesnastkowej, na przykład, w tym celu otwieramy kalkulator systemu Windows iw trybie „WIDOK” wybierz opcję „Programator”.

Kalkulator Windows

Wpisz żądany numer:

Tryb kalkulatora programisty

I kliknij HEX:

Tłumaczenie liczb na kalkulatorze

W tym przypadku przesyłamy to wszystko do Arduino IDE, ale zamiast przedrostka „B” będzie to „0x”.

Przeniesienie numeru w Arduino IDE

Ale z tym wejściem jest problem. Jeśli masz coś podłączonego do innych pinów, wprowadź polecenie takie jak B00010000 - zresetujesz wszystkie piny oprócz 13 (PB5). Możesz wprowadzić dane dla każdego pinu osobno. Będzie to wyglądać tak:

Wprowadzanie danych do każdego pinu

Taki zapis może wydawać się niezrozumiały, wymyślmy to.

Przetwarzanie rekordu

Jest to logiczna operacja dodawania, | = oznacza dodanie czegoś do zawartości portu.

Operacja dodawania logicznego

Oznacza to, że musisz dodać słowo 8 bitów do rejestru z jednostką przesuniętą o 5 bitów - w rezultacie, jeśli 11000010 okaże się 110 1101010. W tym przykładzie widać, że zmienił się tylko PB5, pozostałe bity tego rejestru pozostały niezmienione, a także Stan pinów mikrokontrolera pozostał niezmieniony.

Ale przy logicznym dodawaniu pojawia się problem - nie można zmienić jednostki na zero, ponieważ:

0+0=1

1+0=1

0+1=1

Pomoże nam logiczne mnożenie i inwersja:

Logiczne mnożenie i odwracanie

& = oznacza pomnożenie zawartości portu przez określoną liczbę.

 

Mnożenie zawartości portu przez liczbę

I to jest liczba, przez którą mnożymy. Znak „~” oznacza inwersję. W naszym przypadku jednostka odwrócona wynosi zero. Oznacza to, że mnożymy zawartość portu przez zero, przesuwane o 5 bitów. Na przykład było 10110001, stało się 10100001. Pozostałe bity pozostały niezmienione.

Pomnóż zawartość portu przez zero przesunięte o 5 bitów

To samo można zrobić za pomocą operacji odwracania (^):

Odczytując z portów, analog digitalRead () jest wykonywany przy użyciu rejestru PIN, w praktyce wygląda to tak:

Czytaj z portów

Tutaj sprawdzamy, czy wyrażenie w nawiasach jest równe rzeczywistemu stanowi portów, tj. podobnie, gdybyśmy napisali if (digitalRead (12) == 1).


Wniosek

Dlaczego występują takie trudności w zarządzaniu portami, jeśli można korzystać ze standardowych wygodnych funkcji? Chodzi o szybkość i rozmiar kodu. Podczas korzystania z drugiej metody omówionej w artykule rozmiar kodu jest znacznie zmniejszony, a prędkość wzrasta o kilka rzędów wielkości. Standardowy digitalWrite () został wykonany w 1800 μs, a nagrywanie bezpośrednio do portu w 0,2 μs, a digitalRead () w 1900 μs, a także w 0.2 μs. Ta metoda kontroli została znaleziona na otwartych przestrzeniach sieci i często znajduje się w kodzie. zakończone projekty.

Zobacz także na bgv.electricianexp.com:

  • Podłączanie i programowanie Arduino dla początkujących
  • Jak podłączyć enkoder inkrementalny do Arduino
  • Mikrokontrolery PIC dla początkujących
  • Pilot mikrokontrolera: pilot na podczerwień, Arduino, ESP8266, 433 ...
  • Pomiar temperatury i wilgotności w Arduino - wybór sposobów

  •  
     
    Komentarze:

    # 1 napisał: Kipowec | [cytat]

     
     

    „Ale przy logicznym dodawaniu pojawia się problem - nie można zmienić jednostki na zero, ponieważ:

    0 + 0 = 1 "(c)

    Mały nadzór: 0 + 0 = 0.

     
    Komentarze:

    # 2 napisał: chugou | [cytat]

     
     

    Kipovets, prawdopodobnie chciał powiedzieć:

    1 + 1 = 1

     
    Komentarze:

    # 3 napisał: | [cytat]

     
     

    Kipowec,
    Banalna literówka! Widzisz, jak dobrze, że specjaliści siedzą na naszym portalu! Musisz tworzyć tylko odpowiednie treści!

     
    Komentarze:

    # 4 napisał: Serg | [cytat]

     
     

    W końcowej części jest napisane PORTB | = 1 << 5 ... if (digitalRead (12) == 1). Ale 5 pin portu B, to 13 pin arduino. A może się mylę?

     
    Komentarze:

    # 5 napisał: p-a-h-a | [cytat]

     
     

    Jeśli (PINB == B00010000) {} nie jestpodobnie jak gdybyśmy napisali if (digitalRead (12) == 1)
    raczej analogowy
    (digitalRead (12) == 1) i&(digitalRead (13) == 1) i&(digitalRead (14) == 1) i&(digitalRead (15) == 1) i&(digitalRead (11) == 1) ... a więc 8 pinów portów

    Tutaj potrzebujesz albo tego:
    jeśli (
    ! (~ PORTB & (1 << PB4))) {} //zwraca0 lub 1
    albo tak:
    jeśli (PORTB & (1 << PB4)) {} // zwraca przesuniętą jednostkę = 16, DEC
    albo tak:
    jeśli (
    bit_is_set (PORTB, 4)) {}// zwraca przesuniętą jednostkę = 16, DEC