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.

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

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.
Kanskje noen vil tydeligere undersøke portene i denne formen (det samme på figuren, men i en annen design):

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.

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.

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

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.

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.

Tast inn ønsket nummer:

Og klikk på HEX:

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

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:

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

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

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:

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

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.

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:

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
: