4.01. Цифровые сигналы и GPIO.md


В основе работы любого микроконтроллера лежит простой, но очень мощный принцип: он — цифровое устройство. Это означает, что он «думает» и оперирует не словами или плавными значениями, а всего лишь двумя состояниями: 1 и 0. Для микроконтроллера весь мир сводится к языку из двух «слов»: «включено» и «выключено». Эти два состояния лежат в основе цифрового сигнала, с помощью которого плата общается с внешним миром.

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

В отличие от аналогового сигнала (например, звука или яркости света), который может плавно изменяться, цифровой сигнал дискретен. Он может принимать только два чётких значения:

  • Высокий уровень (HIGH). Соответствует логической единице (1).
  • Низкий уровень (LOW). Соответствует логическому нулю (0).

На физическом уровне эти состояния представлены напряжением. Для Рудирона это означает:

  • Высокий уровень (HIGH) — это напряжение, близкое к напряжению питания микроконтроллера, то есть 3.3 В.
  • Низкий уровень (LOW) — это напряжение, близкое к земле (GND), то есть 0 В.

Важная особенность Рудирона! Его пины толерантны к 5 В. Это значит, что, хотя сам микроконтроллер работает от 3.3 В, на его входы можно безопасно подавать сигналы с напряжением до 5 В. Это очень удобно, так как позволяет подключать огромное количество модулей и датчиков, рассчитанных на 5-вольтовую логику (например, от популярных плат Arduino), без дополнительных преобразователей уровней.

Графически цифровой сигнал выглядит как последовательность прямоугольных импульсов — он либо на высоком уровне, либо на низком, без промежуточных значений.

Но как микроконтроллер отправляет и принимает эти сигналы? Через свои «уста и уши» — порты ввода-вывода GPIO.

Порты GPIO

GPIO (General-Purpose Input/Output) — это универсальные выводы на плате, которые работают с цифровыми сигналами. Каждый такой пин можно настроить на одну из двух ролей:

  • Вывод (OUTPUT). Пин становится «ртом» микроконтроллера. Он отправляет сигнал вовне, устанавливая на выходе либо HIGH (3.3 В), либо LOW (0 В). Так можно зажечь светодиод или включить реле.
  • Ввод (INPUT). Пин становится «ухом» микроконтроллера. Он «слушает» напряжение, которое на него подаётся извне, и определяет, является ли оно высоким (HIGH) или низким (LOW). Так можно узнать, нажата ли кнопка.

Для управления этими процессами в ядре Рудирон есть три ключевые функции: pinMode(), digitalWrite() и digitalRead().

Настройка пина — функция pinMode()

Прежде чем использовать пин, микроконтроллеру нужно сообщить его роль. Для этого используется функция pinMode(), которую обычно вызывают один раз в блоке setup().

Синтаксис функции:

pinMode(номерПина, режим);
  • номерПина - номер пина Рудирон, который вы настраиваете.
  • режим - одно из ключевых слов, определяющих роль пина.

  • Режим OUTPUT: Пин настроен на вывод сигнала. Он может подавать напряжение.

    const int ledPin = 5;
    void setup() {
      pinMode(ledPin, OUTPUT); // Пин 5 будет отправлять сигналы
    }
    
  • Режим INPUT: Пин настроен на приём сигнала. Он «слушает» входящее напряжение.

    const int buttonPin = 35;
    void setup() {
      pinMode(buttonPin, INPUT); // Пин 35 будет считывать сигналы
    }
    

    Однако в этом режиме возникает проблема, если к пину ничего не подключено (например, кнопка не нажата), он находится в «плавающем» состоянии. Он ловит электрические помехи из воздуха, как антенна, и может считывать случайные значения — HIGH или LOW. Чтобы этого избежать, используют подтягивающие резисторы.

  • Подтяжка пинов — INPUT_PULLUP и INPUT_PULLDOWN, чтобы пин в режиме INPUT всегда имел определённое состояние, его можно «подтянуть» к высокому или низкому уровню с помощью встроенных в микроконтроллер резисторов.

    • INPUT_PULLUP - пин внутренне подключается к 3.3 В через резистор. По умолчанию он всегда находится в состоянии HIGH. Если к такому пину подключить кнопку, которая при нажатии соединяет его с землёй (GND), то при нажатии пин перейдёт в состояние LOW. Это самый распространённый способ подключения кнопок в мире Arduino.
    • INPUT_PULLDOWN - пин внутренне подключается к GND. По умолчанию он всегда LOW. При подаче на него напряжения 3.3 В он перейдёт в HIGH. Именно по такой схеме подключены встроенные кнопки на плате Рудирон.
    // Для встроенных кнопок Рудирона используем INPUT_PULLDOWN
    pinMode(BUTTON_BUILTIN_1, INPUT_PULLDOWN); 
    

Управление пином — функция digitalWrite()

Когда пин настроен как OUTPUT, функция digitalWrite() позволяет установить на нём нужный уровень сигнала.

Синтаксис функции:

digitalWrite(номерПина, состояние); // состояние - HIGH или LOW

Пример (мигание встроенным светодиодом L1):

void setup() {
  pinMode(LED_BUILTIN_1, OUTPUT);
}
void loop() {
  digitalWrite(LED_BUILTIN_1, HIGH); // Подаём 3.3 В, светодиод горит
  delay(1000);
  digitalWrite(LED_BUILTIN_1, LOW);  // Подаём 0 В, светодиод гаснет
  delay(1000);
}

Чтение состояния пина — функция digitalRead()

Когда пин настроен как INPUT, функция digitalRead() считывает его состояние.

Синтаксис функции:

состояниеПина = digitalRead(номерПина); // Вернёт HIGH или LOW

Пример (управление светодиодом L1 с помощью кнопки B1):

void setup() {
  pinMode(LED_BUILTIN_1, OUTPUT);
  // Встроенная кнопка B1 на Рудироне уже подтянута к земле (PULLDOWN)
  pinMode(BUTTON_BUILTIN_1, INPUT_PULLDOWN); 
}
void loop() {
  // Считываем состояние кнопки B1
  int buttonState = digitalRead(BUTTON_BUILTIN_1); 

  if (buttonState == HIGH) { // Если кнопка нажата (сигнал HIGH)
    digitalWrite(LED_BUILTIN_1, HIGH); // Включаем светодиод
  } else {
    digitalWrite(LED_BUILTIN_1, LOW);  // Иначе выключаем
  }
}

Зачем это нужно?

GPIO — это мост между цифровым миром микроконтроллера (его нулями и единицами) и физическим миром (светом, звуком, движением). Функции pinMode(), digitalWrite() и digitalRead() — это ваш основной набор инструментов для строительства этого моста. Освоив их, вы сможете создавать интерактивные устройства, которые реагируют на действия пользователя и управляют внешними компонентами.


Теперь, когда вы знаете, как микроконтроллер работает с цифровыми сигналами, самое время решить, что делать дальше. Если вы готовы применить знания на практике, переходите к лабораторным работам, чтобы своими руками зажечь светодиоды. А если вам не терпится узнать, как управлять яркостью плавно, отправляйтесь в следующий параграф, где мы изучим аналоговые сигналы и ШИМ.