Kategorien: Mikrocontroller-Schaltungen
Anzahl der Ansichten: 41940
Kommentare zum Artikel: 5

Methoden zum Lesen und Verwalten von Arduino-E / A-Ports

 

Um mit der Außenwelt zu interagieren, müssen Sie die Ausgänge des Mikrocontrollers so konfigurieren, dass sie ein Signal empfangen oder senden. Infolgedessen arbeitet jeder Pin im Eingangs- und Ausgangsmodus. Es gibt zwei Möglichkeiten, dies auf jedem Arduino-Board zu tun, das Sie lieben, genau wie Sie aus diesem Artikel lernen.

Methoden zum Lesen und Verwalten von Arduino-E / A-Ports

Methode Eins - Die Standardsprache für die Arduino IDE

Das weiß jeder Arduino Es ist in C ++ mit einigen Anpassungen und Vereinfachungen für Anfänger programmiert. Es heißt Verkabelung. Anfänglich sind alle Arduino-Ports als Eingaben definiert, und dies muss nicht im Code angegeben werden.

Ports werden normalerweise in der Variableninitialisierungsfunktion geschrieben:

void setup ()
{
// Code
}

Hierfür wird der Befehl pinMode verwendet. Er hat eine recht einfache Syntax. Zuerst wird die Portnummer angegeben, dann wird seine Rolle durch Kommas getrennt.

pinMode (nomer_porta, naznachenie)

Mit diesem Befehl wird die interne Schaltung des Mikrocontrollers auf eine bestimmte Weise konfiguriert.

Es gibt drei Modi, in denen der Port arbeiten kann: INPUT - Eingang, in diesem Modus erfolgt Daten von Sensoren lesen, Tastenstatus, analoges und digitales Signal. Der Hafen befindet sich im sogenannten hochohmiger Zustand, in einfachen Worten - der Eingang hat einen hohen Widerstand. Dieser Wert wird beispielsweise bei Bedarf wie folgt auf 13 Pin der Platine eingestellt:

pinMode (13, INPUT);

AUSGABE - Ausgabe, abhängig von dem im Code vorgeschriebenen Befehl, nimmt der Port den Wert Eins oder Null an. Der Ausgang wird zu einer Art geregelter Stromquelle und erzeugt einen maximalen Strom (in unserem Fall 20 mA und 40 mA an der Spitze) an die daran angeschlossene Last. Um Arduino einen Port als Ausgang zuzuweisen, müssen Sie Folgendes eingeben:

PinMode (13, OUTPUT);

INPUT_PULLUP - Der Port fungiert als Eingang, aber der sogenannte verbindet sich mit ihm. 20 kΩ Pull-Up Widerstand.

Die bedingte interne Schaltung des Ports in diesem Zustand ist unten gezeigt. Ein Merkmal dieses Eingangs ist, dass das Eingangssignal als invertiert wahrgenommen wird (die "Einheit" am Eingang wird vom Mikrocontroller als "Null" wahrgenommen). In diesem Modus können Sie keine externen Pull-up-Widerstände verwenden bei der Arbeit mit Tasten.

pinMode (13, INPUT_PULLUP);

Eingangs-Pull-up-Widerstand

Daten werden von den Ports empfangen und durch die folgenden Befehle an sie übertragen:

  • digitalWrite (Pin, Wert) - wandelt den Ausgangspin in eine logische 1 bzw. 0 um, 5 V Spannung erscheint oder verschwindet am Ausgang, z. B. digitalWrite (13, HIGH) - liefert 5 Volt (logische Einheit) an 13 Pins und digitalWrite (13, niedrig) ) - übersetzt 13 Pins in einen Zustand logischer Null (0 Volt);

  • digitalRead (Pin) - liest den Wert vom Eingang, zum Beispiel digitalRead (10), liest das Signal von 10 Pins;

  • analogRead (Pin) - Liest ein analoges Signal von einem analogen Port. Sie erhalten einen Wert im Bereich von 0 bis 1023 (innerhalb eines 10-Bit-ADC). Ein Beispiel ist analogRead (3).


Methode zwei - Verwalten von Ports über Atmega-Register und Beschleunigen des Codes

Eine solche Steuerung ist natürlich einfach, aber in diesem Fall gibt es zwei Nachteile - einen höheren Speicherverbrauch und eine schlechte Leistung beim Arbeiten mit Ports. Aber denken Sie daran, was ist Arduino, unabhängig von der Optionskarte (uno, micro, nano)? Zuallererst dies Mikrocontroller AVR-Familie ATMEGA, kürzlich verwendet MK atmega328.

In der Arduino IDE können Sie für diese C AVR-Familie in der Muttersprache programmieren, als würden Sie mit einem separaten Mikrocontroller arbeiten. Aber das Wichtigste zuerst. Um Arduino-Ports auf diese Weise zu verwalten, müssen Sie zunächst die folgende Abbildung sorgfältig betrachten.

Atmega168 Mikrocontroller-Ports

Vielleicht wird jemand die Ports in dieser Form genauer untersuchen (das gleiche in der Abbildung, aber in einem anderen Design):

Atmega328 Mikrocontroller-Ports

Hier sehen Sie die Entsprechung der Schlussfolgerungen von Arduino und die Namen der Häfen von Atmega. Wir haben also 3 Ports:

  • PORTB;

  • PORTC;

  • PORTD.

Basierend auf den gezeigten Bildern habe ich eine Korrespondenztabelle zwischen den Häfen von Arduino und Atmega zusammengestellt, die Ihnen in Zukunft nützlich sein wird.

Konkordanztabelle der Häfen Arduino und Atmega

Atmega verfügt über drei 8-Bit-Register, die den Status der Ports steuern. Port B ermittelt beispielsweise seinen Zweck, indem es Analogien zu den am Anfang dieses Artikels beschriebenen Standardverdrahtungswerkzeugen zieht:

  • PORTB - Ausgabestatus verwalten. Befindet sich der Pin im Modus "Ausgang", bestimmen 1 und 0 das Vorhandensein derselben Signale am Ausgang. Befindet sich der Pin im Eingangsmodus, verbindet 1 einen Pull-up-Widerstand (wie oben beschrieben mit INPUT_PULLUP), wenn 0 ein hochohmiger Zustand ist (analog zu INPUT);

  • PINB ist ein Leseregister. Dementsprechend enthält es Informationen über den aktuellen Status der Port-Pins (logische Einheit oder Null).

  • DDRB - Portrichtungsregister. Damit geben Sie dem Mikrocontroller an, ob der Port ein Eingang oder ein Ausgang ist, wobei „1“ ein Ausgang und „0“ ein Eingang ist.

Anstelle des Buchstabens "B" kann es auch andere geben, die den Namen der Ports entsprechen, z. B. PORTD oder PORTC. Andere Befehle funktionieren ähnlich.

Wir blinken die LED und ersetzen die Standardfunktion digitalWrite (). Erinnern wir uns zunächst daran, wie das ursprüngliche Beispiel aus der Arduino IDE-Bibliothek aussieht.

Arduino LED blinkt Code

Dies ist der Code des bekannten „Blinkens“, der das Blinken der in die Platine eingebauten LED anzeigt.

Pin-Management

Die Kommentare erklären den Code. Die Logik dieser Arbeit ist wie folgt.

Der Befehl PORTB B00100000 versetzt PB5 in den Zustand einer logischen Einheit. Schauen Sie und die Bilder und die Tabelle, die sich unten befinden, und sehen Sie, dass PB5 13 Pin von Arduina entspricht.

Der Buchstabe "B" vor den Zahlen zeigt an, dass wir die Werte in binärer Form schreiben. Die Nummerierung in Binärform erfolgt von rechts nach links, d. H. Hier befindet sich die Einheit im sechsten Bit vom rechten Rand des Bits, was dem Mikrocontroller über die Wechselwirkung mit dem Zustand des sechsten Bits des Port-B-Registers (PB5) informiert. Die folgende Tabelle zeigt die Struktur von Port D, sie ist ähnlich und wird als Beispiel angegeben.

Port D Struktur

Sie können den Wert nicht binär, sondern hexadezimal einstellen. Dazu öffnen wir beispielsweise den Windows-Rechner und wählen im Modus „ANSICHT“ die Option „Programmierer“.

Windows-Rechner

Geben Sie die gewünschte Nummer ein:

Programmierrechner-Modus

Und klicken Sie auf HEX:

Übersetzung von Zahlen auf einem Taschenrechner

In diesem Fall übertragen wir dies alles auf die Arduino IDE, aber anstelle des Präfixes "B" ist es "0x".

Nummernübertragung in Arduino IDE

Bei dieser Eingabe gibt es jedoch ein Problem. Wenn Sie etwas mit anderen Pins verbunden haben, geben Sie einen Befehl wie B00010000 ein - Sie setzen alle Pins außer 13 (PB5) zurück. Sie können Daten für jeden Pin einzeln eingeben. Es wird so aussehen:

Eingabe von Daten in jeden Pin

Eine solche Aufzeichnung mag unverständlich erscheinen, lassen Sie es uns herausfinden.

Analysieren eines Datensatzes

Dies ist eine logische Additionsoperation. | = Bedeutet, dass dem Inhalt des Ports etwas hinzugefügt wird.

Logische Additionsoperation

Dies bedeutet, dass Sie ein Wort mit 8 Bits in das Register mit einer um 5 Bits verschobenen Einheit einfügen müssen. Wenn sich herausstellt, dass 11000010 110.110.010 ist. In diesem Beispiel ist zu sehen, dass sich nur PB5 geändert hat, und die verbleibenden Bits dieses Registers sind unverändert geblieben Der Zustand der Mikrocontroller-Pins blieb unverändert.

Bei logischer Addition tritt jedoch ein Problem auf: Sie können das Gerät nicht auf Null setzen, weil:

0+0=1

1+0=1

0+1=1

Logische Multiplikation und Inversion werden uns helfen:

Logische Multiplikation und Invertierung

& = bedeutet, den Inhalt des Ports mit einer bestimmten Zahl zu multiplizieren.

 

Portinhalt mit einer Zahl multiplizieren

Und das ist die Zahl, mit der wir multiplizieren. Das Zeichen „~“ zeigt die Inversion an. In unserem Fall ist die invertierte Einheit Null. Das heißt, wir multiplizieren den Inhalt des Ports mit Null, verschoben um 5 Bits. Zum Beispiel war es 10110001, es wurde 10100001. Die verbleibenden Bits blieben unverändert.

Multiplizieren Sie den Inhalt des Ports mit Null, verschoben um 5 Bit

Das gleiche kann mit der Invertierungsoperation (^) gemacht werden:

Beim Lesen von Ports wird das Analog von digitalRead () über das PIN-Register ausgeführt. In der Praxis sieht es folgendermaßen aus:

Von Ports lesen

Hier prüfen wir, ob der Ausdruck in Klammern gleich dem realen Zustand der Ports ist, d.h. ähnlich, wenn wir if (digitalRead (12) == 1) geschrieben haben.


Fazit

Warum gibt es solche Schwierigkeiten bei der Portverwaltung, wenn Sie bequeme Standardfunktionen verwenden können? Es geht um Geschwindigkeit und Codegröße. Bei Verwendung der im Artikel beschriebenen zweiten Methode wird die Codegröße erheblich reduziert und die Geschwindigkeit um mehrere Größenordnungen erhöht. Der Standard digitalWrite () wurde in 1800 μs durchgeführt und in 0,2 μs direkt am Port und digitalRead () in 1900 μs aufgezeichnet und wurde ebenfalls in 0,2 μs. Diese Steuerungsmethode wurde in den offenen Bereichen des Netzwerks gefunden und ist häufig im Code enthalten. abgeschlossene Projekte.

Siehe auch auf i.electricianexp.com:

  • Anschließen und Programmieren von Arduino für Anfänger
  • So verbinden Sie den Inkrementalgeber mit Arduino
  • PIC-Mikrocontroller für Anfänger
  • Mikrocontroller-Fernbedienung: IR-Fernbedienung, Arduino, ESP8266, 433 ...
  • Messung von Temperatur und Luftfeuchtigkeit auf Arduino - eine Auswahl von Methoden

  •  
     
    Kommentare:

    # 1 schrieb: Kipovets | [Zitat]

     
     

    "Aber mit logischer Addition tritt ein Problem auf - Sie können die Einheit nicht auf Null setzen, weil:

    0 + 0 = 1 "(c)

    Kleines Versehen: 0 + 0 = 0.

     
    Kommentare:

    # 2 schrieb: Chugou | [Zitat]

     
     

    Kipovets, wollte er wahrscheinlich sagen:

    1 + 1 = 1

     
    Kommentare:

    # 3 schrieb: | [Zitat]

     
     

    Kipovets,
    Banaler Tippfehler! Sie sehen, wie gut es ist, dass Spezialisten auf unserem Portal sitzen! Sie müssen nur geeignete Inhalte erstellen!

     
    Kommentare:

    # 4 schrieb: Serg | [Zitat]

     
     

    Im letzten Teil steht PORTB | = 1 << 5 ... if (digitalRead (12) == 1). Aber 5 Pin von Port B, es ist 13 Pin von Arduino. Oder irre ich mich ?!

     
    Kommentare:

    # 5 schrieb: p-a-h-a | [Zitat]

     
     

    If (PINB == B00010000) {} ist nichtähnlich wie wenn wir geschrieben haben if (digitalRead (12) == 1)
    eher analog
    (digitalRead (12) == 1) &&(digitalRead (13) == 1) &&(digitalRead (14) == 1) &&(digitalRead (15) == 1) &&(digitalRead (11) == 1) ... und damit 8 Port-Pins

    Hier brauchen Sie entweder Folgendes:
    if (
    ! (~ PORTB & (1 << PB4))) {} //kehrt zurück0 oder 1
    entweder so:
    if (PORTB & (1 << PB4)) {} // gibt die verschobene Einheit = 16, DEC zurück
    entweder so:
    if (
    bit_is_set (PORTB, 4)) {}// gibt die verschobene Einheit zurück = 16, DEC