Push-pull / dreno aberto; pull-up / pull-down

49

Estou lendo a folha de dados de um chip ARM Cortex, especificamente o capítulo GPIO. Por fim, desejo configurar vários pinos GPIO para usá-los no modo "Função alternativa" para acesso de leitura / gravação à SRAM.

De todos os registros GPIO disponíveis, não compreendo dois: GPIO_PUPDRe GPIO_OTYPEque são, respectivamente, o "registro pull-up / pull-down" e o "registro do tipo de saída".

Pois GPIO_PUPDRtenho três opções:

  • Sem puxar para cima ou para baixo
  • Puxar para cima
  • Puxar para baixo

Pois GPIO_0TYPEtenho duas opções:

  • Push-pull de saída
  • Dreno aberto de saída

Qual é a diferença entre todas as configurações diferentes e qual seria a mais apropriada para a comunicação SRAM?

A documentação da placa em que estou trabalhando está disponível aqui (consulte a página 24 para os esquemas SRAM). O manual de referência para o chip ARM está disponível aqui (consulte as páginas 145 e 146 para os registros GPIO).

Randomblue
fonte
Você pode fornecer os números / links do modelo para as folhas de dados da CPU SRAM e ARM que você está usando.
Dean
@ Dean: Claro. Atualizei minha pergunta com dois links.
Randomblue

Respostas:

54

Esta resposta é geral para processadores e periféricos e possui um comentário específico da SRAM no final, provavelmente pertinente à sua RAM e CPU específicas.

Os pinos de saída podem ser acionados em três modos diferentes:

  • dreno aberto - um transistor se conecta ao ponto baixo e nada mais
  • dreno aberto, com pull-up - um transistor se conecta ao ponto baixo e um resistor se conecta ao ponto alto
  • push-pull - um transistor se conecta ao ponto alto e um transistor se conecta ao ponto baixo (apenas um é operado por vez)

Os pinos de entrada podem ser uma entrada de porta com:

  • pull-up - um resistor conectado a alta
  • pull-down - um resistor conectado a baixa
  • pull-up e pull-down - um resistor conectado ao alto e um resistor conectado ao baixo (útil apenas em casos raros).

Há também um modo de entrada acionado por Schmitt, no qual o pino de entrada é puxado com um pull-up fraco para um estado inicial. Quando deixado sozinho, ele persiste em seu estado, mas pode ser puxado para um novo estado com o mínimo de esforço.

O dreno aberto é útil quando vários portões ou pinos são conectados juntos com uma extração (externa ou interna). Se todos os pinos estiverem altos, serão todos circuitos abertos e a tração puxará os pinos para cima. Se algum pino estiver baixo, todos ficarão baixos enquanto se amarram. Essa configuração forma efetivamente um ANDportão.

Ao dirigir uma SRAM, você provavelmente desejará conduzir as linhas de dados ou as linhas de endereço alta ou baixa da maneira mais sólida e rápida possível, para que seja necessária uma unidade ativa de subida e descida, de modo que o push-pull seja indicado. Em alguns casos, com várias RAMs, você pode fazer algo inteligente e combinar linhas, onde outro modo pode ser mais adequado.

Com a SRAM com entradas de dados da SRAM, se o IC da RAM estiver sempre afirmando dados, um pino sem pull-up provavelmente estará OK, pois a RAM sempre define o nível e isso minimiza a carga. Se as linhas de dados da RAM às vezes estiverem em circuito aberto ou tristate, você precisará dos pinos de entrada para poder definir seu próprio estado válido. Nas comunicações muito alta velocidade que você pode querer usar um pull-up e e aa suspenso de modo a resistência efetiva paralelo é a resistência de terminação, e a tensão ocioso ônibus é definido pelas duas resistências, mas isso é um pouco especialista.

Russell McMahon
fonte
Só para ficar claro, o que você quer dizer com "um transistor conectado ao ponto baixo e nada mais"? Um transistor tem 3 pinos. Como cada pino está conectado?
Randomblue 23/03
@Randomblue - remediar - coletor do transistor de drenagem ou quando actua como uma saída
Russell McMahon
Para esclarecer sua resposta sobre "pull down", qual é a diferença entre "ground", "low" e "-ve"?
Randomblue 28/07/12
Fiz muitas edições na sua pergunta. Você pode verificar se não cometi nenhum erro?
Randomblue 28/07/12
@ Randomblue - As edições parecem boas. Isso me faz pensar no que escrevi inicialmente? Você parece ter dito o que acho que pensei :-).
Russell McMahon
17

Encontrei esta resposta no STM32: Noções básicas sobre configurações de GPIO

  • GPIO_PuPd (pull-up / pull-down)

Nos circuitos digitais, é importante que as linhas de sinal nunca possam "flutuar". Ou seja, eles precisam sempre estar em um estado alto ou baixo. Ao flutuar, o estado é indeterminado e causa alguns tipos diferentes de problemas.

A maneira de corrigir isso é adicionar um resistor da linha de sinal para Vcc ou Gnd. Dessa forma, se a linha não estiver sendo ativada alta ou baixa, o resistor fará com que o potencial seja desviado para um nível conhecido.

O ARM (e outros microcontroladores) possuem circuitos internos para fazer isso. Dessa forma, você não precisa adicionar outra parte ao seu circuito. Se você escolher "GPIO_PuPd_UP", por exemplo, é equivalente a adicionar um resistor entre a linha de sinal e o Vcc.

  • GPIO_OType (tipo de saída):

Push-Pull: este é o tipo de saída que a maioria das pessoas considera "padrão". Quando a saída é baixa, ela é ativamente "puxada" para o chão. Por outro lado, quando a saída é definida como alta, ela é "empurrada" ativamente em direção a Vcc. Simplificado, fica assim: insira a descrição da imagem aqui

Uma saída de dreno aberto, por outro lado, só está ativa em uma direção. Ele pode puxar o pino em direção ao solo, mas não pode empurrá-lo alto. Imagine a imagem anterior, mas sem o MOSFET superior. Quando não está puxando para o chão, o MOSFET (do lado inferior) é simplesmente não condutor, o que faz com que a saída flutue.

Para este tipo de saída, é necessário adicionar um resistor de pull-up ao circuito, o que fará com que a linha fique alta quando não for acionada em baixa. Você pode fazer isso com uma parte externa ou definindo o valor GPIO_PuPd como GPIO_PuPd_UP.

O nome vem do fato de que o dreno do MOSFET não está conectado internamente a nada. Esse tipo de saída também é chamado de "coletor aberto" ao usar um BJT em vez de um MOSFET.

  • GPIO_Speed

Basicamente, isso controla a taxa de variação (o tempo de subida e descida) do sinal de saída. Quanto mais rápida a taxa de rotação, mais ruído é irradiado do circuito. É uma boa prática manter a taxa de variação lenta e apenas aumentá-la se você tiver um motivo específico.

Abhishek
fonte
3

Mais um pouquinho: para microcontroladores que não possuem um modo "dreno aberto" explícito, como AVR e placas baseadas no Arduino ATmega328, como o Uno, esse modo "dreno aberto" pode ser simulado escrevendo uma função wrapper que simplesmente define um pino para "Saída LOW" quando você envia um 0e que configura o pino como uma "Entrada LOW" (modo de alta impedância, resistor de pullup interno NÃO ativado) quando você o envia a 1. Dessa forma, você obtém o mesmo efeito. Esses modernos microcontroladores ARM de 32 bits têm apenas muito mais opções.

Além disso, a p146 do Manual de Referência do STM32, vinculada aos itens acima, declara o seguinte [minhas adições estão entre colchetes] :

- Modo de drenagem aberto: um “0” no registro de saída ativa o N-MOS [acionando ativamente LOW conectando o pino ao GND] enquanto um “1” no registro de saída deixa a porta em Hi-Z (o P- MOS nunca é ativado) [modo de alta impedância - o mesmo que uma entrada flutuante sem resistências de pull-up ou pull-down]

- Modo push-pull: Um “0” no registro de saída ativa o N-MOS [aciona ativamente LOW conectando o pino ao GND] enquanto um “1” no registro de saída ativa o P-MOS [aciona ativamente HIGH conectando o pino para VCC]


No código do Arduino, a "função wrapper" poderia ser implementada assim:

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

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

Observe que, para ativar o resistor de pullup interno em um Arduino, você pode:

pinMode(pin, INPUT_PULLUP);

OU (mesma coisa):

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

Leitura adicional:

Gabriel Staples
fonte