Kategorie: Obvody mikrokontrolérů
Počet zobrazení: 41940
Komentáře k článku: 5

Metody čtení a správy vstupních / výstupních portů Arduino

 

Chcete-li komunikovat s vnějším světem, musíte nakonfigurovat výstupy mikrokontroléru pro příjem nebo přenos signálu. Výsledkem bude, že každý pin bude pracovat ve vstupním a výstupním režimu. Existují dva způsoby, jak to udělat na každé desce Arduino, kterou milujete, přesně jak se z tohoto článku poučíte.

Metody čtení a správy vstupních / výstupních portů Arduino

Metoda jedna - Standardní jazyk pro Arduino IDE

Každý to ví Arduino Je programován v C ++ s určitými úpravami a zjednodušením pro začátečníky. Říká se tomu zapojení. Zpočátku jsou všechny arduino porty definovány jako vstupy a není nutné je specifikovat v kódu.

Porty jsou obvykle zapsány ve funkci inicializace proměnných:

neplatné nastavení ()
{
// kód
}

K tomu se používá příkaz pinMode, má poměrně jednoduchou syntaxi, nejprve je uvedeno číslo portu, poté je jeho role oddělena čárkami.

pinMode (nomer_porta, naznachenie)

Tímto příkazem je vnitřní obvod mikrokontroléru nakonfigurován specifickým způsobem.

Port může fungovat ve třech režimech: INPUT - vstup, v tomto režimu dochází čtení dat ze senzorů, stav tlačítka, analogový a digitální signál. Port je umístěn v tzv vysoce impedanční stav, jednoduše řečeno - vstup má vysoký odpor. Tato hodnota se nastavuje například na 13 kolíků desky, je-li to nutné, následujícím způsobem:

pinMode (13, INPUT);

OUTPUT - výstup, v závislosti na příkazu předepsaném v kódu, má port hodnotu jedna nebo nula. Výstup se stává jakýmsi regulovaným zdrojem energie a produkuje maximální proud (v našem případě 20 mA a 40 mA na špičce) připojený k zátěži. Chcete-li přiřadit port jako výstup Arduinu, musíte zadat:

pinMode (13, VÝSTUP);

INPUT_PULLUP - port funguje jako vstup, ale tzv. Se k němu připojuje. 20 kΩ pull-up rezistor.

Podmíněné vnitřní obvody portu v tomto stavu jsou uvedeny níže. Charakteristikou tohoto vstupu je to, že vstupní signál je vnímán jako invertovaný („jednotka“ na vstupu je mikrokontrolérem vnímána jako „nula“). V tomto režimu nelze použít externí pull-up rezistory při práci s tlačítky.

pinMode (13, INPUT_PULLUP);

Vstupní pull-up rezistor

Data jsou přijímána z portů a přenášena na ně příkazy:

  • digitalWrite (pin, value) - převádí výstupní pin na logickou 1 nebo 0, na výstupu se objeví nebo zmizí 5V napětí, například digitalWrite (13, HIGH) - dodává 5 voltů (logická jednotka) na 13 pinů a digitalWrite (13, nízká) ) - převádí 13 pinů do stavu logické nuly (0 voltů);

  • digitalRead (pin) - čte hodnotu ze vstupu, například digitalRead (10), čte signál z 10 pinů;

  • analogRead (pin) - čte analogový signál z analogového portu, dostanete hodnotu v rozsahu od 0 do 1023 (v rámci 10bitového ADC), příkladem je analogRead (3).


Druhá metoda - správa portů prostřednictvím registrů Atmega a urychlení kódu

Takové ovládání je samozřejmě jednoduché, ale v tomto případě existují dvě nevýhody - větší spotřeba paměti a nízký výkon při práci s porty. Ale pamatujte si, co je Arduino, bez ohledu na volitelnou desku (uno, micro, nano)? Za prvé, tohle mikrokontrolér rodiny AVR ATMEGA, nedávno použité MK atmega328.

V Arduino IDE můžete naprogramovat jazyk C AVR nativní pro tuto rodinu, jako byste pracovali se samostatným mikrokontrolérem. Nejdříve ale první. Chcete-li tímto způsobem spravovat porty Arduino, musíte nejprve pečlivě zvážit následující obrázek.

Porty mikrokontroléru Atmega168

Možná někdo jasněji prozkoumá porty v této podobě (stejné na obrázku, ale v jiném designu):

Porty mikrokontroléru Atmega328

Zde vidíte korespondenci závěrů Arduina a názvy přístavů Atmega. Máme tedy 3 porty:

  • PORTB;

  • PORTC;

  • PORTD.

Na základě zobrazených obrázků jsem sestavil tabulku korespondence mezi přístavy Arduino a Atmega, bude to pro vás v budoucnu užitečné.

Tabulka shody portů Arduino a Atmega

Atmega má tři 8bitové registry, které řídí stav portů, například port B zjistí svůj účel nakreslením analogií pomocí standardních nástrojů pro kabeláž popsaných na začátku tohoto článku:

  • PORTB - Správa stavu výstupu. Pokud je kolík v režimu „Výstup“, pak 1 a 0 určí přítomnost stejných signálů na výstupu. Pokud je kolík v režimu „Input“, 1 připojí pull-up rezistor (stejný jako výše uvedený INPUT_PULLUP), pokud 0 je stav s vysokou impedancí (analog INPUT);

  • PINB je registr pro čtení. V souladu s tím obsahuje informace o aktuálním stavu pinů portů (logická jednotka nebo nula).

  • DDRB - registr směru portu. Tím označíte mikrokontroléru, zda je port vstupem nebo výstupem, s „1“ výstupem a „0“ vstupem.

Místo písmene „B“ mohou existovat i další názvy podle názvů portů, např. PORTD nebo PORTC jiné příkazy pracují podobně.

Blikáme LED, nahrazujeme standardní funkci digitalWrite (). Nejprve si připomeňme, jak vypadá původní příklad z knihovny Arduino IDE.

Blikající kód Arduino LED

Toto je kód známého „blikání“, který ukazuje blikání LED vestavěné do desky.

Správa pinů

Poznámky vysvětlují kód. Logika této práce je následující.

Příkaz PORTB B00100000 uvádí PB5 do stavu logické jednotky, podívejte se a ty obrázky a tabulka níže jsou umístěny a vidíme, že PB5 odpovídá 13 pinům Arduiny.

Písmeno "B" před čísly znamená, že hodnoty píšeme binární formou. Číslování v binárních číslech jde zprava doleva, tj. zde je jednotka v šestém bitu od pravého okraje bitu, který říká mikrokontroléru o interakci se stavem šestého bitu registru B registru (PB5). Níže uvedená tabulka ukazuje strukturu portu D, je podobná a je uvedena jako příklad.

Struktura přístavu D

Hodnotu můžete nastavit nikoli v binární, ale v hexadecimální podobě, například proto otevřeme kalkulačku oken a v režimu „ZOBRAZENÍ“ vyberte možnost „Programátor“.

Kalkulačka systému Windows

Zadejte požadované číslo:

Režim kalkulačky programátoru

A klikněte na HEX:

Překlad čísel na kalkulačce

V tomto případě vše převedeme na Arduino IDE, ale namísto předpony „B“ to bude „0x“.

Přenos čísla v Arduino IDE

S tímto vstupem je však problém. Pokud máte něco připojeného k jiným pinům, zadejte příkaz jako B00010000 - vynulujete všechny piny kromě 13 (PB5). Můžete zadat data pro každý pin samostatně. Vypadá to takto:

Zadávání dat do každého kolíku

Takový záznam se může zdát nepochopitelný, pojďme na to přijít.

Parsování záznamu

Jedná se o logickou operaci sčítání, | = znamená přidat něco k obsahu portu.

Logická operace sčítání

To znamená, že musíte do registru přidat slovo 8 bitů s jednotkou posunutou o 5 bitů - v důsledku toho, pokud se 11000010 ukáže jako 110 1101010. V tomto příkladu je vidět, že se změnil pouze PB5, zbývající bity tohoto registru zůstaly nezměněny, stejně jako Stav pinů mikrokontroléru zůstal nezměněn.

S logickým sčítáním však vyvstává problém - jednotku nelze změnit na nulu, protože:

0+0=1

1+0=1

0+1=1

Logické množení a inverze nám pomohou:

Logické násobení a převrácení

& = znamená vynásobit obsah portu konkrétním číslem.

 

Násobení obsahu portu číslem

A toto je číslo, které vynásobíme. Znak „~“ označuje inverzi. V našem případě je obrácená jednotka nulová. To znamená, že vynásobíme obsah portu nulou a posuneme o 5 bitů. Například to bylo 10110001, stalo se 10100001. Zbývající bity zůstaly nezměněny.

Vynásobte obsah portu nulou posunutou o 5 bitů

Totéž lze provést pomocí operace invertování (^):

Při čtení z portů se analog digitalRead () provádí pomocí registru PIN, v praxi to vypadá takto:

Čtení z portů

Zde zkontrolujeme, zda se výraz v závorkách rovná skutečnému stavu portů, tj. podobně pokud jsme napsali if (digitalRead (12) == 1).


Závěr

Proč existují takové problémy se správou portů, pokud můžete používat standardní pohodlné funkce? Je to všechno o rychlosti a velikosti kódu. Při použití druhé metody popsané v článku je velikost kódu výrazně snížena a rychlost se zvyšuje o několik řádů. Standardní digitalWrite () byl proveden v 1800 μs a zaznamenáván přímo do portu v 0,2 μs, a digitalRead () v 1900 μs a také se stal v 0,2 μs. Tato metoda řízení byla nalezena na otevřených prostorech sítě a je často nalezena v kódu. dokončené projekty.

Viz také na i.electricianexp.com:

  • Připojení a programování Arduino pro začátečníky
  • Jak připojit inkrementální kodér k Arduino
  • Mikrokontroléry PIC pro začátečníky
  • Dálkové ovládání mikrokontroléru: IR Remote, Arduino, ESP8266, 433 ...
  • Měření teploty a vlhkosti na Arduino - výběr způsobů

  •  
     
    Komentáře:

    # 1 napsal: Kipovets | [citovat]

     
     

    "Ale s logickým sčítáním se objevuje problém - jednotku nelze změnit na nulu, protože:

    0 + 0 = 1 "(c)

    Malý dohled: 0 + 0 = 0.

     
    Komentáře:

    # 2 napsal: chugou | [citovat]

     
     

    Kipovets, pravděpodobně chtěl říct:

    1 + 1 = 1

     
    Komentáře:

    # 3 napsal: | [citovat]

     
     

    Kipovets,
    Banální překlep! Vidíte, jak je dobré, že na našem portálu sedí specialisté! Musíte vytvořit pouze vhodný obsah!

     
    Komentáře:

    # 4 napsal: Serg | [citovat]

     
     

    V závěrečné části je uvedeno PORTB | = 1 << 5 ... if (digitalRead (12) == 1). Ale 5 pinů portu B, je to 13 pinů arduina. Nebo se mýlím?

     
    Komentáře:

    # 5 napsal: p-a-h-a | [citovat]

     
     

    Pokud (PINB == B00010000) {} nenípodobné, jako kdybychom napsali (digitalRead (12) == 1)
    spíše analogové
    (digitalRead (12) == 1) &&(digitalRead (13) == 1) &&(digitalRead (14) == 1) &&(digitalRead (15) == 1) &&(digitalRead (11) == 1) ... a tak 8 pinů portů

    Zde potřebujete buď toto:
    pokud (
    ! (~ PORTB & (1 << PB4))) {} //se vrací0 nebo 1
    buď takto:
    pokud (PORTB & (1 << PB4)) {} // vrátí posunutou jednotku = 16, DEC
    buď takto:
    pokud (
    bit_is_set (PORTB, 4)) {}// vrátí posunutou jednotku = 16, DEC