Push-pull / open spust; pull-up / pull-down

49

Czytam arkusz danych układu ARM Cortex, a konkretnie rozdział GPIO. Ostatecznie chcę skonfigurować różne piny GPIO, aby używały ich w trybie „Funkcja alternatywna” w celu dostępu do odczytu / zapisu do pamięci SRAM.

Ze wszystkich dostępnych rejestrów GPIO nie rozumiem dwóch: GPIO_PUPDRi GPIO_OTYPEktóre są odpowiednio „rejestrem rozwijanym / rozwijanym” i „rejestrem typu wyjściowego”.

Bo GPIO_PUPDRmam trzy możliwości:

  • Bez podciągania lub podciągania
  • Pull-up
  • Rozbierać, opuszczać

Bo GPIO_0TYPEmam dwie możliwości:

  • Wyjście push-pull
  • Wyjście z odpływem

Jaka jest różnica między wszystkimi różnymi konfiguracjami i która byłaby najbardziej odpowiednia dla komunikacji SRAM?

Dokumentacja płyty, nad którą pracuję, jest dostępna tutaj (schematy SRAM na stronie 24). Instrukcja obsługi układu ARM jest dostępna tutaj (patrz strony 145 i 146 dla rejestrów GPIO).

Randomblue
źródło
Czy możesz podać numery modeli / łącza do arkuszy danych SRAM i ARM CPU, których używasz.
Dean
@Dean: Jasne. Zaktualizowałem swoje pytanie o dwa linki.
Randomblue,

Odpowiedzi:

54

Ta odpowiedź jest ogólna dla procesorów i urządzeń peryferyjnych i zawiera na końcu komentarz specyficzny dla SRAM, który prawdopodobnie dotyczy konkretnej pamięci RAM i procesora.

Piny wyjściowe mogą być sterowane w trzech różnych trybach:

  • otwarty odpływ - tranzystor łączy się z niskim i niczym więcej
  • otwarty odpływ, z podciąganiem - tranzystor łączy się z niskim, a rezystor łączy się z wysokim
  • push-pull - tranzystor łączy się z wysokim, a tranzystor łączy z niskim (tylko jeden jest obsługiwany jednocześnie)

Piny wejściowe mogą być bramą wejściową z:

  • pull-up - rezystor podłączony do wysokiego
  • rozwijanie - rezystor podłączony do niskiego
  • pull-up i pull-down - zarówno rezystor podłączony do wysokiego, jak i rezystor podłączony do niskiego (przydatne tylko w rzadkich przypadkach).

Istnieje również tryb wejściowy wyzwalany przez Schmitta, w którym pin wejściowy jest wyciągany słabym podciąganiem do stanu początkowego. Pozostawiony w spokoju utrzymuje się w swoim stanie, ale może zostać wciągnięty do nowego stanu przy minimalnym wysiłku.

Otwarty odpływ jest przydatny, gdy wiele bramek lub kołków jest połączonych razem z (zewnętrznym lub wewnętrznym) podciągnięciem. Jeśli wszystkie styki są wysokie, wszystkie są w obwodach otwartych, a podciąganie powoduje wysokie styki. Jeśli którykolwiek pin jest niski, wszystkie stają się niskie, gdy są powiązane. Ta konfiguracja skutecznie tworzy ANDbramę.

Podczas jazdy SRAM prawdopodobnie chcesz prowadzić linie danych lub linie adresowe wysoko lub nisko tak solidnie i szybko, jak to możliwe, aby potrzebny był aktywny napęd w górę i w dół, więc wskazane jest naciśnięcie i pociągnięcie. W niektórych przypadkach z wieloma RAM ty może chcesz zrobić coś mądrego i połączyć linie, gdzie inny tryb może być bardziej odpowiednie.

W przypadku SRAM z danymi wejściowymi z SRAM, jeśli układ scalony RAM zawsze zapisuje dane, wtedy pin bez podciągania jest prawdopodobnie OK, ponieważ RAM zawsze ustawia poziom, a to minimalizuje obciążenie. Jeśli linie danych RAM są czasami w obwodzie otwartym lub tristate, będziesz potrzebował pinów wejściowych, aby móc ustawić własny prawidłowy stan. W komunikacji bardzo szybkich ty może chcieć użyć pull-up i pull-aa i dół tak skuteczny opór równoległy jest odporność kończący, a bezczynne napięcie magistrali jest ustawiony przez dwa rezystory, ale jest to nieco specjalista.

Russell McMahon
źródło
Żeby było jasne, co rozumiesz przez „tranzystor łączący się z niskim i niczym innym”? Tranzystor ma 3 piny. Jak jest podłączony każdy pin?
Randomblue
@Randomblue - przepraszam - kolektor tranzystora lub dren podczas działania jako wyjście
Russell McMahon
Aby wyjaśnić swoją odpowiedź na temat „rozwijania”, jaka jest różnica między „uziemieniem”, „niskim” i „-ve”?
Randomblue
Wprowadziłem wiele zmian w twoim pytaniu. Czy mógłbyś sprawdzić, czy nie popełniłem żadnych błędów?
Randomblue
@Randomblue - Edycje wydają się być dobre. Zastanawiam się, co napisałem na początku? Wygląda na to, że powiedziałeś to, co myślę :-).
Russell McMahon
17

Znalazłem tę odpowiedź w STM32 Zrozumienie ustawień GPIO

  • GPIO_PuPd (Pull-up / Pull-down)

W obwodach cyfrowych ważne jest, aby linie sygnałowe nigdy nie mogły się „unosić”. Oznacza to, że muszą zawsze znajdować się w stanie wysokim lub niskim. Gdy jest zmiennoprzecinkowy, stan jest nieokreślony i powoduje kilka różnych rodzajów problemów.

Sposobem na to jest dodanie rezystora z linii sygnałowej do Vcc lub Gnd. W ten sposób, jeśli linia nie będzie aktywnie prowadzona wysoko lub nisko, rezystor spowoduje dryfowanie potencjału do znanego poziomu.

ARM (i inne mikrokontrolery) mają wbudowane obwody do tego celu. W ten sposób nie musisz dodawać kolejnej części do swojego obwodu. Jeśli na przykład wybierzesz „GPIO_PuPd_UP”, wystarczy dodać rezystor między linią sygnałową a Vcc.

  • GPIO_OType (typ wyjścia):

Push-Pull: jest to typ wyjścia, który większość ludzi uważa za „standardowy”. Kiedy moc wyjściowa spada, jest ona aktywnie „ciągnięta” do ziemi. I odwrotnie, gdy wartość wyjściowa jest ustawiona na wysoką, jest ona aktywnie „wypychana” w kierunku Vcc. Uproszczony wygląda następująco: wprowadź opis zdjęcia tutaj

Z drugiej strony wyjście Open-Drain jest aktywne tylko w jednym kierunku. Może ciągnąć kołek w kierunku ziemi, ale nie może podnieść go wysoko. Wyobraź sobie poprzednie zdjęcie, ale bez górnego MOSFETU. Gdy nie ciągnie się do ziemi, MOSFET (po dolnej stronie) jest po prostu nieprzewodzący, co powoduje, że sygnał wyjściowy się unosi.

W przypadku tego typu wyjścia do obwodu musi być dodany rezystor podciągający, co spowoduje, że linia podniesie się, gdy nie zostanie doprowadzona do stanu niskiego. Możesz to zrobić z częścią zewnętrzną lub ustawiając wartość GPIO_PuPd na GPIO_PuPd_UP.

Nazwa pochodzi od faktu, że odpływ MOSFET-u nie jest wewnętrznie połączony z niczym. Ten typ danych wyjściowych jest również nazywany „otwartym kolektorem”, gdy używany jest BJT zamiast MOSFET.

  • GPIO_Speed

Zasadniczo kontroluje to szybkość narastania (czas narastania i czas opadania) sygnału wyjściowego. Im szybsza prędkość narastania, tym więcej szumów jest emitowanych z obwodu. Dobrą praktyką jest utrzymywanie niskiej prędkości zabijania i zwiększanie jej tylko, jeśli masz konkretny powód.

Abhishek
źródło
3

Jeszcze jeden drobiazg: dla mikrokontrolerów, które nie mają jawnego trybu „otwartego spustu”, takich jak AVR i płyty oparte na Arduino ATmega328, takich jak Uno, ten tryb „otwartego spustu” można symulować, pisząc funkcję opakowania który po prostu ustawia pin na „Output LOW”, gdy wysyłasz go a, 0i który konfiguruje pin jako „Input LOW” (tryb wysokiej impedancji, wewnętrzny rezystor pullup NIE jest włączony), gdy wysyłasz go 1. W ten sposób otrzymujesz ten sam efekt. Te nowoczesne 32-bitowe mikrokontrolery z rdzeniem ARM mają po prostu znacznie więcej opcji.

Również p146 Podręcznika STM32 powiązanego z powyższym stwierdza, że [moje uzupełnienia są w nawiasach kwadratowych] :

- Tryb otwartego spustu: „0” w rejestrze wyjściowym aktywuje N-MOS [tym samym aktywnie napędza LOW poprzez podłączenie styku do GND], podczas gdy „1” w rejestrze wyjściowym opuszcza port w trybie Hi-Z (P- MOS nigdy nie jest aktywowany) [tryb wysokiej impedancji - taki sam jak wejście bezpotencjałowe bez rezystorów podwyższających lub obniżających]

- Tryb push-pull: „0” w rejestrze wyjściowym aktywuje N-MOS [aktywnie napędza LOW poprzez podłączenie pinu do GND], podczas gdy „1” w rejestrze wyjściowym aktywuje P-MOS [ aktywuje HIGH przez podłączenie pin do VCC]


W kodzie Arduino ta „funkcja opakowania” może być zaimplementowana w następujący sposób:

digitalWriteOpenDrain(byte pin, bool state)
{
    // Actively drive LOW
    if (state==LOW)
    {
        pinMode(pin, OUTPUT);
        digitalWrite(pin, LOW);
    }
    // High impedance mode 
    // (note that an internal or external pull-up resistor can optionally be added if you like, according to your requirements)
    else //state==HIGH
    {
        pinMode(pin, INPUT);
        digitalWrite(pin, LOW);
    }
}

Lub uproszczony:

digitalWriteOpenDrain(byte pin, bool state)
{
    digitalWrite(pin, LOW);

    // Actively drive LOW
    if (state==LOW)
    {
        pinMode(pin, OUTPUT);
    }
    // High impedance mode
    // (note that an internal or external pull-up resistor can optionally be added if you like, according to your requirements)
    else //state==HIGH
    {
        pinMode(pin, INPUT);
    }
}

Pamiętaj, że aby włączyć wewnętrzny rezystor podciągający w Arduino, możesz:

pinMode(pin, INPUT_PULLUP);

LUB (to samo):

pinMode(pin, INPUT);
digitalWrite(pin, HIGH);

Dodatkowe czytanie:

Gabriel Staples
źródło