Мікроконтролери призначені для керування електронікою пристроїв найрізноманітнішого призначення — від побутових приладів до дронів і роботів. Вони отримують інформацію від датчиків, кнопок чи інших елементів, обробляють її за допомогою програми й віддають команди виконавчим пристроям, наприклад двигунам, світлодіодам або дисплеям. Інколи мікроконтролери також передають дані іншим системам, наприклад через інтерфейси UART, I²C або SPI.
Зв’язок чіпа мікроконтролера з іншими електронними компонентами забезпечують порти вводу-виводу (I/O-порти).
Порт мікроконтролера — це набір фізичних ніжок-виводів (пінів), якими можна керувати з програми. Кожен пін може працювати в одному з двох основних режимів:
-
вивід (output) — коли програма керує вихідною напругою на піну, встановлюючи високий або низький рівень (наприклад, щоб вмикати-вимикати світлодіод),
-
ввід (input) — коли пін «слухає» зовнішній сигнал, наприклад натискання кнопки.
Таким чином, через порти мікроконтролер обмінюється інформацією з зовнішнім світом. Зазвичай він має кілька портів (A, B, C тощо), кожен з яких містить певну кількість пінів (часто 8).
На малюнку показано приклад мікроконтролера. Праворуч розташовані піни порту A, що працює в режимі виводу. До кожного піна через резистор під’єднано світлодіод. У програмі можна керувати цими пінами, вмикаючи або вимикаючи відповідні світлодіоди. Зверніть увагу, що тут назви пінів складаються з літери порту та номера піна — наприклад, PA0 означає «пін 0 порту A». У реальних мікроконтролерах порти та їхні позначення відрізняються. Тому для роботи з конкретним чіпом варто звертатися до його документації — datasheet, де вказано повну розпіновку, характеристики портів і можливі режими роботи.
Кожен порт мікроконтролера складається з кількох пінів, і керування ними здійснюється через спеціальні регістри.
-
DDRx (Data Direction Register) — задає напрямок піну: ввід чи вивід.
-
PORTx — встановлює логічний рівень на вихідних пінах або вмикає внутрішні підтягувальні резистори для вводу.
-
PINx — дозволяє зчитувати поточний стан піну.
Тут x — літера порту (B, C, D тощо). Саме через ці регістри мікроконтролер отримує інформацію від зовнішніх пристроїв і керує ними. Таким чином на кожен порт є свій набір регістрів DDRx, PORTx і PINx
Щоб спростити сприйняття, далі ми будемо використовувати приклади на платі Arduino. На перший погляд здається, що тут немає портів, бо ми працюємо з цифровими пінами D0–D13. Насправді порти все одно присутні — Arduino просто приховує складність регістрів і робить роботу з піном більш дружньою: замість DDRx/PORTx/PINx ми використовуємо функції pinMode(), digitalWrite() і digitalRead().
Таким чином, основна концепція GPIO лишається тією ж: пін може працювати як ввідний або вивідний, а плата обмінюється сигналами зі світом через ці піни. Arduino дозволяє зосередитися на практичних прикладах без потреби заглиблюватися в деталі регістрів.
Режими вводу і виводу
Робота з пінами — це основа взаємодії програми з реальним світом електроніки. Через них плата отримує сигнали від кнопок і сенсорів або керує світлодіодами, двигунами та іншими пристроями.
На платі Arduino ми працюємо з пінами D0–D13 (а також A0–A5). Кожен пін може працювати в одному з двох основних режимів:
-
OUTPUT — пін відправляє сигнал (керує пристроєм);
-
INPUT — пін зчитує зовнішній сигнал.
Режим виводу (OUTPUT)
Припустимо, до піна 13 під’єднано світлодіод (на Arduino Uno він уже вбудований). Найпростіший приклад:
void setup() { //функція викликається 1 раз на старті програмиpinMode(13, OUTPUT); // встановлюємо режим виводу}void loop() { //основний цикл програмиdigitalWrite(13, HIGH); // увімкнути світлодіодdelay(200);digitalWrite(13, LOW); // вимкнутиdelay(200);}
Що відбувається в коді:
- Виклик функції
pinMode(13, OUTPUT)налаштовує пін 13 як вихід. На рівні мікроконтролера це означає, що в регістрі напрямку (DDRx) відповідний біт встановлюється в 1. - Виклик
digitalWrite(13, HIGH)- на піні з’являється логічна 1 (близько 5 В або 3.3 В залежно від плати). На рівні регістрів це запис у PORTx. digitalWrite(13, LOW)- встановлює логічний 0 на виході 13.
Таким чином ми керуємо світлодіодом, змінюючи логічний рівень на піні.
Можна під’єднати кілька світлодіодів до різних пінів і керувати ними незалежно:
void setup() {pinMode(8, OUTPUT);pinMode(9, OUTPUT);pinMode(10, OUTPUT);pinMode(11, OUTPUT);}void loop() {digitalWrite(8, HIGH);digitalWrite(9, LOW);digitalWrite(10, LOW);digitalWrite(11, LOW);delay(200);digitalWrite(8, LOW);digitalWrite(9, HIGH);delay(200);}
Arduino дозволяє керувати кожним піном окремо, хоча на рівні мікроконтролера ці піни можуть належати до одного й того самого порту. Тобто порти фізично існують, але Arduino приховує їх від нас і дає зручний інтерфейс для роботи з окремими пінами.
Режим вводу (INPUT)
Окрім керування пристроями, плата повинна отримувати сигнали. Найпростіший приклад — кнопка. Під’єднаємо кнопку до піна 2 так, щоб при натисканні вона з’єднувала пін із землею.
void setup() {pinMode(2, INPUT_PULLUP); // ввід із внутрішнім підтягуваннямpinMode(13, OUTPUT);}void loop() {if (digitalRead(2) == LOW) {digitalWrite(13, HIGH); // кнопка натиснута} else {digitalWrite(13, LOW); // кнопка не натиснута}}
Зверніть увагу на виклик pinMode(2, INPUT_PULLUP), він вмикає режим вводу і одночасно активує внутрішній підтягувальний резистор.
На рівні регістрів біт у DDRx встановлюється в 0 (ввід) і у PORTx записується 1 — це і вмикає підтягування.
Чому потрібен підтягувальний резистор?
Без нього пін залишався б у “підвішеному стані” — він міг би випадково змінювати значення через електричні шуми. Підтягування забезпечує стабільний логічний рівень, коли кнопка не натиснута. У такій схемі: кнопка не натиснута → пін читає HIGH, кнопка натиснута → пін з’єднаний із землею → LOW.
Детальніше про підключення приладів до пінів можна почитати в статті Підключення приладів вводу/виводу до мікроконтролера
Зверніть увагу
У Arduino ми працюємо з окремими пінами через зручні функції:
pinMode()— визначає режим,digitalWrite()— встановлює стан,digitalRead()— зчитує стан.
Проте всередині мікроконтролера все одно існують порти й регістри! Arduino просто приховує цю складність, дозволяючи зосередитися на логіці програми.
Альтернативні функції портів
Розглянуті вище піни називаються GPIO (General Purpose Input/Output) — піни загального призначення. Вони керуються одночасно, тому їх ще називають паралельними портами.
Але кожен пін може виконувати не лише базові функції вводу-виводу. У сучасних мікроконтролерах один і той самий пін може мати декілька призначень:
-
Аналогові входи — для вимірювання напруги за допомогою вбудованого АЦП.
-
PWM-виходи (ШІМ) — мікроконтролер швидко вмикає і вимикає сигнал, створюючи «псевдоаналогову» напругу. Це дозволяє керувати, наприклад, яскравістю світлодіода або швидкістю двигуна.
-
Комунікаційні лінії — ті самі піни можуть передавати дані через UART, I²C або SPI.
Таким чином, фізично один і той самий пін може виконувати різні ролі, і потрібну функцію зазвичай обирають у програмі при налаштуванні плати, але це вже тема для іншої статті...
