Цифровые порты/пины


В уроке про распиновку платы мы обсуждали такое понятие, как GPIO: с англ. General Purpose Input-Output, входы-выходы общего назначения. Теперь надо разобраться с такими понятиями, как пин и порт. Пин – это конкретная нога микроконтроллера, имеющая свой номер, по которому к ней можно обратиться. Порт – это совокупность пинов. Микроконтроллер спроектирован так, чтобы обеспечить хорошее быстродействие, поэтому например пины объединены в порты, в одном порте обычно до 8 пинов (потому что в байте 8 бит). Работая с микроконтроллером напрямую, мы можем за одно действие установить состояние для всех пинов одного порта. Это очень быстро. Уроки у нас базовые, поэтому сегодня поговорим о функциях для работы с пинами, которые нам предлагает Ардуино. Но сначала давайте разберёмся, какие из пинов являются цифровыми. Взглянем на распиновку платы Нано:

Все пины, имеющие название PD*, PC*, PB*, являются GPIO. D, С и B указывает на номер порта, которому принадлежит пин. На плате пины подписаны по-другому, просто по порядку. Таким образом мы видим, что все пины с D0-D13 и A0-A5 являются GPIO, то есть цифровыми входами-выходами. Многие называют пины A0A7 аналоговыми, на некоторых неофициальных распиновках они прям подписаны как analog pin, и это вводит новичков в заблуждение, потому что A0-A5 являются такими же цифровыми пинами, как D0-D13. Но у этих пинов есть дополнительная функция в виде чтения аналогового сигнала. Об этом поговорим в следующем уроке. А вот пины A6 и A7 являются именно аналоговыми, потому что у них есть только выход на АЦП, эти пины не являются GPIO, и с ними нельзя работать функциями для цифровых пинов. Если вы посмотрите на распиновку Arduino UNO, то вообще не найдёте там пинов A6 и A7, то есть УНО хоть и больше НАНО, но возможностей у неё меньше =)

Нумерация пинов


Пины пронумерованы на плате как “цифровые” D* пины и аналоговые A* пины. К цифровым пинам мы будем обращаться просто по их номеру, т.е. D3 это просто 3. С аналоговыми пинами чуть сложнее:

  • Обратиться можно с буквой A (A3, A5)
  • Можно цифрой по порядку после цифровых, так например у Нано последний цифровой – D13, следующий за ним “аналоговый” А0 имеет номер 14, а например A5 имеет номер 19, по которому к нему тоже можно обратиться, что позволяет управлять всеми пинами при помощи циклов

Режимы работы пинов


Цифровой пин может находиться в двух состояниях, вход и выход. В режиме входа пин может считывать напряжение от 0 до напряжения питания МК, а в режиме выхода – выдавать такое же напряжение. Режим работы выбирается при помощи функции pinMode(pin, mode), где pin это номер пина, а mode это режим:

  • mode – режим работы
    • INPUT – вход
    • OUTPUT – выход
    • INPUT_PULLUP – подтянутый к питанию вход

Если со входом/выходом всё понятно, то с подтяжкой давайте разберёмся. В режиме входа пин микроконтроллера не подключен никуда и ловит из воздуха всякие наводки, получая практически случайное значение. Для задания пину “состояния по умолчанию” используют подтяжку резистором к земле или питанию. Вот режим INPUT_PULLUP включает встроенную в микроконтроллер подтяжку пина к питанию. Подробнее об этом, со схемами и примерами я рассказывал в начале вот этого видео урока.

По умолчанию все пины сконфигурированы как входы (INPUT)
Используя информацию из предыдущего пункта и урока о циклах, можно изменить режим работы например для всех пинов с D2 по A5:
for (byte i = 2; i <= 19; i++) {   // с 2 по 19 (D2-D13, A0-A5)
  pinMode(i, OUTPUT);              // делаем выходами
}

Вывод цифрового сигнала


Цифровой пин в режиме выхода (OUTPUT) может генерировать цифровой сигнал, т.е. выдавать напряжение. Так как понятие “цифровой” обычно связано с двумя состояниями, 0 и 1, цифровой пин может выдать 0 или 1, точнее: сигнал низкого или высокого уровня. Сигнал низкого уровня это 0 Вольт, грубо говоря в этом состоянии пин подключается к GND микроконтроллера. Сигнал высокого уровня подключает пин к VCC микроконтроллера, то есть к питанию. Если вы вспомните урок по питанию платы, то поймёте, что сигнал высокого уровня на цифровом пине будет варьироваться в зависимости от того, как питается плата Arduino. При питании от источника 5V на пине будет 5V, при питании от USB с потерей на защитном диоде мы получим около 4.7 Вольт на цифровом пине в режиме выхода с высоким сигналом.

Самый главный момент касательно цифровых пинов: микроконтроллер – это логическое устройство, которое создано для управления другими устройствами при помощи логических (цифровых) сигналов. Под словом логическое я подразумеваю не силовое, то есть питать что-то от микроконтроллера нельзя, за редким исключением. На картинке с распиновкой выше вы можете найти надпись “Absolute MAX per pin 40mA, recommended 20mA“. Это означает, что максимум можно снять с пина 40 миллиампер, а рекомендуется не больше 20 миллиампер. Поверьте, для микроконтроллера это очень много. В других микроконтроллерах ограничение по току на пин может составлять 5-10 мА. Также есть общее ограничение на ток с цифровых пинов – 200 мА: “Absolute MAX 200mA for entire package“. Эту информацию можно найти в любом официальном источнике информации об Arduino и микроконтроллере в целом, в том числе в даташите на микроконтроллер.

Что произойдёт, если снять с пина больше, чем он может отдать? Всё очень просто – он сломается. Что будет, если снять с нескольких пинов больше, чем может отдать микроконтроллер в целом? Правильно – сгорит микроконтроллер. Поэтому ничего мощнее светодиода и маленькой пищалки к микроконтроллеру подключать нельзя. Никаких моторчиков, лампочек, нагревателей, мощных радио-модулей и прочего питать от цифровых пинов нельзя. Цифровые пины служат для подачи команд другим устройствам, например реле/транзисторам для коммутации нагрузок. Но об этом мы поговорим отдельно.

Сейчас вернёмся к вопросу подачи цифрового сигнала: для этого у нас есть функция digitalWrite(pin, value) :

  • pin – цифровой пин МК, подписанный на плате как D. Также например у НАНО это пины A0-A5
  • value – уровень сигнала: HIGH высокий, LOW низкий. Также можно использовать цифры 0 и 1

Пример, в котором пины инициализируются как выходы, и на них подаётся сигнал:

void setup() {
  pinMode(10, OUTPUT);  // D10 как выход
  pinMode(A3, OUTPUT);  // A3 как выход
  pinMode(19, OUTPUT);  // A5 как выход (Nano/UNO)

  digitalWrite(10, HIGH); // высокий сигнал на D10
  digitalWrite(A3, 1);    // высокий сигнал на A3
  digitalWrite(19, 1);    // высокий сигнал на A5
}

void loop() {}
Пин, настроенный как OUTPUT, по умолчанию имеет сигнал LOW

Ещё интересный момент: в старых версиях IDE не было варианта режима работы INPUT_PULLUP, и подтяжка делалась вручную. Запомните, что вот эти два варианта являются равноценными, вы можете встретить второй в старых скетчах из Интернета, не пугайтесь. Оба варианта делают пин подтянутым к питанию в режиме входа

// современный вариант
pinMode(10, INPUT_PULLUP);  // D10 как подтянутый вход

// старый вариант
pinMode(10, INPUT);     // D10 как вход
digitalWrite(10, HIGH); // "подтянуть" D10

Перейдём к чтению цифрового сигнала в режиме INPUT

Чтение цифрового сигнала


Цифровой пин может “измерять” напряжение, но сообщить он может только о его отсутствии (сигнал низкого уровня, LOW) или наличии (сигнал высокого уровня, HIGH), причём отсутствием напряжения считается промежуток от 0 до ~2.1V. Соответственно от ~2.1V до VCC (до 5V) микроконтроллер считает за наличие сигнала высокого уровня. Таким образом микроконтроллер спокойно может работать с логическими устройствами, которые шлют ему высокий сигнал с напряжением 3.3V, он такой сигнал примет как HIGH.

Нельзя подавать на цифровой пин (да и на любой другой пин тоже) напряжение выше напряжения питания микроконтроллера.

Для чтения уровня сигнала на пине используется функция digitalRead(pin), где пин – номер пина согласно подписи на плате. Это пины, подписанные как D, а также пины A0-A5 у Arduino Nano/Uno/Pro Mini. Данная функция возвращает 0, если сигнал низкого уровня, и 1 – если высокого. Простой пример:

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println(digitalRead(5));
}

Данный код будет выводить в порт сигнал на пине D5. Если подключить его проводом к VCC – получим 1, если к GND – получим 0.

Видео


Важные страницы


  • Каталог ссылок на дешёвые Ардуины, датчики, модули и прочие железки с AliExpress у проверенных продавцов
  • Подборка библиотек для Arduino, самых интересных и полезных, официальных и не очень
  • Полная документация по языку Ардуино, все встроенные функции и макро, все доступные типы данных
  • Сборник полезных алгоритмов для написания скетчей: структура кода, таймеры, фильтры, парсинг данных
  • Видео уроки по программированию Arduino с канала “Заметки Ардуинщика” – одни из самых подробных в рунете
Последнее обновление Июль 06, 2019
2019-07-06T10:27:28+03:00