kategorier: Mikrokontrollkretser
Antall visninger: 41940
Kommentarer til artikkelen: 5

Metoder for å lese og administrere Arduino I / O-porter

 

For å samhandle med omverdenen, må du konfigurere utgangene til mikrokontrolleren for å motta eller overføre et signal. Som et resultat vil hver pinne fungere i inn- og utgangsmodus. Det er to måter å gjøre dette på hvert Arduino-brett du elsker, nøyaktig hvordan du lærer av denne artikkelen.

Metoder for å lese og administrere Arduino I / O-porter

Metode én - standardspråket for Arduino IDE

Det vet alle Arduino Den er programmert i C ++ med litt tilpasning og forenklinger for nybegynnere. Det heter Wiring. Til å begynne med er alle arduino-porter definert som innganger, og det er ikke nødvendig å spesifisere dette i koden.

Porter skrives vanligvis i variabelinitieringsfunksjonen:

ugyldig oppsett ()
{
// kode
}

For å gjøre dette, bruk pinMode-kommandoen, den har en ganske enkel syntaks, angi først portnummeret, deretter rollen, atskilt med kommaer.

pinMode (nomer_porta, naznachenie)

Med denne kommandoen blir den interne kretsløpet til mikrokontrolleren konfigurert på en spesifikk måte.

Det er tre modus der porten kan fungere: INPUT - inngang, i denne modusen oppstår lese data fra sensorer, knappestatus, analogt og digitalt signal. Porten ligger i den såkalte høyimpedansetilstand, med enkle ord - inngangen har høy motstand. Denne verdien settes for eksempel 13 pinner på brettet, om nødvendig, som følger:

pinMode (13, INPUT);

UTGANG - utgang, avhengig av kommandoen som er foreskrevet i koden, tar porten en verdi på en eller null. Utgangen blir en slags kontrollert kraftkilde og produserer en maksimal strøm (i vårt tilfelle 20 mA og 40 mA på toppen) til belastningen som er koblet til den. For å tilordne en port som en utgang til Arduino må du angi:

pinMode (13, UTGANG);

INPUT_PULLUP - porten fungerer som en inngang, men den såkalte kobles til den. 20 kΩ opptrekksmotstand.

De betingede interne kretsløpene til porten i denne tilstanden er vist nedenfor. Et trekk ved denne inngangen er at inngangssignalet oppfattes som omvendt (“enheten” ved inngangen oppfattes av mikrokontrolleren som “null”). I denne modusen kan du ikke bruke eksterne opptrekksmotstander når du jobber med knapper.

pinMode (13, INPUT_PULLUP);

Inngang opptrekksmotstand

Data mottas fra portene og overføres til dem av kommandoene:

  • digitalWrite (pin, value) - konverterer utgangspinnen til en logisk henholdsvis 1 eller 0, 5V spenning vises eller forsvinner ved utgangen, for eksempel digitalWrite (13, HIGH) - leverer 5 volt (logisk enhet) til 13 pins, og digitalWrite (13, low) ) - oversetter 13 pinner til en tilstand av logisk null (0 volt);

  • digitalRead (pin) - leser verdien fra inngangen, eksempel digitalRead (10), leser signalet fra 10 pins;

  • analogRead (pin) - leser et analogt signal fra en analog port, du får en verdi i området 0 til 1023 (i en 10-bit ADC), et eksempel er analogRead (3).


Metode to - administrer porter gjennom Atmega-registre og fremskynder kode

Slik kontroll er selvfølgelig enkel, men i dette tilfellet er det to ulemper - større minneforbruk og dårlig ytelse når du jobber med porter. Men husk hva er Arduino, uavhengig av opsjonsbrett (uno, mikro, nano)? Først av alt, dette mikrokontroller AVR-familie ATMEGA, nylig brukt MK atmega328.

I Arduino IDE kan du programmere C AVR-språket som er hjemmehørende i denne familien, som om du jobbet med en egen mikrokontroller. Men først ting først. For å administrere Arduino-porter på denne måten, må du først vurdere følgende illustrasjon nøye.

Atmega168 mikrokontroller-porter

Kanskje noen vil tydeligere undersøke portene i denne formen (det samme på figuren, men i en annen design):

Atmega328 mikrokontroller-porter

Her ser du korrespondansen til konklusjonene fra Arduino og navnene på havnene i Atmega. Så vi har tre porter:

  • PORTB;

  • PORTC;

  • PORTD.

Basert på bildene som er vist, samlet jeg en korrespondansetabell mellom havnene i Arduino og Atmega, det vil være nyttig for deg i fremtiden.

Konkordansetabell over havner Arduino og Atmega

Atmega har tre 8-biters registre som kontrollerer tilstanden til portene, for eksempel vil port B finne ut deres formål ved å tegne analogier med standard ledningsverktøy som er beskrevet i begynnelsen av denne artikkelen:

  • PORTB - Administrer utgangsstatus. Hvis pinnen er i "Output" -modus, bestemmer 1 og 0 tilstedeværelsen av de samme signalene ved utgangen. Hvis pinnen er i "Input" -modus, kobler 1 en opptrekksmotstand (samme som INPUT_PULLUP omtalt ovenfor), hvis 0 er en høyimpedansetilstand (analog INPUT);

  • PINB er et leseregister. Følgelig inneholder den informasjon om strømtilførselenes nåværende tilstand (logisk enhet eller null).

  • DDRB - portretningsregister. Med det indikerer du for mikrokontrolleren hva porten er som inngang eller utgang, med "1" en utgang og "0" en inngang.

I stedet for bokstaven “B”, kan det være andre i henhold til portene, for eksempel PORTD eller PORTC andre kommandoer fungerer på samme måte.

Vi blinker i LED, bytter ut standard digitalWrite () -funksjonen. La oss først huske hvordan det originale eksemplet fra Arduino IDE-biblioteket ser ut.

Arduino LED blinkende kode

Dette er koden til den velkjente “blinkingen”, som viser blinkingen av LED-en som er innebygd i brettet.

Pin ledelse

Kommentarene forklarer koden. Logikken i dette arbeidet er som følger.

Kommandoen PORTB B00100000 setter PB5 i tilstanden til en logisk enhet, utseende, og bildene og tabellen nedenfor er plassert, og vi ser at PB5 tilsvarer 13 pin Arduina.

Bokstaven "B" foran tallene indikerer at vi skriver verdiene i binær form. Nummerering i binær går fra høyre til venstre, dvs. her er enheten i den sjette biten fra høyre kant av biten, som forteller mikrokontrolleren om samspillet med tilstanden til den sjette biten i port B-registeret (PB5). Tabellen nedenfor viser strukturen til port D, den er lik og er gitt som et eksempel.

Port D-struktur

Du kan stille verdien ikke i binær, men i heksadesimal form, for eksempel, for dette åpner vi Windows-kalkulatoren, og i "VIEW" -modus velger du "Programmer" -alternativet.

Windows-kalkulator

Tast inn ønsket nummer:

Programmerer kalkulator modus

Og klikk på HEX:

Oversettelse av tall på en kalkulator

I dette tilfellet overfører vi alt dette til Arduino IDE, men i stedet for prefikset "B" vil det være "0x".

Nummeroverføring i Arduino IDE

Men med dette innspillet er det et problem. Hvis du har noe koblet til andre pinner, skriver du inn en kommando som B00010000 - vil du tilbakestille alle pinner bortsett fra 13 (PB5). Du kan legge inn data for hver pin enkeltvis. Det vil se slik ut:

Legger inn data i hver pin

En slik post kan virke uforståelig, la oss finne ut av det.

Analyser en post

Dette er en logisk tilleggsoperasjon, | = betyr å legge til noe i innholdet i porten.

Logisk tilleggsoperasjon

Dette betyr at du må legge til et ord på 8 biter i registeret med en enhet forskjøvet med 5 biter - som et resultat, hvis 11000010 viser seg å være 110.110.010. I dette eksemplet kan det sees at bare PB5 har endret seg, de gjenværende bitene i dette registeret har holdt seg uendret, så vel som Tilstanden til mikrokontrollpinnene forble uendret.

Men med logisk tillegg oppstår det et problem - du kan ikke gjøre enheten til null, fordi:

0+0=1

1+0=1

0+1=1

Logisk multiplikasjon og inversjon vil hjelpe oss:

Logisk multiplikasjon og invertering

& = betyr multiplisere innholdet i porten med et spesifikt tall.

 

Multiplisere portinnholdet med et nummer

Og dette er tallet vi multipliserer med. “~” -Tegnet indikerer inversjon. I vårt tilfelle er den omvendte enheten null. Det vil si at vi multipliserer innholdet i porten med null, forskjøvet med 5 biter. For eksempel var det 10110001, det ble 10100001. De resterende bitene forble uendret.

Multipliser innholdet i porten med null forskjøvet med 5 biter

Det samme kan gjøres ved hjelp av inverter-operasjonen (^):

Lesing fra porter, analogen til digitalRead () utføres ved hjelp av PIN-registeret, i praksis ser det slik ut:

Les fra portene

Her sjekker vi om uttrykket i parentes er lik portens reelle tilstand, d.v.s. på samme måte hvis vi skrev if (digitalRead (12) == 1).


konklusjon

Hvorfor er det slike vanskeligheter med portstyring hvis du kan bruke praktiske standardfunksjoner? Det handler om hastighet og kodestørrelse. Når du bruker den andre metoden, diskutert i artikkelen, reduseres kodestørrelsen betydelig, og hastigheten øker med flere størrelsesordener. Standard digitalWrite () ble utført i 1800 μs, og ble registrert direkte til porten i 0,2 μs, og digitalRead () i 1900 μs, og ble også i 0,2 μs. Denne kontrollmetoden ble funnet på de åpne områdene i nettverket og finnes ofte i kode. ferdige prosjekter.

Se også på elektrohomepro.com:

  • Koble til og programmerer Arduino for nybegynnere
  • Hvordan koble inkrementell koding til Arduino
  • PIC-mikrokontrollere for nybegynnere
  • Microcontroller Remote Control: IR Remote, Arduino, ESP8266, 433 ...
  • Måling av temperatur og fuktighet på Arduino - et utvalg av måter

  •  
     
    kommentarer:

    Nr. 1 skrev: Kipovets | [Cite]

     
     

    "Men med logisk tillegg oppstår det et problem - du kan ikke gjøre enheten til null, fordi:

    0 + 0 = 1 "(c)

    Lite tilsyn: 0 + 0 = 0.

     
    kommentarer:

    Nr. 2 skrev: vaskemidler | [Cite]

     
     

    Kipovets, ville han sannsynligvis si:

    1 + 1 = 1

     
    kommentarer:

    Nr. 3 skrev: | [Cite]

     
     

    Kipovets,
    Banal skrivefeil! Du ser hvor bra det er at spesialister sitter på vår portal! Du må lage bare passende innhold!

     
    kommentarer:

    Nr. 4 skrev: Serg | [Cite]

     
     

    I den siste delen står det PORTB | = 1 << 5 ... if (digitalRead (12) == 1). Men 5 pin port B, det er 13 pin arduino. Eller tar jeg feil ?!

     
    kommentarer:

    Nr. 5 skrev: p-a-h-en | [Cite]

     
     

    Hvis (PINB == B00010000) {} ikke er detligner på hvis vi skrev hvis (digitalRead (12) == 1)
    heller analog
    (digitallesning (12) == 1) &&(digitallesning (13) == 1) &&(digitallesning (14) == 1) &&(digitallesning (15) == 1) &&(digitalRead (11) == 1) ... og så 8 portpinner

    Her trenger du enten dette:
    hvis (
    ! (~ PORTB & (1 << PB4))) {} //avkastning0 eller 1
    enten som dette:
    hvis (PORTB & (1 << PB4)) {} // returnerer forskjøvet enhet = 16, DEC
    enten som dette:
    hvis (
    bit_is_set (PORTB, 4)) {}// returnerer forskjøvet enhet = 16, DEC