kategória: Mikrovezérlő áramkörök
Megtekintések száma: 41940
Megjegyzések a cikkhez: 5

Az Arduino I / O portok olvasásának és kezelésének módszerei

 

A külvilággal való interakcióhoz be kell állítania a mikrovezérlő kimeneteit a jel fogadására vagy továbbítására. Ennek eredményeként minden tű bemeneti és kimeneti módban működik. Kétféle módon lehet ezt megtenni minden szeretett Arduino táblán, pontosan hogyan tanulhatja meg ezt a cikket.

Az Arduino I / O portok olvasásának és kezelésének módszerei

1. módszer - az Arduino IDE standard nyelve

Mindenki tudja Arduino C ++ -ba van beprogramozva, némi adaptációval és egyszerűsítéssel kezdőknek. Huzalozásnak hívják. Kezdetben az összes arduino portot bemenetekként definiálták, és ezt nem kell megadni a kódban.

A portokat általában a változó inicializáló függvényben írják:

érvénytelen beállítás ()
{
// kód
}

Erre a pinMode parancsot használják, meglehetősen egyszerű szintaxissal, először a portszámot jelzik, majd a szerepét vesszővel választják el.

pinMode (nomer_porta, naznachenie)

Ezzel a paranccsal a mikrovezérlő belső áramköre meghatározott módon konfigurálható.

Három üzemmódban működhet a port: INPUT - bemenet, ebben az üzemmódban fordul elő az érzékelők adatainak olvasása, gomb állapot, analóg és digitális jel. A kikötő úgynevezett magas impedanciaállapot, egyszerű szavakkal - a bemenetnek nagy ellenállása van. Ezt az értéket állíthatjuk be például a tábla 13 tűjére, ha szükséges, az alábbiak szerint:

pinMode (13, INPUT);

OUTPUT - kimenet, a kódban előírt parancs függvényében a port értéke egy vagy nulla. A kimenet egyfajta vezérelt áramforrássá válik, és maximális áramot generál (a mi esetünkben 20 mA és 40 mA a csúcson) a hozzá kapcsolt terheléshez. Ahhoz, hogy egy portot kimenetként rendeljen Arduino-hoz, be kell írnia:

pinMode (13, OUTPUT);

INPUT_PULLUP - a port bemenetként működik, de az úgynevezett csatlakozik hozzá. 20 kΩ húzó ellenállás.

A port feltételes belső áramköre ebben az állapotban az alább látható. Ennek a bemenetnek az a jellemzője, hogy a bemeneti jelet fordítottnak tekinti (a bemeneten lévő „egységet” a mikrokontroller „nullának” érzékeli). Ebben az üzemmódban nem használhat külső húzó ellenállást ha gombokkal dolgozik.

pinMode (13, INPUT_PULLUP);

Bemeneti pull-up ellenállás

Az adatokat a portok fogadják és továbbítják számukra a következő parancsokkal:

  • digitalWrite (tű, érték) - konvertálja a kimeneti tűt logikai 1 vagy 0 értékre, 5V feszültség jelenik meg vagy eltűnik a kimenetnél, például digitalWrite (13, HIGH) - 5 voltos (logikai egység) 13 érintkezőre, és digitalWrite (13 alacsony) ) - átalakítja a 13 tűt logikai nulla állapotba (0 volt);

  • digitalRead (pin) - beolvassa az értéket a bemenetből, például digitalRead (10), leolvassa a jelet 10 tűből;

  • analogRead (pin) - analóg jelet olvas az analóg portról, 0 és 1023 közötti értéket kap (egy 10 bites ADC-n belül), egy példa az analogRead (3).


Második módszer - kezelje a portokat Atmega regiszterek segítségével és gyorsítsa fel a kódot

Az ilyen vezérlés természetesen egyszerű, de ebben az esetben két hátránya van - nagyobb memória-fogyasztás és gyenge teljesítmény a portokkal történő munkavégzés során. De ne feledje, mi az Arduino, függetlenül az opcionális táblától (uno, mikro, nano)? Először is ezt mikrokontroller AVR család ATMEGA, nemrégiben használt MK atmega328.

Az Arduino IDE-ben beprogramozhatja a C AVR nyelvét ennek a családnak az anyanyelvén, mintha külön mikrovezérlővel dolgozna. De az első dolgok először. Az Arduino portok ilyen módon történő kezeléséhez először alaposan meg kell fontolnia a következő ábrát.

Atmega168 mikrokontroller portok

Talán valaki egyértelműbben megvizsgálja a portokat ebben a formában (ugyanaz az ábrán, de másképp):

Atmega328 mikrokontroller portok

Itt látható az Arduino következtetéseinek és az Atmega kikötőinek a neve. Tehát 3 portunk van:

  • PORTB;

  • PORTC;

  • PORTD.

A bemutatott képek alapján összeállítottam egy táblázatot az Arduino és az Atmega kikötői között, ez hasznos lesz a jövőben is.

Arduino és Atmega kikötők megfelelőségi táblázata

Az Atmega-nak három 8 bites regisztere van, amelyek ellenőrzik a portok állapotát, például a B port megmutatja céljaikat a cikk elején ismertetett szabványos huzalozási eszközök analógiájának rajzolásával:

  • PORTB - A kimeneti állapot kezelése. Ha a tüske "Kimeneti" módban van, akkor az 1 és a 0 meghatározza ugyanazon jelek jelenlétét a kimeneten. Ha a csap „bemeneti” módban van, akkor az 1 csatlakoztat egy húzó ellenállást (ugyanaz, mint a fent tárgyalt INPUT_PULLUP), ha 0 nagy impedanciájú állapot (az INPUT analógja);

  • A PINB olvasott regiszter. Ennek megfelelően információkat tartalmaz a port csapok jelenlegi állapotáról (logikai egység vagy nulla).

  • DDRB - portirányító regiszter. Ezzel megmutatja a mikrovezérlőnek, hogy mi a port bemenetként vagy bemenetként, „1” kimenettel és „0” bemenettel.

A „B” betű helyett a portok neve szerint más is lehet, például a PORTD vagy a PORTC egyéb parancsok hasonlóan működnek.

Villog a LED, kicseréljük a szokásos digitalWrite () funkciót. Először emlékezzünk vissza az eredeti példának az Arduino IDE könyvtárból.

Arduino LED villogó kód

Ez a jól ismert „villogás” kódja, amely a táblába épített LED villogását mutatja.

Tű kezelése

A megjegyzések magyarázzák a kódot. A munka logikája a következő.

A PORTB B00100000 parancs a PB5-et logikai egység állapotába helyezi, nézd meg, és ezek a képek és az alábbi táblázat találhatók, és látjuk, hogy a PB5 megfelel az Arduina 13 pin-nek.

A számok előtti "B" betű azt jelzi, hogy az értékeket bináris formában írjuk. A bináris számozás jobbról balra megy, azaz itt az egység a hatodik bitben van a bit jobb szélétől, amely elmondja a mikrovezérlőnek a B port regiszter (PB5) hatodik bitjével való kölcsönhatásról. Az alábbi táblázat a D port felépítését mutatja, hasonló, és példaként szolgál.

D port szerkezete

Az értéket nem binárisan, hanem hexadecimális formában állíthatja be, ehhez például megnyitjuk a Windows kalkulátort, és „VIEW” módban válassza a „Programmer” lehetőséget.

Windows számológép

Írja be a kívánt számot:

Programozó kalkulátor mód

És kattintson a HEX-re:

Számok fordítása a számológépen

Ebben az esetben mindezt átvisszük az Arduino IDE-re, de a "B" előtag helyett "0x" lesz.

Számátvitel az Arduino IDE-ben

De ezzel a bemenettel probléma merül fel. Ha van valami csatlakoztatva más tűkhöz, akkor olyan parancs beírásával, mint a B00010000 - minden csapot visszaállít, kivéve a 13-at (PB5). Az egyes PIN-kódokhoz külön-külön adhat meg adatokat. Így néz ki:

Adatok bevitele minden PIN-kódba

Egy ilyen rekord érthetetlennek tűnhet, derítsük ki.

Rekord elemzése

Ez logikus addíciós művelet, | = azt jelenti, hogy valamit hozzáadunk a port tartalmához.

Logikai addíciós művelet

Ez azt jelenti, hogy 8 bites szót kell hozzáadnia a nyilvántartásba egy 5 bittel eltolt egységgel - ennek eredményeként, ha az 11000010 110 110 010 értékű lesz. Ebben a példában látható, hogy csak a PB5 megváltozott, a regiszter többi bitje változatlan maradt, valamint A mikrovezérlő csapok állapota változatlan maradt.

De logikai kiegészítéssel probléma merül fel - az egységet nem lehet nullára változtatni, mert:

0+0=1

1+0=1

0+1=1

A logikai szorzás és az inverzió segítségünkre lesz:

Logikai szorzás és invertálás

& = azt jelenti, hogy meg kell szorozni a port tartalmát egy adott számmal.

 

A port tartalmát megszorozzuk egy számmal

És ez az a szám, amellyel megszorozzuk. A „~” jel inverziót jelez. Esetünkben a fordított egység nulla. Vagyis megszorozzuk a port tartalmát nullával, 5 bittel eltolva. Például 10110001 volt, 10100001 lett. A fennmaradó bit változatlan maradt.

Szorozzuk meg a port tartalmát nullával, 5 bittel eltolva

Ugyanezt lehet tenni az invert művelet (^) használatával:

A portokból történő olvasáskor a digitalRead () analógját a PIN-regiszter segítségével hajtjuk végre, a gyakorlatban így néz ki:

Olvassa el a portokról

Itt megvizsgáljuk, hogy a zárójelben szereplő kifejezés megegyezik-e a portok valós állapotával, azaz hasonlóan, ha írtunk, ha (digitalRead (12) == 1).


következtetés

Miért vannak ilyen nehézségek a portkezelésnél, ha használhat szabványos kényelmes funkciókat? A sebességről és a kódméretről szól. A cikkben tárgyalt második módszer használatakor a kódméret jelentősen csökken, és a sebesség több nagyságrenddel növekszik. A szokásos digitalWrite () programot 1800 μs-ben hajtották végre, és közvetlenül a portba rögzítették 0,2 μs-ban, a digitalRead () -et 1900 μs-ban, és szintén 0,2 μs-ra váltották fel. Ezt a vezérlési módszert a hálózat szabad területein találták meg, és gyakran kódban találhatók meg. kész projektek.

Lásd még az i.electricianexp.com oldalon:

  • Az Arduino csatlakoztatása és programozása kezdőknek
  • Hogyan lehet csatlakoztatni az inkrementális kódolót az Arduino-hoz
  • PIC mikrovezérlők kezdőknek
  • Mikrovezérlő távirányító: IR távirányító, Arduino, ESP8266, 433 ...
  • Hőmérséklet és páratartalom mérése az Arduinón - számos módszer

  •  
     
    Megjegyzések:

    # 1 írta: Kipovets | [Cite]

     
     

    "De logikai hozzáadásával probléma merül fel - az egységet nem lehet nullára változtatni, mert:

    0 + 0 = 1 "(c)

    Kis felügyelet: 0 + 0 = 0.

     
    Megjegyzések:

    # 2 írta: chugou | [Cite]

     
     

    Kipovets, valószínűleg azt akarta mondani:

    1 + 1 = 1

     
    Megjegyzések:

    # 3 írta: | [Cite]

     
     

    Kipovets,
    Banális gépelés! Látja, milyen jó, hogy a szakemberek ülnek portálunkon! Csak a megfelelő tartalmat kell készítenie!

     
    Megjegyzések:

    # 4 írta: Serg | [Cite]

     
     

    A végső részben PORTB | = 1 <5 = if van (digitalRead (12) == 1). De 5 tű a B port, ez 13 tű arduino. Vagy tévedek ?!

     
    Megjegyzések:

    # 5 írta: p-a-H-a | [Cite]

     
     

    Ha (PINB == B00010000) {} nemhasonlóan, ha if írta (digitalRead (12) == 1)
    inkább analóg
    (digitalRead (12) == 1) &&(digitalRead (13) == 1) &&(digitalRead (14) == 1) &&(digitalRead (15) == 1) &&(digitalRead (11) == 1) ... és így 8 port csap

    Itt szükséged van erre:
    ha (
    ! (~ PORTB & (1 << PB4))) {} //visszatér0 vagy 1
    akár így:
    ha (PORTB & (1 << PB4)) {} // visszatér az eltolt egység = 16, DEC
    akár így:
    ha (
    bit_is_set (PORTB, 4)) {}// visszaadja az eltolt egységet = 16, DEC