Push-pull / drenaje abierto; pull-up / pull-down

49

Estoy leyendo la hoja de datos de un chip ARM Cortex, específicamente el capítulo GPIO. Finalmente, quiero configurar varios pines GPIO para usarlos en modo "Función alternativa" para acceso de lectura / escritura a SRAM.

De todos los registros GPIO disponibles, no entiendo dos: GPIO_PUPDRy GPIO_OTYPEque son respectivamente el "registro pull-up / pull-down" y el "registro de tipo de salida".

Porque GPIO_PUPDRtengo tres opciones:

  • Sin pull-up o pull-down
  • Levantar
  • Derribar

Porque GPIO_0TYPEtengo dos opciones:

  • Salida push-pull
  • Salida de drenaje abierto

¿Cuál es la diferencia entre todas las diferentes configuraciones y cuál sería la más adecuada para la comunicación SRAM?

La documentación de la placa en la que estoy trabajando está disponible aquí (consulte la página 24 para ver los esquemas de SRAM). El manual de referencia para el chip ARM está disponible aquí (consulte las páginas 145 y 146 para ver los registros GPIO).

Randomblue
fuente
¿Puede proporcionar números de modelo / enlaces a hojas de datos de la CPU SRAM y ARM que está utilizando?
Dean
@Dean: Claro. He actualizado mi pregunta con dos enlaces.
Randomblue

Respuestas:

54

Esta respuesta es general para procesadores y periféricos, y tiene un comentario específico de SRAM al final, que probablemente sea pertinente para su RAM y CPU específicas.

Los pines de salida pueden manejarse en tres modos diferentes:

  • drenaje abierto : un transistor se conecta a bajo y nada más
  • drenaje abierto, con pull-up : un transistor se conecta a bajo y una resistencia se conecta a alto
  • push-pull : un transistor se conecta a alto y un transistor se conecta a bajo (solo se opera uno a la vez)

Los pines de entrada pueden ser una entrada de puerta con:

  • pull-up - una resistencia conectada a alta
  • pull-down - una resistencia conectada a baja
  • pull-up y pull-down : una resistencia conectada a alta y una resistencia conectada a baja (solo útil en casos excepcionales).

También hay un modo de entrada activada por Schmitt donde el pin de entrada se tira con un pull-up débil a un estado inicial. Cuando se deja solo, persiste en su estado, pero puede ser llevado a un nuevo estado con un esfuerzo mínimo.

El drenaje abierto es útil cuando se conectan múltiples compuertas o pasadores con un pull-up (externo o interno). Si todos los pines son altos, todos son circuitos abiertos y el pull-up impulsa los pines hacia arriba. Si algún alfiler está bajo, todos caen cuando se atan. Esta configuración forma efectivamente una ANDpuerta.

Al conducir una SRAM, es probable que desee conducir las líneas de datos o las líneas de dirección de manera alta o baja de la manera más sólida y rápida posible, de modo que se necesite una unidad activa hacia arriba y hacia abajo, por lo que se indica push-pull. En algunos casos con múltiples RAMs, es posible que desee hacer algo inteligente y combinar líneas, donde otro modo puede ser más adecuado.

Con la SRAM con entradas de datos de la SRAM si la RAM IC siempre está confirmando datos, entonces un pin sin pull-up probablemente esté bien, ya que la RAM siempre establece el nivel y esto minimiza la carga. Si las líneas de datos de RAM a veces son de circuito abierto o tristadas, necesitará los pines de entrada para poder establecer su propio estado válido. En comunicaciones de muy alta velocidad, es posible que desee utilizar un pull-up y aa pull-down para que la resistencia efectiva paralela sea la resistencia de terminación, y el voltaje inactivo del bus lo establecen las dos resistencias, pero esto es algo especializado.

Russell McMahon
fuente
Para que quede claro, ¿qué quieres decir con "un transistor conectado a bajo y nada más"? Un transistor tiene 3 pines. ¿Cómo se conecta cada pin?
Randomblue
@Randomblue - lo siento - colector de transistor o drenaje cuando actúa como salida
Russell McMahon
Para aclarar su respuesta en "pull down", ¿cuál es la diferencia entre "ground", "low" y "-ve"?
Randomblue
He hecho muchas ediciones a su pregunta, ¿podría verificar que no haya cometido ningún error?
Randomblue
@Randomblue - Las ediciones parecen ser buenas. ¿Me hace preguntarme qué escribí inicialmente? Parece que has dicho lo que creo que pensé :-).
Russell McMahon
17

Encontré esta respuesta de STM32 Comprensión de la configuración de GPIO

  • GPIO_PuPd (Pull-up / Pull-down)

En los circuitos digitales, es importante que nunca se permita que las líneas de señal "floten". Es decir, siempre deben estar en un estado alto o bajo. Cuando flota, el estado es indeterminado y causa algunos tipos diferentes de problemas.

La forma de corregir esto es agregar una resistencia desde la línea de señal a Vcc o Gnd. De esa manera, si la línea no se conduce activamente hacia arriba o hacia abajo, la resistencia hará que el potencial se desplace a un nivel conocido.

El ARM (y otros microcontroladores) tienen circuitos integrados para hacer esto. De esa manera, no necesita agregar otra parte a su circuito. Si elige "GPIO_PuPd_UP", por ejemplo, es equivalente a agregar una resistencia entre la línea de señal y Vcc.

  • GPIO_OType (Tipo de salida):

Push-Pull: este es el tipo de salida que la mayoría de la gente considera "estándar". Cuando la salida baja, es activamente "tirada" a tierra. Por el contrario, cuando la salida se establece en alta, se "empuja" activamente hacia Vcc. Simplificado, se ve así: ingrese la descripción de la imagen aquí

Una salida de drenaje abierto, por otro lado, solo está activa en una dirección. Puede tirar del pasador hacia el suelo, pero no puede conducirlo alto. Imagine la imagen anterior, pero sin el MOSFET superior. Cuando no está tirando a tierra, el MOSFET (lado inferior) simplemente no es conductor, lo que hace que la salida flote.

Para este tipo de salida, debe haber una resistencia pull-up agregada al circuito, lo que provocará que la línea suba cuando no se maneje bajo. Puede hacer esto con una parte externa, o estableciendo el valor GPIO_PuPd en GPIO_PuPd_UP.

El nombre proviene del hecho de que el drenaje del MOSFET no está conectado internamente a nada. Este tipo de salida también se denomina "colector abierto" cuando se utiliza un BJT en lugar de un MOSFET.

  • GPIO_Speed

Básicamente, esto controla la velocidad de respuesta (el tiempo de subida y el tiempo de caída) de la señal de salida. Cuanto más rápida sea la velocidad de respuesta, más ruido se irradia desde el circuito. Es una buena práctica mantener la velocidad de rotación lenta y solo aumentarla si tiene una razón específica.

Abhishek
fuente
3

Un pequeño bit de tid más: para los microcontroladores que no tienen un modo de "drenaje abierto" explícito, como las placas basadas en AVR y Arduino ATmega328 como el Uno, este modo de "drenaje abierto" se puede simular escribiendo una función de envoltura que simplemente establece un pin en "Salida BAJA" cuando lo envía 0y que configura el pin como "Entrada BAJA" (modo de alta impedancia, resistencia de pullup interna NO activada) cuando lo envía a 1. De esta manera obtienes el mismo efecto. Estos modernos microcontroladores ARM-core de 32 bits solo tienen muchas más opciones, eso es todo.

Además, p146 del Manual de referencia STM32 vinculado a los estados anteriores lo siguiente [mis adiciones están entre corchetes] :

- Modo de drenaje abierto: un "0" en el registro de Salida activa el N-MOS [por lo tanto, activa activamente BAJO conectando el pin a GND] mientras que un "1" en el registro de Salida deja el puerto en Hi-Z (el P- MOS nunca se activa) [modo de alta impedancia - igual que una entrada flotante sin resistencias pull-up o pull-down]

- Modo push-pull: un "0" en el registro de Salida activa el N-MOS [activa activamente BAJO conectando el pin a GND] mientras que un "1" en el registro de Salida activa el P-MOS [activa activamente ALTO conectando el pin a VCC]


En el código Arduino, esa "función de envoltura" podría implementarse así:

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 simplificado:

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

Tenga en cuenta que para encender la resistencia pullup interna en un Arduino puede hacer:

pinMode(pin, INPUT_PULLUP);

O (lo mismo):

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

Lectura adicional:

Gabriel Staples
fuente