Porty jako cyfrowe wejścia wyjścia ogólnego przeznaczenia w µC AVR.

Porty jako cyfrowe wejścia wyjścia ogólnego przeznaczenia w µC AVR.
Oceń opis

 

typowe wejcie (PIN) jednostki MCU AVR ATtiny i ATmega, schemat logiczny Warto by usystematyzować sobie wiadomości na temat: konfiguracji, praktycznego używania oraz funkcjonalności potów IO w mikrokontrolerach AVR. Wydawało by się ze sprawa jest błaha, bo dotyczy pinów, które mogą być wejściem lub wyjściem. W rzeczywistości jak to widać na schemacie otrzymana funkcjonalność jest skomplikowana fizycznie, lecz niezawikłana w używaniu jeśli dla prawidłowego funkcjonowania/obsługi tego bloku posiada się stosowną porcję wiedzy. Nie należy też zapominać o fakcie, że z tym blokiem powiązana jest funkcjonalność przerwań zewnętrznych asynchronicznych i synchronicznych.
W końcu jak by nie było jest to podstawowe dobrodziejstwo, dzięki któremu µC może komunikować się ze światem zewnętrznym, i przetwarzać odpowiednio zebrane informacje czy też sterować peryferiami zewnętrznymi.

Sięgając pamięcią daleko wstecz przypominam sobie gdy mnóstwo czasu poświęciłem na rozgryzienie błędnego funkcjonowania powstającego sterownika z tytułu pomyłki w obsłudze rejestrów związanych bezpośrednio z tym tematem.  😀 i pewno nie tylko ja jeden.

Podstawowa funkcjonalność wyprowadzenia – PIN-u.

Na pewnym etapie wtajemniczenia nie jest dla nikogo nowością posiadanie przez µC trzech rejestrów funkcjonalnych, które odpowiadają za pracę i kierunek przepływu danych, jak i określają możliwość zastosowania rezystora pull-up.  Mowa tu o rejestrach:
DDRx (konfiguracyjnym – decyduje czy pin jest wejściem czy wyjściem),
PORTx
 (wyjściowym – wartości wymuszone przez MCU),
PINx (wejściowym – rzeczywiste wartości na końcówkach).
W tym momencie dopowiedzieć można o znaczniku PUD (Pull-Up Disable),  odpowiedzialnym za globalne odłączenie (zablokowanie) rezystorów podciągających po zapisaniu do niego wartości 1. Może on być umieszczony w rejestrze MCUCR dla rodziny ATtiny i rejestrach SFIOR lub MCUCR dla rodziny ATmega. Ponieważ co nieco o rezystorach pull-up już pisałem więc tego wątku nie będę teraz kontynuować.

Wracając do naszych rejestrów przypomnieć można, że zajmują część pamięci noszącej miano Specjal Function Register – SFR. Przestrzeń pamięci wejścia wyjścia może przykładowo wynosić 96B dla rodziny ATtiny i 256B dla rodziny ATmega.

Jak się ustrzec przed pomyłką i popełnieniem błędu w odróżnieniu nazw i funkcjonalności wybranych rejestrów? W sposób stosunkowo prosty … PORT, O – jak output, PIN, I – jak input. I po strachu i zawrocie głowy  😛

W trakcie pracy µC możemy zmieniać funkcjonalność użytkową pinów, w razie potrzeby raz może być wejściem, a za chwilkę wyjściem. Konfigurację tą można zmieniać dowolną ilość razy podczas funkcjonowania urządzenia finalnego, które tworzymy.

Konfigurujemy piny.

By zdefiniować czy wyprowadzenie ma pełnić rolę wejścia lub wyjścia należy posłużyć się znacznikiem DDx rejestru DDRx. Czyli jeśli chcemy by wybrany pin był wejściem odpowiedni bit rejestru DDRx ustawiamy na zero. Jeśli ma być wyjściem zapisujemy wartość 1.

I znowu jak się nie pomylić z określeniem parametru wyjścia i wejścia? Teraz by było zabawnie, sprawę sprowadzę do czynności starej jak świat, dzięki której trwamy – „bzykanie” i sprzętów doń niezbędnych.
Więc wartość zero  „0″ niech symbolizuje dziurkę (cipkę) czyli wejście :mrgreen: wartość 1 niech symbolizuje wtyczkę czyli fifolka. Wszak często spotyka się z określeniem wyprowadzeń jako male i female. Myślę, że po takiej lekcji już nikomu się nie będzie myliło kiedy wstawić 1 a kiedy 0.  😀

Najczęściej przez takie przykłady – na wesoło zapamiętujemy coś dozgonnie. Bo „głupota” trzyma się nas sama.  😆 Ale może też uczyć.
Kiedyś gdy miałem naście lat, podobnie kolega wytłumaczył mi jak nie mylić symbolu tranzystora PNP z NPN i pomogło niesamowicie  😉 Pamiętam do dziś, i nigdy się już nie pomyliłem. Powiedział tak: wyobraź sobie, że ta strzałka skierowana do środka „pieprzy” tranzystor i dlatego jest on typu PNP  :mrgreen: a ten drugi to NPN.

Jak to zrobić w środowisku bascom AVR?

Do wyboru mamy kilka sposobów:

Osobiście stosuję przykład 4, a zaraz za nim aliasy z przyjaznymi nazwami do użytku w kodzie.

Użycie pinów w kodzie zależne od kierunku przepływów danych w nawiązaniu do poprzednich przykładów konfiguracji może wyglądać następująco:.

Czwarty przykład pokazuje prostotę obsługi pinów bez konieczności pamiętania o zadeklarowanych kierunkach przepływu danych, przez zastosowanie etykiety o specyficznej nazwie.

Odskocznia do Bascom 8051.

Natomiast BASCOM 8051 rządzi się swoimi prawami. W tej wersji środowiska nie przeprowadzamy deklaracji kierunku, gdyż ta rodzina µC posiada zupełnie inną architekturę. Przy odwołaniach nie ma też dwóch typów rejestrów, zdefiniowanych zależnie od tego czy pin jest wejściem czy wyjściem.

Przy stosowaniu wewnętrznych rezystorów podciągających Pull-up warto zaglądnąć do notki katalogowej wybranego µC z rodziny 8051, czy aby na pewno wybrany pin w takowy jest wyposażony. Standardowo piny z podłączonym komparatorem nie posiadają takiej funkcjonalności. W większych µC tej rodziny, rezystorów Pull-up pozbawiony jest port P0.
Bufory wyjściowe portu P1 i P3 (dotyczy AT89C2051, AT89C4051) pozwalają na ciągły przepływ prądu 20mA i mogą bezpośrednio sterować wyświetlacze LED.

Dodatkowe funkcjonalności.

Praktycznie każdy pin dowolnego µC posiada dodatkową funkcjonalność. Wynika to z faktu, iż w układzie scalonym siedzi zabudowanych wiele bloków funkcjonalnych, a liczba wyprowadzeń jest ograniczona.  Dlatego układ został opracowany tak by można było decydować o funkcjonalności wyprowadzenia (budowa nadmiarowa, gdyż bardzo często skomplikowane peryferia są pozostawione odłogiem). Dzieje się to za sprawą wewnętrznych multiplekserów i rejestrów sterujących. Akurat te czynności (przełączenie funkcji) odbywają się automatycznie po zadeklarowaniu chęci użytkowania danego modułu wewnętrznego. Dla przypomnienia – funkcjonalności pinów można zmieniać w kodzie w trakcie działania układu.
Warto pamiętać o tym, że jeśli uaktywnimy jakiś blok funkcjonalny na danym pinie, ustawianie znaczników PORTxn i DDRxn jest najczęściej ignorowane, a linię kontroluje wewnętrzny układ peryferyjny. A po inicjacji MCU wartością domyślną dla kierunku przepływu danych jest zero (piny są wejściami).

Przerwania zewnętrzne.

Przerwania zewnętrzne wyzwalane są dzięki specjalnej funkcjonalności pinów, określanej symbolem INT lub PCIN (pin change interrupts).
Przerwanie INT z uwagi na możliwość działania synchronicznego (złożonej architektury) zazwyczaj przypisane jest do niewielkiej liczby wyprowadzeń  – 1 do 8 w zależności od stopnia skomplikowania i rodziny µC.
W tym przypadku mamy do dyspozycji szeroki wybór parametru wyzwalającego – zbocze opadające lub narastające, poziom wysoki lub niski (poziom napięcia, jakakolwiek zmiana stanu logicznego).
Funkcjonalność przerwania PCINT pojawiła się stosunkowo niedawno (w nowszych µC, na dziś dzień jest ulepszona o rejestr PCMSK) i posiada ją większość wyprowadzeń µC. Dzięki temu możemy samodzielnie decydować, który port ma być aktywny dla tej funkcjonalności. Jak zaznaczyłem przed chwilą przerwanie PCINT definiowane jest dla określonego portu i może mieć maksymalnie 8 źródeł wyzwalających (pinów), działających niezależnie. Wywołane zostanie dowolną zmianą stanu logicznego, na co najmniej jednym z pinów danego portu.

Jeśli piny są skonfigurowane jako wyjścia, a przerwania INT lub PCIN uaktywnione, nie spowoduje to żadnej zmiany w dotychczasowej pracy i przerwanie zostanie wywołane. Ta funkcjonalność zapewnia sposób generowania przerwań programowo!

Małe zestawienie liczebności źródeł przerwań zewnętrznych:

• ATmega640/1280/1281/2560/2561 – 8 przerwań INT, 24 źródła przerwania PCIN, na 3 portach,
• ATmega328/P – 2 przerwania INT, 24 źródła przerwania PCIN, na 3 portach,
• ATmega48A/88A/168A – 2 przerwania INT, 24 źródła przerwania PCIN, na 3 portach,
• ATmega128/128L – 8 przerwań INT,
• ATmega64/64L – 8 przerwań INT,
• ATmega32/32L – 2 przerwania INT,
• ATmega16/16L – 2 przerwania INT,
• ATmega8A – 2 przerwania INT, 12 źródeł przerwania PCIN, na 3 portach,
• ATmega8/8L – 2 przerwania INT,
• ATtiny13 – 1 przerwanie INT, 6 źródeł przerwania PCIN, na 2 portach,
• ATtiny2313A/4313 – 2 przerwania INT, 18 źródeł przerwania PCIN, na 3 portach,
• ATtiny25/V / ATtiny45/V / ATtiny85/V – 1 przerwanie INT, 6 źródeł przerwania PCIN, na 2 portach,
• ATtiny441/841 – 1 przerwanie INT, 12 źródeł przerwania PCIN, na 2 portach,

By jakiekolwiek przerwanie mogło funkcjonować w rejestrze SREG – Status RegisterBit 7 – I (Global Interrupt Enable), musi zostać ustawiony. Bit I jest kasowany sprzętowo po wystąpieniu dowolnego przerwania. Po zakończeniu jego obsługi jest ponownie ustawiony przez instrukcję RETI (język maszynowy) aby umożliwić wystąpienie kolejnych przerwań. Znacznik ten może być również ustawiany i kasowany przez aplikację odpowiednimi instrukcjami.

W Bascom AVR do dyspozycji w tym celu mamy polecenie:

Naturalnym biegiem rzeczy jest zezwolenie na przerwania z wybranego źródła, np:

Za to uczynnienie odpowiedzialny jest rejestr GIMSKGeneral Interuupt Mask Register. Posiada znaczniki INTn i PCIEn odpowiedzialne za uaktywnienie wybranych przerwań przez zapisanie do nich stanu wysokiego (1).
Pamiętając o tych dwóch warunkach prawidłowo uruchomimy przerwanie. No tak, ale to nie koniec bo do wybranych z nich mamy do dyspozycji zestaw parametrów precyzujących ich sposób funkcjonowania,  😉 oraz instrukcję DISABLE. W wybranych przypadkach ten zestaw parametrów będzie niezbędny do prawidłowego działania planowanej funkcjonalności, czy też samego przerwania. Do pełni szczęścia niezbędna jest jeszcze programowa obsługa akcji, którą planujemy po wystąpieniu danego przerwania.

opis instrukcji ON. Po czym na końcu programu za instrukcją END powinna się znaleźć zdefiniowana etykieta z kodem o zaplanowanej funkcjonalności. Całość musi być zakończona instrukcją powrotu Return.

Oczywiście w temacie tym pominąć nie można kolejnego rejestru GIFR (General Interrupt Flag Register) lub EIFR(External Interrupt Flag Register). Krótko mówiąc służy do przechowywania znaczników przerwań zewnętrznych. Bity INTFn i PCIFn ustawiane są sprzętowo po wystąpieniu przerwania, i zerowane przed samym rozpoczęciem jego obsługi.
Odstępstwa od reguły:
• zerowanie manualne przez zapis bitu wartością logiczną high (1),
• w przypadku przerwania INTn wyzwalanego poziomem napięciowym, znacznik stale znajduje się w stanie logicznym low (0).

Przerwanie INT.

Jest ciekawym stworem z tytułu obfitości opcji do konfiguracji, a co z tego wynika dużej wszechstronności stosowania. Jeżeli sprzęt posiada takie możliwości objawia się to potrzebą stworzenia niewielkiego kodu, a co z tego wynika sprawnością w działaniu, i super. Aby wybrać interesujący nas wariant pracy dysponujemy znacznikami np ISC01, ISC00: Interrupt Sense Control 0 Bit 1 and Bit 0 z rejestru MCUCR lub ICR.

W Bascom AVR do tego celu służy instrukcja Config INTx, a przykładowa konfiguracja może wyglądać następująco:

oczywiście nie można zapomnieć o obsłudze uruchomionego przerwania:

W tym przykładzie pokazana jest dodatkowo funkcjonalność parametru NOSAVE, dzięki któremu można znacząco skrócić czas wykonywania obsługi przerwania. Zaznaczam, że procedury zamrożenia i odtworzenia wartości stosów w języku maszynowym są indywidualne dla każdego przypadku zastosowania parametru NOSAVE.

Do wyboru mamy następujące konfiguracje wyzwolenia przerwania INTx:

• wykrywanie stanu niskiego (Low Level Interrupt)

Należy pamiętać, że żądanie przerwania generowanego poziomem logicznym (0) występuje tak długo jak sygnał wejściowy pozostaje w stanie niskim. Oraz, że przerwanie to nie korzysta z rejestru znaczników GIFR. Dlatego ważnym parametrem jest odpowiednio długi czas trwania sygnału wyzwalającego. Jest to istotne ponieważ µC musi zdążyć zakończyć wykonywać bieżące instrukcje i ustawić znacznik w rejestrze SREG, by żądanie wykonania przerwania nie zostało pominięte. Z tego tytułu przerwanie to jest nazywane asynchronicznym.
Ten rodzaj przerwania nadaje się do wybudzania µC z wszystkich trybów uśpienia. W odróżnieniu od pozostałych konfiguracji przerwania, które wybudzą µC tylko z trybu IDLE (tryb w którym zegar I/O nie jest zatrzymywany). A sygnał wyzwalający musi być odpowiednio długi by µC zdążył wyjść ze stanu uśpienia.

• wykrywanie dowolnej zmiany stanów logicznych (Any logical change – toggle)

W tym przypadku wartość na wyprowadzeniu INTn jest próbkowana przed detekcją zbocza. Jeśli zostanie wybrana przerwanie generowane zboczem lub zmianą stanu, impulsy, które trwają dłużej niż jeden okres zegara wygenerują zgłoszenie przerwanie. Krótsze nie są zalecane do generowania przerwania, bo mogą być zbyt krótkie i µC może je pominąć. Jest to przerwanie synchroniczne.

• wykrywanie zbocza narastającego, wykrywanie zbocza opadającego (The falling edge, The rising edge)

W tym przerwaniu obowiązują zasady identyczne jak w poprzednim, również jest to przerwanie synchroniczne, czyli wykrywane zależnie od zegara systemowego.

Przed zmianą parametru wyzwalającego powinno się wyzerować znacznik uruchamiający przerwanie (INTn) by nie spowodować fałszywego wystąpienia przerwania. Robimy to instrukcją: Disable INTx.

Przerwanie PCIn.

Tą funkcjonalność dość szczegółowo omówiłem już w opisie PCINT Bascom AVR, jak je pogodzić?
Przerwanie tego typu można wykorzystać do budzenia MCU z trybów uśpienia idle mode, ADC Noise Reduction, Standby, Power-down.

Warto wiedzieć.

wartości wybranych rejestrów po starcie MCU na przykładzie µC ATtiny13 • Po inicjacji µC (załączeniu zasilania i starcie, resecie) wartościami „początkowymi” rejestrów MCUCR, DDRx, PORTx jest 0.

• Producent zaleca by piny niewykorzystane nie były pozostawione jako niepodłączone (pływające), by uniknąć przypadkowych oscylacji i tym samym zwiększonego poboru prądu. W takim wypadku można uaktywnić wewnętrzne rezystory podciągające dla nie używanych wyprowadzeń. Dla ograniczenia prądu można użyć rezystorów zewnętrznych o większych wartościach. Producent nie zaleca natomiast podłączania wyprowadzeń bezpośrednio do potencjałów VCC lub GND, co może spowodować przepływ zbyt dużych wartości prądów zwarciowych i uszkodzić µC.

• Stanem aktywnym uważa się stan niski. Wynika to z tytułu większej wydajności prądowej mikrokontrolerów (20mA dla zasilania 5V i 10mA dla 3V), w odróżnieniu od stanu wysokiego (3mA dla zasilania 5V i 1,5mA dla zasilania 3V).
Tymczasem nowsze wersje/typy µC mają już porty o charakterystyce prądowej symetrycznej.

• Typową wartością prądu przepływającego przez daną linię jest 20mA dla zasilania 5V i 10mA dla zasilania 3V, zarówno dla stanu niskiego jak i wysokiego. W przypadku niektórych układów ATtiny wartości te wynoszą o połowę mniej.
Natomiast maksymalne graniczne natężenie przepływającego prądu dla poszczególnego pinu wynosi 40mA (20mA XMEGA A4). Przy czym pamiętać trzeba, że dodatkowym ogranicznikiem jest maksymalne natężenie sumy prądów przepływających przez wyprowadzenia VCC i GND. Zwykle nie może ono przekroczyć 100mA lub 200mA dla rodziny ATtiny i 200mA, 300mA lub 400mA dla rodziny ATmega, oraz 200mA dla XMEGA A4.

• Ciekawą cechą portów w trybie wejścia jest charakterystyka histerezowa. Zapobiega to niepotrzebnym oscylacjom przy sygnałach wolnozmiennych lub zniekształconych. Dla różnych układów ATtiny może wynosić 200mV do 500mV, zależnie od napięcia zasilania i panującej temperatury. Natomiast dla rodziny ATmega histereza ta wynosi około 50mV.
synchronizacja i opóźnienia na przykładzie ATtiny13 Dodatkowo warto zwrócić uwagę na fakt, że odczyt stanu wejścia w pewnych warunkach (np obciążenie pojemnościowe) powinien zostać opóźniony by przedstawił realną wartość. Wynika to z pracy układów synchronizujących, które mają zapobiegać przed błędami stanów nieustalonych. Opóźnienie to może wynosić od pół do półtora okresu zegara µC. W notach katalogowych poszczególnych MCU przedstawiono sposób programowej korekty w razie potrzeby odczytu stanu portu bezpośrednio po jego zmianie.

• W nowszych typach mikrokontrolerów zapisanie do rejestru wejściowego PINxn wartości 1, spowoduje zmianę stanu odpowiadającego mu bitu w rejestrze PORTxn na przeciwny. Informacja w nocie – rozdział Toogling the pin.


Obsługa dowolnego przerwania musi trwać MOŻLIWIE JAK NAJKRÓCEJ, i naturalnym jest, że musi być zakończona przed następnym jego wywołaniem. Do przyspieszenia wykonywania procedur związanych z obsługą przerwań służy parametr NOSAVE opisany tutaj.


Informacje odnośnie rodzaju przerwań i możliwości wybudzenia, warto zweryfikować z użytym typem µC w swojej aplikacji z danymi zawartymi w nocie katalogowej.

Share Button
Tagi , , , , , , , , , , , , .Dodaj do zakładek Link.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

twelve − 8 =