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.

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

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ę.
Być może ktoś dokładniej zbada porty w tej formie (to samo na rysunku, ale w innym projekcie):

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.

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.

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

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.

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

Wpisz żądany numer:

I kliknij HEX:

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

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:

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

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

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:

& = oznacza pomnożenie zawartości portu przez określoną 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.

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:

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 electro-pl.tomathouse.com
: