Mam pełnoetatową pracę jako inżynier oprogramowania. Niedawno otrzymałem zadanie przejrzenia konfiguracji GPIO i zmiany ustawień w razie potrzeby. Znalazłem kilka pinów, które były nieprawidłowo skonfigurowane, więc naturalnie je ponownie skonfigurowałem, ale powiedziano mi, że zrobiłem to w niewłaściwej kolejności. Oto o czym mówię:
Przed:
GPIO1.direction = WEJŚCIE;Po:
GPIO1.direction = WYJŚCIE;
GPIO1.value = 0;
Jednak podczas przeglądu kodu powiedziano mi, że muszę zmienić kolejność inicjowania na następujące:
GPIO1.value = 0;
GPIO1.direction = WYJŚCIE;
Innymi słowy, najpierw ustaw wartość, a następnie ustaw kierunek sworznia. Powiedziano mi również, że tak właśnie musi być na współczesnych procesorach, ponieważ używają dwóch rejestrów, jednego dla danych wejściowych i jednego dla danych wyjściowych, jednak stare procesory używają tylko jednego rejestru, więc kolejność operacji nie miałaby znaczenia.
(Uwaga: Nowoczesne = ARM Cortex M3 i nowsze, Stare = Intel 8051)
Poprosiłem o lepsze wyjaśnienie w pracy, ale nie mogłem uzyskać dobrej odpowiedzi. Dlatego postanowiłem zapytać tutaj.
Oto moje pytania:
- Dlaczego kolejność inicjalizacji ma znaczenie dla nowych procesorów?
- Dlaczego kolejność inicjalizacji nie ma znaczenia na starych procesorach?
- O jakich dwóch rejestrach mówią w nowoczesnych procesorach?
- O jakim pojedynczym rejestrze mówią na starych procesorach?
Gdyby ktoś mógł podać jakiś schemat, byłoby to jeszcze lepsze.
Odpowiedzi:
Oryginalny 8051 używał tak zwanych pseudokierunkowych portów wyjściowych (open-drain z pullupami), więc tak naprawdę nie było żadnego ustawienia kierunku portu.
Oczywiście w przypadku nowoczesnych prawdziwych dwukierunkowych portów wyjściowych lepiej jest ustawić znaną wartość przed włączeniem pinów portu dla danych wyjściowych, ponieważ w przeciwnym razie możesz mieć stan przejściowy na wyjściu, który mógłby zrobić coś niepożądanego.
Zobacz na przykład moją odpowiedź tutaj .
Edycja: Oto struktura pinów we / wy dla (względnie) nowoczesnego mikrokontrolera CMOS :
TRIS (TRIState) nazywa się DDR (rejestr kierunku danych) w wielu innych mikrach. W takim przypadku, jeśli moc wyjściowa zatrzasku TRIS jest wysoka, oba tranzystory są wyłączone, ale port można nadal odczytać.
Oto nieco bardziej złożona struktura pinów we / wy dla nowszego Microchip micro .
Ponownie zatrzask TRIS wyłącza wyjście. Ten zawiera zatrzask LAT, który pomaga uniknąć problemów z odczytem, modyfikacją i zapisem . W serii PIC powinieneś pisać tylko do rejestru LAT (i czytać z rejestru PORT).
Oto oryginalne obwody wewnętrzne portów we / wy 8051 i CMOS 8051 classic (z tego źródła ):
Trochę dodatkowej złożoności polega na tym, że równolegle do tranzystora przyspieszenia jest dołączany tranzystor przyspieszający, aby przezwyciężyć zewnętrzną pojemność. Jak widać, w ogóle nie ma kontroli TRIS / DDR. Podciągane tranzystory MOSFET używane podczas normalnej pracy są „słabe” - są na tyle małe (niskie Idss), że zewnętrzne wyjście podłączone do pinu może podciągnąć niską linię portu pseudo dwukierunkowego.
źródło
Jeśli najpierw ustawisz kierunek, kołek zostanie na krótko skonfigurowany do wyjścia niezależnie od jego bieżącej wartości wyjściowej. Jeśli najpierw ustawisz wartość, tak się nie stanie.
Robiąc to tak, jak zalecono, unika się trzasków na wyjściu, które mogą wahać się od nieszkodliwych do katastrofalnych, w zależności od tego, do czego podłączony jest pin.
źródło
Zakładając, że domyślnym kierunkiem jest wejście (tj. High-Z, co ma sens, ponieważ nie chcemy, aby MCU wymuszało jakąkolwiek wartość na podłączonych liniach), ta kolejność konfigurowania portu jest preferowana, ale nie konieczna. Jest to w rzeczywistości konieczne, gdy twoja aplikacja wymaga, aby przy uruchomieniu wartość portu nie była, powiedzmy, wartością
1
. Następnie ustaw wartość na,0
a następnie zmień kierunek. W takim przypadku unikasz możliwej chwilowej „usterki” między ustawieniem kierunku a wartością, co mogłoby spowodować skok na tej szpilce. Dotyczy to wszystkich procesorów o takiej logice, nie tylko nowych.źródło