View Categories

GPIO, вход

Режим INPUT #

В данном режиме пин находится в высокоимпедансном состоянии - можно считать, что он подключен к GND последовательно через резистор с сопротивлением в десятки и сотни мегаом - это очень большое сопротивление, практически "обрыв провода", т.е. пин как будто "висит в воздухе". Собственно МК будет измерять напряжение на данном резисторе:

Таким образом, если подключить к нему GND - вольтметр покажет 0, а если подключить VCC - всё это напряжение упадёт на резисторе и МК его измерит. При подключении VCC в цепи пойдёт ничтожно маленький ток (при питании от 5V получится 5 / 100000000 А). Это - измерительная цепь, она практически не потребляет энергию.

Нельзя подавать на пин в режиме входа напряжение выше напряжения питания МК или отрицательное напряжение!

Чтение пина #

Для измерения цифрового сигнала на пине используется функция digitalRead(пин) (цифровое чтение), где пин - номер пина по распиновке. Давайте соберём простую схему и измерим сигнал на пине:

void setup() {
    Serial.begin(115200);
    //pinMode(2, INPUT);    // пин по умолчанию как вход, можно не указывать
}

void loop() {
    bool signal = digitalRead(2);
    Serial.println(signal);
    delay(100);
}

В первом случае в порт будет печататься 1 - высокий сигнал, а во втором - 0 - низкий. Аккуратно подключайте провод поочерёдно к 5V и GND, не отключая плату от компьютера - значение в мониторе порта будет меняться.

Оставьте провод подключенным к D2 и просто держите его в руках или подключите куда-нибудь в свободное место на макетке (справа от платы). С большой вероятностью в порт пойдут случайные значения 001001100111010100101010 - дело в том, что провод как антенна "ловит" различные наводки из воздуха: окружающего оборудования и сетевых проводов.

Какое напряжение на GPIO МК считает за 0, а какое за 1? Это указано в документации на МК, например для Arduino Nano (ATMega328p) за 0 считается напряжение от -0.5 V до 0.3 VCC, а за 1 - от 0.7 VCC до VCC + 0.5, где VCC это напряжение питания. При питании от 5V получится логический ноль при (-0.5.. 1.5)V и единица при (3.5.. 5.5)V

Подтяжка #

Высокоимпедансное состояние удобно тем, что не потребляет энергию. Но у него есть и серьёзный минус - если пин никуда не подключен, то он имеет неопределённое состояние со случайным сигналом. Если в реальном устройстве от такого пина "отвалится" провод - МК начнёт получать с него случайные значения. Страшно представить что случится, если это кнопка - она может "натыкать" в устройстве всё что угодно! Более того, обычно кнопка имеет всего два контакта, то есть может только замыкать и размыкать цепь. Если мы подключим кнопку вот так:

То при нажатии она будет подавать на пин стабильные 5V, их можно будет точно измерить. А вот если отпустить кнопку - пин начнёт получать случайные значения.

У типичной тактовой кнопки контакты соединены следующим образом:

Подключите её и посмотрите что получится. Программа та же, что выше:

При нажатии будет стабильная единица 1, а при отпускании могут пойти случайные значения. Для решения неопределённого поведения используется подтяжка - в схему добавляется резистор с сопротивлением порядка нескольких десятков кОм, который устанавливает на пине стабильное напряжение, пока кнопка не нажата. Подтяжка делается к противоположному от кнопки полюсу - если резистор подтягивает к VCC - подтяжка называется pull-up, если к GND - pull-down:

Если сопротивление подтяжки слишком маленькое (сотни Ом) - через неё будет идти большой ток, если слишком маленькое (сотни кОм) - могут "пробиться" помехи

Добавьте внешнюю подтяжку в схему двумя способами и понажимайте кнопку, программа та же:

В первом случае нажатая кнопка - это сигнал 1, а во втором - 0.

Режим INPUT_PULLUP #

Для удобства подключения кнопок (и не только) МК часто имеют внутреннюю подтяжку в несколько десятков кОм, она активируется через pinMode. В большинстве МК есть только подтяжка к плюсу питания - INPUT_PULLUP. В этом режиме никуда не подключенный пин будет выдавать стабильный высокий сигнал. Давайте добавим этот режим на тот же пин и подключим кнопку без внешних резисторов:

void setup() {
    Serial.begin(115200);
    pinMode(2, INPUT_PULLUP);
}

void loop() {
    bool signal = digitalRead(2);
    Serial.println(signal);
    delay(100);
}

Теперь кнопка может стабильно опрашиваться без внешних резисторов, выдавая 0 при нажатии и 1 при отпускании.

Пин, к которому подключен светодиод на плате (13 на Arduino Nano/UNO) некорректно работает в режиме INPUT_PULLUP - имеет сигнал LOW, так как подключенный светодиод тянет его к GND через свой резистор!

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх