Двухтактный / открытый сток; подтягивающий / выпадающий

49

Я читаю спецификацию чипа ARM Cortex, особенно главу GPIO. В конечном итоге я хочу настроить различные выводы GPIO, чтобы использовать их в режиме «Альтернативная функция» для доступа к чтению / записи в SRAM.

Из всех доступных регистров GPIO я не понимаю два: GPIO_PUPDRи GPIO_OTYPEэто соответственно «регистр подтягивания / понижения» и «регистр типа вывода».

Ибо у GPIO_PUPDRменя есть три варианта:

  • Нет подтягивания или опускания
  • Подтягивание
  • Тянуть вниз

Ибо у GPIO_0TYPEменя есть два варианта:

  • Выходной двухтактный
  • Выход с открытым стоком

В чем разница между всеми различными конфигурациями, и какая будет наиболее подходящей для связи SRAM?

Документация по плате, над которой я работаю, доступна здесь (см. Стр. 24 для схем SRAM). Справочное руководство по микросхеме ARM доступно здесь (см. Стр. 145 и 146 для регистров GPIO).

Randomblue
источник
Можете ли вы предоставить номера моделей / ссылки на технические характеристики используемых вами процессоров SRAM и ARM.
Дин
@ Дин: Конечно. Я обновил свой вопрос двумя ссылками.
Randomblue

Ответы:

54

Этот ответ является общим для процессоров и периферийных устройств, и в конце содержит комментарий, специфичный для SRAM, который, вероятно, имеет отношение к вашей конкретной оперативной памяти и процессору.

Выходные контакты могут работать в трех разных режимах:

  • открытый сток - транзистор подключается к низкому и ничего больше
  • открытый сток, с подтягиванием - транзистор подключается к низкому уровню, а резистор подключается к высокому
  • двухтактный - транзистор подключается к высокому уровню, а транзистор подключается к низкому (одновременно работает только один)

Входные контакты могут быть входом затвора с:

  • подтягивание - резистор, подключенный к высокой
  • опускание - резистор подключен к низкому
  • pull-up и pull-down - и резистор, подключенный к высокому, и резистор, подключенный к низкому (полезно только в редких случаях).

Существует также триггерный входной режим Шмитта, при котором входной вывод тянется со слабым подтягиванием в исходное состояние. Оставленный в покое, он остается в своем состоянии, но может быть переведен в новое состояние с минимальными усилиями.

Открытый слив полезен, когда несколько ворот или штифтов соединены вместе с (внешним или внутренним) подтягиванием. Если все штыри находятся на высоком уровне, все они являются разомкнутыми цепями, и подтягивающие штыри поднимают штифты на высокий уровень. Если какая-либо булавка низкая, все они становятся низкими, поскольку они связаны друг с другом. Эта конфигурация эффективно формирует ANDворота.

При управлении SRAM вы, вероятно, хотите, чтобы линии передачи данных или строки адреса были высокими или низкими как можно более твердыми и быстрыми, чтобы был необходим активный привод вверх и вниз, поэтому указывается двухтактный режим. В некоторых случаях с несколькими ОЗУ вы можете захотеть сделать что-нибудь умное и объединить линии, где другой режим может быть более подходящим.

При использовании SRAM с данными, вводимыми из SRAM, если микросхема ОЗУ всегда утверждает данные, то вывод без подтягивания, вероятно, в порядке, так как ОЗУ всегда устанавливает уровень, и это минимизирует нагрузку. Если линии данных ОЗУ иногда разомкнуты или находятся в трехстороннем состоянии, вам понадобятся входные контакты, чтобы иметь возможность установить свое собственное допустимое состояние. В очень высокоскоростных коммуникациях вы можете использовать подтягивание и, и, а также понижение, так что параллельное эффективное сопротивление является конечным сопротивлением, а напряжение холостого хода шины устанавливается двумя резисторами, но это несколько специфично.

Рассел МакМахон
источник
Просто чтобы прояснить, что вы подразумеваете под «транзистор, соединяющийся с низким и ничем иным»? Транзистор имеет 3 контакта. Как каждый контакт подключен?
Randomblue
@Randomblue - извините - транзисторный коллектор или сток при работе в качестве выхода
Рассел МакМэхон
Чтобы прояснить свой ответ на «pull down», в чем разница между «ground», «low» и «-ve»?
Randomblue
Я внес много правок в ваш вопрос. Не могли бы вы проверить, что я не допустил ошибок?
Randomblue
@Randomblue - Правка кажется хорошей. Это заставляет меня задуматься, что я написал изначально? Вы, кажется, сказали то, что я думаю, я думал :-).
Рассел МакМахон
17

Я нашел этот ответ от STM32 Понимание настроек GPIO

  • GPIO_PuPd (Pull-up / Pull-down)

В цифровых цепях важно, чтобы сигнальным линиям никогда не разрешалось «плавать». То есть они должны всегда находиться в высоком или низком состоянии. При плавающем состоянии состояние не определено и вызывает несколько различных типов проблем.

Способ исправить это - добавить резистор из сигнальной линии к Vcc или Gnd. Таким образом, если линия активно не приводится в действие на высоком или низком уровне, резистор вызовет дрейф потенциала до известного уровня.

ARM (и другие микроконтроллеры) имеют встроенную схему для этого. Таким образом, вам не нужно добавлять другую часть в вашу схему. Например, если вы выберете «GPIO_PuPd_UP», это равносильно добавлению резистора между сигнальной линией и Vcc.

  • GPIO_OType (Тип вывода):

Push-Pull: это тип вывода, который большинство людей считает «стандартным». Когда выходной сигнал становится низким, он активно «тянется» на землю. И наоборот, когда выходной сигнал установлен на высокий уровень, он активно «подталкивается» к Vcc. Упрощенно это выглядит так: введите описание изображения здесь

Выход Open-Drain, с другой стороны, активен только в одном направлении. Он может тянуть штифт к земле, но он не может вести его высоко. Представьте себе предыдущее изображение, но без верхнего MOSFET. Когда он не тянет на землю, полевой МОП-транзистор (нижняя сторона) просто непроводящий, что вызывает всплывание выходного сигнала.

Для этого типа выхода в цепь должен быть добавлен подтягивающий резистор, который приведет к тому, что линия станет высокой, когда она не будет переведена в низкий уровень. Вы можете сделать это с внешней деталью или установив значение GPIO_PuPd равным GPIO_PuPd_UP.

Название происходит от того факта, что утечка MOSFET внутренне не связана ни с чем. Этот тип вывода также называется «открытый коллектор» при использовании BJT вместо MOSFET.

  • GPIO_Speed

По сути, это контролирует скорость нарастания (время нарастания и спада) выходного сигнала. Чем выше скорость нарастания, тем больше шума излучается от цепи. Хорошей практикой является замедление скорости нарастания и увеличение ее только при наличии конкретной причины.

Абхишек
источник
3

Еще один маленький кусочек: для микроконтроллеров, у которых нет явного режима «открытого стока», таких как платы на базе AVR и Arduino ATmega328, таких как Uno, этот режим «открытого стока» можно смоделировать, написав функцию-обертку который просто устанавливает вывод на «Выход НИЗКИЙ», когда вы отправляете его, 0и который настраивает вывод как «Вход НИЗКИЙ» (режим с высоким импедансом, внутренний подтягивающий резистор НЕ включен), когда вы отправляете его a 1. Таким образом, вы получите тот же эффект. Эти современные 32-битные ARM-ядра микроконтроллеров просто имеют гораздо больше возможностей.

Кроме того, p146 Справочного руководства STM32, связанного с вышеупомянутым, заявляет следующее [мои дополнения в квадратных скобках] :

- Режим открытого стока: «0» в выходном регистре активирует N-MOS [тем самым активно приводя в действие НИЗКИЙ, подключая вывод к GND], тогда как «1» в выходном регистре покидает порт в Hi-Z (P- MOS никогда не активируется) [режим с высоким импедансом - такой же, как плавающий вход без подтягивающих или понижающих резисторов]

- Двухтактный режим: «0» в выходном регистре активирует N-MOS [активно запускает НИЗКИЙ, подключая вывод к GND], тогда как «1» в выходном регистре активирует P-MOS [активно управляет HIGH, подключая штырь к VCC]


В коде Arduino эта «функция-обертка» может быть реализована так:

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

Или упрощенно:

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

Обратите внимание, что для включения внутреннего подтягивающего резистора на Arduino вы можете сделать:

pinMode(pin, INPUT_PULLUP);

ИЛИ (тоже самое):

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

Дополнительное чтение:

Габриэль Стейплс
источник