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


49

Sto leggendo la scheda tecnica di un chip ARM Cortex, in particolare il capitolo GPIO. In definitiva, voglio configurare vari pin GPIO per usarli in modalità "Funzione alternativa" per l'accesso in lettura / scrittura a SRAM.

Di tutti i registri GPIO disponibili, non ne capisco due: GPIO_PUPDRe GPIO_OTYPEche sono rispettivamente il "registro pull-up / pull-down" e il "registro del tipo di uscita".

Perché GPIO_PUPDRho tre scelte:

  • Nessun pull-up o pull-down
  • Pull-up
  • Tirare verso il basso

Perché GPIO_0TYPEho due scelte:

  • Push-pull in uscita
  • Uscita open-drain

Qual è la differenza tra tutte le diverse configurazioni e quale sarebbe la più appropriata per la comunicazione SRAM?

La documentazione per la scheda su cui sto lavorando è disponibile qui (vedere pagina 24 per gli schemi SRAM). Il manuale di riferimento per il chip ARM è disponibile qui (vedere le pagine 145 e 146 per i registri GPIO).


Potete fornire numeri / collegamenti di modello a fogli dati della CPU SRAM e ARM che state utilizzando.
Decano del

@Dean: certo. Ho aggiornato la mia domanda con due collegamenti.
Randomblue,

Risposte:


54

Questa risposta è generale per processori e periferiche e ha un commento specifico SRAM alla fine, che è probabilmente pertinente alla tua RAM e CPU specifica.

I pin di uscita possono essere pilotati in tre diverse modalità:

  • drain aperto - un transistor si collega al basso e nient'altro
  • drenaggio aperto, con pull-up : un transistor si collega al basso e un resistore si collega al massimo
  • push-pull : un transistor si collega ad alto e un transistor si collega a basso (ne viene azionato solo uno alla volta)

I pin di input possono essere un input gate con un:

  • pull-up - una resistenza collegata ad alto
  • pull-down - un resistore collegato al basso
  • pull-up e pull-down - sia una resistenza collegata ad alta che una resistenza collegata a bassa (utile solo in rari casi).

C'è anche una modalità di input innescata Schmitt in cui il pin di input viene tirato con un pull-up debole fino a uno stato iniziale. Se lasciato solo, persiste nel suo stato, ma può essere trascinato in un nuovo stato con il minimo sforzo.

Lo scarico aperto è utile quando più porte o perni sono collegati insieme a un pull-up (esterno o interno). Se tutti i pin sono alti, sono tutti circuiti aperti e il pull-up guida i pin in alto. Se uno spillo è basso, si abbassano tutti quando vengono legati insieme. Questa configurazione costituisce effettivamente un ANDgate.

Quando si guida una SRAM, probabilmente si desidera guidare le linee dati o le linee degli indirizzi in alto o in basso il più solidamente e rapidamente possibile in modo che sia necessaria l'unità attiva su e giù, quindi è indicato il push-pull. In alcuni casi, con più RAM si potrebbe desiderare di fare qualcosa di intelligente e combinare le linee, dove un altro modo può essere più adatto.

Con SRAM con input di dati da SRAM se l'IC RAM asserisce sempre dati, probabilmente un pin senza pull-up è OK poiché la RAM imposta sempre il livello e questo riduce al minimo il carico. Se le linee di dati RAM a volte sono a circuito aperto o tristate, saranno necessari i pin di ingresso per poter impostare il proprio stato valido. Nelle comunicazioni ad altissima velocità si potrebbe desiderare di utilizzare un pull-up e e aa pull-down in modo che la resistenza effettiva parallelo è la resistenza di terminazione, e la tensione di inattività del bus è fissato dalle due resistenze, ma questo è un po specialista.


Giusto per essere chiari, cosa intendi con "un transistor che si collega al basso e nient'altro"? Un transistor ha 3 pin. Come è collegato ciascun pin?
Randomblue,

@Randomblue - scusa - collettore a transistor o drain quando agisce come uscita
Russell McMahon

Per chiarire la tua risposta su "pull down", qual è la differenza tra "ground", "low" e "-ve"?
Randomblue,

Ho apportato molte modifiche alla tua domanda, potresti controllare che non abbia fatto errori?
Randomblue,

@Randomblue - Le modifiche sembrano essere buone. Mi chiedo cosa ho scritto inizialmente? Sembra che tu abbia detto quello che penso di aver pensato :-).
Russell McMahon,

17

Ho trovato questa risposta da STM32 Comprensione delle impostazioni GPIO

  • GPIO_PuPd (Pull-up / Pull-down)

Nei circuiti digitali, è importante che le linee di segnale non possano mai "fluttuare". Cioè, devono sempre essere in uno stato alto o basso. Quando fluttua, lo stato è indeterminato e causa alcuni diversi tipi di problemi.

Il modo per correggere questo è aggiungere un resistore dalla linea del segnale a Vcc o Gnd. In questo modo, se la linea non viene pilotata attivamente in alto o in basso, il resistore causerà il potenziale di spostarsi a un livello noto.

Il ARM (e altri microcontrollori) hanno circuiti integrati per farlo. In questo modo, non è necessario aggiungere un'altra parte al circuito. Se si sceglie "GPIO_PuPd_UP", ad esempio, è utile aggiungere un resistore tra la linea di segnale e Vcc.

  • GPIO_OType (Tipo di output):

Push-Pull: questo è il tipo di output che la maggior parte delle persone considera "standard". Quando l'uscita si abbassa, viene attivamente "tirata" a terra. Al contrario, quando l'output è impostato su high, viene attivamente "spinto" verso Vcc. Semplificato, si presenta così: inserisci qui la descrizione dell'immagine

Un output Open-Drain, d'altra parte, è attivo solo in una direzione. Può tirare il perno verso terra, ma non può guidarlo in alto. Immagina l'immagine precedente, ma senza il MOSFET superiore. Quando non sta tirando a terra, il MOSFET (lato inferiore) è semplicemente non conduttivo, causando il galleggiamento dell'uscita.

Per questo tipo di uscita, è necessario aggiungere una resistenza di pull-up al circuito, che farà salire la linea quando non viene pilotata bassa. È possibile farlo con una parte esterna o impostando il valore GPIO_PuPd su GPIO_PuPd_UP.

Il nome deriva dal fatto che lo scarico del MOSFET non è collegato internamente a nulla. Questo tipo di output è anche chiamato "open-collector" quando si utilizza un BJT invece di un MOSFET.

  • GPIO_Speed

Fondamentalmente, questo controlla la velocità di risposta (il tempo di salita e il tempo di caduta) del segnale di uscita. Più veloce è la velocità di risposta, maggiore è il rumore irradiato dal circuito. È buona norma mantenere la velocità di risposta lenta e aumentarla solo se si ha un motivo specifico.


3

Ancora un po 'di marea: per i microcontrollori che non hanno una modalità "open drain" esplicita, come schede AVR e Arduino basate su ATmega328 come Uno, questa modalità "open drain" può essere simulata scrivendo una funzione wrapper che imposta semplicemente un pin su "Output LOW" quando lo si invia a 0e che configura il pin come "Input LOW" (modalità ad alta impedenza, resistenza di pullup interna NON attiva) quando lo si invia a 1. In questo modo si ottiene lo stesso effetto. Questi moderni microcontrollori ARM-core a 32 bit hanno solo molte più opzioni.

Inoltre, p146 del Manuale di riferimento STM32 collegato a quanto sopra indica quanto segue [le mie aggiunte sono tra parentesi quadre] :

- Modalità drain aperta: uno "0" nel registro di uscita attiva l'N-MOS [guidando così attivamente BASSO collegando il pin a GND] mentre uno "1" nel registro di uscita lascia la porta in Hi-Z (la P- MOS non viene mai attivato) [modalità ad alta impedenza - uguale a un ingresso flottante senza resistenze pull-up o pull-down]

- Modalità push-pull: uno “0” nel registro di uscita attiva l'N-MOS [guida attivamente BASSO collegando il pin a GND] mentre uno “1” nel registro di uscita attiva il P-MOS [guida attivamente ALTO collegando il pin a VCC]


Nel codice Arduino quella "funzione wrapper" potrebbe essere implementata in questo modo:

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

O semplificato:

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

Nota che per attivare la resistenza pullup interna su un Arduino puoi fare:

pinMode(pin, INPUT_PULLUP);

OPPURE (stessa cosa):

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

Letture addizionali:

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.