74 votos

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

Estoy leyendo el datasheet de un chip ARM Cortex, concretamente el capítulo de GPIO. En definitiva, quiero configurar varios pines GPIO para utilizarlos en modo "Función Alterna" para el acceso de lectura/escritura a la SRAM.

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

Para GPIO_PUPDR Tengo tres opciones:

  • Sin pull-up o pull-down
  • Pull-up
  • Tira hacia abajo

Para GPIO_0TYPE Tengo dos opciones:

  • Salida push-pull
  • Salida abierta

¿Cuál es la diferencia entre las distintas 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í (ver página 24 para el esquema de la SRAM). El manual de referencia del chip ARM está disponible aquí (ver páginas 145 y 146 para los registros GPIO).

79voto

aryeh Puntos 1594

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

Los pines de salida pueden ser manejados 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 baja, y una resistencia se conecta a alta
  • push-pull - un transistor se conecta a alta, y un transistor se conecta a baja (sólo funciona uno a la vez)

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

  • pull-up - una resistencia conectada a alta
  • pull-down - una resistencia conectada a bajo
  • pull-up y pull-down - tanto una resistencia conectada a alta como una resistencia conectada a baja (sólo útil en casos raros).

También hay un Modo de entrada de disparo de 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 arrastrado a un nuevo estado con un esfuerzo mínimo.

El drenaje abierto es útil cuando se conectan varias puertas o pines con un pull-up (externo o interno). Si todos los pines son altos, son todos circuitos abiertos y el pull-up conduce los pines a alto. Si alguno de los pines está bajo, todos se vuelven bajos al estar conectados entre sí. Esta configuración forma efectivamente un AND puerta.

_____________________________

Nota añadida en noviembre de 2019 - 7+ años después: La configuración de combinar múltiples salidas de colector abierto/drenaje se ha denominado tradicionalmente como una configuración "OR cableada". Llamarla OR (incluso tradicionalmente) no la convierte en una. Si se utiliza la lógica negativa (que tradicionalmente puede haber sido el caso) las cosas serán diferentes, pero en lo que sigue me ceñiré a la convención de la lógica positiva que es lo que se utiliza a partir de ahora a menos que se indique específicamente.

El comentario anterior sobre la formación de una puerta "AND" ha sido cuestionado varias veces a lo largo de los años, y se ha sugerido que el resultado es "realmente" una puerta "OR". Es complejo.

La imagen simple" es que si se conectan varias salidas de colector abierto juntas, si uno de los transistores de colector abierto se enciende, la salida común será baja. Para que la salida común sea alta, todas las salidas deben estar apagadas.

Si se considera la combinación de 3 salidas, para que el resultado sea alto, las 3 tendrían que haber sido altas individualmente. 111 -> 1. Eso es un 'AND'.

Si consideras cada una de las etapas de salida como un inversor, para que cada una tenga una salida alta su entrada debe ser baja. Así que para obtener una salida alta combinada necesitas tres 000 -> 1 . Eso es un "NOR".

Algunos han sugerido que se trata de un OR - Cualquiera de XYZ con al menos 1 de estos es un 1 -> 1.
No puedo "forzar" esa idea en la situación.

_________________________________

Cuando se maneja una SRAM probablemente se quiere manejar las líneas de datos o las líneas de dirección en alto o en bajo tan sólida y rápidamente como sea posible, por lo que se necesita un manejo activo hacia arriba y hacia abajo, por lo que se indica push-pull. En algunos casos con múltiples RAMs usted puede quiere hacer algo inteligente y combinar líneas, donde otro modo puede ser más adecuado.

Con la SRAM con entradas de datos desde la SRAM si el IC de la RAM siempre está afirmando datos entonces un pin sin pull-up es probablemente Está bien, ya que la RAM siempre establece el nivel y esto minimiza la carga. Si las líneas de datos de la RAM están a veces en circuito abierto o en triestado, necesitarás que los pines de entrada sean capaces de establecer su propio estado válido. En comunicaciones de muy alta velocidad puede quiere utilizar un pull-up y un pull-down para que la resistencia efectiva en paralelo sea la resistencia de terminación, y la tensión de reposo del bus sea fijada por las dos resistencias, pero esto es algo especializado.

23voto

ddimmich Puntos 23

He encontrado esta respuesta de STM32 Entendiendo la configuración del GPIO

  • GPIO_PuPd (Pull-up / Pull-down)

En los circuitos digitales, es importante que las líneas de señal nunca se dejen "flotar". Es decir, tienen que estar siempre en un estado alto o bajo. Cuando flotan, el estado es indeterminado, y causa varios tipos de problemas.

La forma de corregir esto es añadir una resistencia desde la línea de señal a Vcc o Gnd. De esta manera, si la línea no está siendo activamente conducida a un nivel alto o bajo, la resistencia hará que el potencial se desplace a un nivel conocido.

Los ARM (y otros microcontroladores) tienen circuitos integrados para hacer esto. De esta manera, no necesitas añadir otra parte a tu circuito. Si eliges "GPIO_PuPd_UP", por ejemplo, es equivalente a añadir 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 se pone a nivel bajo, se "tira" activamente a tierra. A la inversa, cuando la salida se pone en alto, es activamente "empujada" hacia Vcc. Simplificado, se ve así: enter image description here

Una salida Open-Drain, en cambio, sólo está activa en una dirección. Puede tirar de la clavija hacia tierra, pero no puede conducirla hacia arriba. Imagine la imagen anterior, pero sin el MOSFET superior. Cuando no tira a tierra, el MOSFET (del lado inferior) simplemente no es conductor, lo que hace que la salida flote.

Para este tipo de salida, es necesario añadir una resistencia de pull-up al circuito, lo que hará que la línea se ponga en alto cuando no sea conducida a bajo. Puedes hacer esto con una parte externa, o ajustando el valor de GPIO_PuPd a 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 el slew rate (el tiempo de subida y bajada) de la señal de salida. Cuanto más rápido sea el slew rate, más ruido se irradiará del circuito. Es una buena práctica mantener el slew rate lento, y sólo aumentarlo si tienes una razón específica.

6voto

Gabriel Staples Puntos 163

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

Además, la página 146 del Manual de referencia de STM32 vinculado a lo anterior afirma lo siguiente [mis añadidos están entre corchetes] :

- Modo de drenaje abierto: Un "0" en el registro de salida activa el N-MOS [por lo que se conduce activamente a LOW 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 [conduce activamente a LOW conectando el pin a GND] mientras que un "1" en el registro de salida activa el P-MOS [conduce activamente a HIGH conectando el pin a VCC]


En el código de Arduino esa "función envolvente" 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 activar la resistencia interna de pullup en un Arduino puede hacer:

pinMode(pin, INPUT_PULLUP);

O (lo mismo):

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

Lectura adicional:

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X