دسته‌بندی نشده

I2C یا SPI یا UART؟ راهنمای انتخاب پروتکل مناسب برای هر پروژه

M98 MAKATRONIC98 • EMBEDDED COMMUNICATION LAB
میکروکنترلر و ارتباطات دیجیتال • سطح صفر تا کاربردی

I2C، SPI و UART چیست؟ سه زبان اصلی ارتباط بین میکروکنترلر، سنسور، نمایشگر و ماژول‌ها را ساده اما عمیق یاد بگیریم

وقتی ESP32، Arduino یا هر میکروکنترلری را به سنسور، نمایشگر، حافظه یا ماژول GPS وصل می‌کنیم، قطعات باید با یک «قانون مشترک» با هم حرف بزنند. I2C، SPI و UART سه روش بسیار رایج برای همین کار هستند. در این آموزش نه‌فقط اسم پایه‌ها، بلکه منطق پشت Clock، Address، ACK، Baud Rate، Chip Select و انتخاب پروتکل مناسب را قدم‌به‌قدم یاد می‌گیریم.

I2C SPI UART ESP32 Arduino
I2C۲ خط + آدرس
SPIسریع + Clock مشترک
UARTساده + بدون Clock
هدف مقالهانتخاب درست پروتکل
10+
توضیح خیلی ساده:

I2C شبیه یک کلاس است که همه روی یک خط مشترک‌اند و هر نفر شماره دارد؛ SPI شبیه گفت‌وگوی خیلی سریع با یک زنگ مشترک است؛ UART هم شبیه دو نفر است که بدون زنگ، فقط از قبل روی سرعت حرف‌زدن توافق کرده‌اند.

01سریال
02Clock یا بدون Clock
03Address یا Select
04Frame و Timing
05انتخاب پروتکل

اول: ارتباط سریال یعنی چه؟

فرض کنید می‌خواهیم عدد 10110110 را از یک میکروکنترلر به یک سنسور یا نمایشگر بفرستیم. در ارتباط سریال، بیت‌ها یکی پس از دیگری روی یک یا چند خط حرکت می‌کنند.

10110110 → زمان

نکته اصلی این است که دو طرف باید بدانند هر بیت چه زمانی معتبر است، شروع و پایان پیام کجاست و داده متعلق به کدام دستگاه است. I2C، SPI و UART هرکدام این مسئله را به روش متفاوتی حل می‌کنند.

I²C

Clock مشترک + Address

دو خط اصلی بین همه دستگاه‌ها مشترک‌اند و دستگاه‌ها با آدرس شناخته می‌شوند.

SPI

Clock مشترک + Select

ارتباط سریع و هم‌زمان ارسال/دریافت؛ هر Client معمولاً یک خط Select دارد.

U

بدون Clock مشترک

هر دو طرف از قبل روی Baud Rate و ساختار Frame توافق می‌کنند.

I2C چیست؟

I2C مخفف Inter-Integrated Circuit است. این باس برای ارتباط بین ICها طراحی شده و در حالت‌های معمول فقط دو خط اصلی دارد:

SDASerial Dataداده
SCLSerial Clockکلاک

طبق مشخصات NXP، I2C یک باس دو سیمه با SDA و SCL است و دستگاه‌ها می‌توانند با آدرس نرم‌افزاری روی همان باس شناخته شوند. نسخه جاری مشخصات NXP در Rev. 7.0 از اصطلاح‌های Controller و Target استفاده می‌کند.

اصطلاح قدیمی را هم بشناسید: در دیتاشیت‌ها و کتابخانه‌های قدیمی ممکن است هنوز Master/Slave ببینید. در مستندات جدیدتر NXP، Controller/Target جایگزین این اصطلاح‌ها شده است.

چرا I2C فقط با دو سیم می‌تواند چند دستگاه را کنترل کند؟

چون هر Target معمولاً یک Address دارد. Controller ابتدا آدرس دستگاه موردنظر را روی باس می‌فرستد؛ فقط همان دستگاه پاسخ می‌دهد.

MCU
Controller
SDA
SCL
OLED 0x3C
Sensor 0x76
EEPROM 0x50

این آدرس‌ها فقط مثال آموزشی هستند؛ آدرس واقعی هر قطعه را باید از دیتاشیت همان قطعه بررسی کنید.

I2C چقدر سریع است؟

100 kbit/sStandard-mode
400 kbit/sFast-mode
1 Mbit/sFast-mode Plus
3.4 Mbit/sHigh-speed
5 Mbit/sUltra Fast-mode*

*Ultra Fast-mode حالت یک‌طرفه خاصی است و با I2C معمول دوطرفه تفاوت‌هایی دارد. برای بیشتر پروژه‌های Arduino و ESP32، سرعت‌های 100kHz و 400kHz بسیار رایج‌ترند.

یک پیام I2C از چه قسمت‌هایی ساخته می‌شود؟

START ADDRESS R/W ACK DATA ACK DATA ACK/NACK STOP

START چیست؟

Controller با یک وضعیت مشخص روی SDA و SCL اعلام می‌کند: «از اینجا یک انتقال جدید شروع می‌شود.»

Address و R/W چیست؟

در آدرس‌دهی رایج 7 بیتی، Controller آدرس Target را می‌فرستد و مشخص می‌کند عملیات Read است یا Write. I2C همچنین آدرس‌دهی 10 بیتی را تعریف می‌کند، ولی 7 بیتی در پروژه‌های معمول بسیار رایج‌تر است.

ACK و NACK چیست؟

بعد از هر Byte، یک بیت نهم برای پاسخ وجود دارد. اگر Receiver داده را پذیرفته باشد، معمولاً با ACK پاسخ می‌دهد. NACK می‌تواند معنای «پاسخ ندادم / داده بیشتری نمی‌خواهم / دستگاه حاضر نیست» داشته باشد؛ معنای دقیق به موقعیت Frame بستگی دارد.

8 Data Bits10110110
9th ClockACK = SDA LOW

Repeated START چیست؟

Controller می‌تواند بدون آزاد کردن باس با STOP، یک START دوباره ایجاد کند. این قابلیت در خواندن Registerها بسیار مهم است: ابتدا شماره Register نوشته می‌شود و سپس جهت ارتباط به Read تغییر می‌کند.

چرا I2C به مقاومت Pull-up نیاز دارد؟

SDA و SCL در I2C معمولاً به‌صورت Open-drain/Open-collector کار می‌کنند: دستگاه‌ها خط را به LOW می‌کشند، ولی HIGH شدن خط توسط Pull-up انجام می‌شود.

VCC
RP
SDA / SCL
MCUSensorOLED

مقدار Pull-up یک عدد جادویی ثابت نیست. ولتاژ، ظرفیت باس، سرعت I2C و توان Pull-down دستگاه‌ها روی انتخاب آن اثر دارند. به همین دلیل 4.7kΩ یک مقدار رایج آموزشی است، اما همیشه «مقدار درست» نیست.

اشتباه رایج: اگر چند ماژول I2C دارید، ممکن است هرکدام روی برد خودش Pull-up داشته باشد. موازی شدن چند Pull-up مقاومت معادل را پایین می‌آورد و می‌تواند جریان LOW را زیاد کند.

Clock Stretching چیست؟

بعضی Targetها می‌توانند SCL را برای مدتی LOW نگه دارند و به Controller بگویند: «هنوز آماده نیستم.» این قابلیت Clock Stretching نام دارد و در مشخصات I2C وجود دارد، هرچند همه Controllerها و کتابخانه‌ها آن را به یک شکل پشتیبانی نمی‌کنند.

SPI چیست؟

SPI یا Serial Peripheral Interface یک ارتباط سریال سنکرون است که برای ارتباط کوتاه‌برد و سریع بین تجهیزات Embedded بسیار استفاده می‌شود.

SCKClock از Host
MOSIHost → Client
MISOClient → Host
SS / CSانتخاب Client

در نام‌گذاری جدید Microchip از Host/Client استفاده می‌شود. MOSI و MISO اصطلاح‌های بسیار رایجی هستند، اما در بعضی دیتاشیت‌های جدید ممکن است نام‌های دیگری مثل SDO/SDI یا COPI/CIPO هم ببینید.

SPI چرا سریع است؟

SPI آدرس‌دهی I2C و ACK بعد از هر Byte را ذاتاً ندارد و برای ارسال و دریافت خطوط جدا دارد. در ساختار معمول Full-duplex، هم‌زمان که یک بیت روی MOSI خارج می‌شود، یک بیت از MISO وارد می‌شود.

HOST
MOSI →→→→ ←←←← MISO SCK →→→→
CLIENT
سرعت SPI یک عدد استاندارد جهانی ثابت نیست. حداکثر Clock را دیتاشیت Host، Client، Layout و شرایط الکتریکی تعیین می‌کنند. بعضی سنسورها چند MHz و بعضی Flashها یا نمایشگرها ده‌ها MHz را پشتیبانی می‌کنند.

چند Client را چطور وصل کنیم؟

MOSI، MISO و SCK معمولاً مشترک‌اند، اما هر Client یک SS/CS جدا می‌گیرد.

MCU
SCK / MOSI / MISO CS1CS2CS3
Display
Flash
ADC

نتیجه این است که اضافه کردن Clientهای بیشتر در SPI می‌تواند GPIO بیشتری برای Chip Select مصرف کند.

SPI Mode چیست؟ CPOL و CPHA را خیلی ساده بفهمیم

دو طرف باید روی این موضوع توافق داشته باشند که Clock در حالت Idle چه سطحی دارد و داده روی کدام لبه نمونه‌برداری می‌شود. ترکیب این دو مفهوم چهار Mode معروف SPI را می‌سازد.

ModeCPOLCPHAایده کلی
000Clock Idle LOW
101Clock Idle LOW
210Clock Idle HIGH
311Clock Idle HIGH
اگر Mode اشتباه باشد، سیم‌کشی ممکن است کاملاً درست باشد ولی داده خراب دیده شود. همیشه CPOL/CPHA یا SPI Mode را از دیتاشیت قطعه بررسی کنید.

UART چیست؟

UART مخفف Universal Asynchronous Receiver/Transmitter است. کلمه مهم اینجا Asynchronous است: UART خط Clock جداگانه بین دو دستگاه ندارد.

TXارسال
RXدریافت
GNDمرجع مشترک

برای اتصال ساده:

MCU TX Module RX
MCU RX Module TX
MCU GND Module GND

اگر Clock نداریم، Receiver از کجا می‌فهمد بیت‌ها کجا هستند؟

دو طرف از قبل روی سرعت ارتباط یا Baud Rate توافق می‌کنند. Receiver لبه Start Bit را پیدا می‌کند و سپس بر اساس Timing داخلی خودش بیت‌ها را نمونه‌برداری می‌کند.

Baud Rate و 8N1 چیست؟

یکی از تنظیمات بسیار رایج UART مثلاً این است:

115200 8N1
115200Baud Rate
8Data Bits
NNo Parity
1Stop Bit

Frame UART چگونه است؟

START D0D1D2D3 D4D5D6D7 STOP

UART می‌تواند Parity اختیاری داشته باشد و تعداد Data/Stop Bit بسته به سخت‌افزار قابل تنظیم است. نکته مهم این است که فرستنده و گیرنده باید تنظیمات سازگار داشته باشند.

UART با RS-232 و RS-485 یکی است؟

خیر. UART روش قالب‌بندی و جابه‌جایی سریال داده در سطح منطقی است. RS-232 و RS-485 بیشتر درباره لایه الکتریکی/فیزیکی انتقال صحبت می‌کنند. مثلاً خروجی UART یک MCU را نباید بدون Driver مناسب مستقیماً به پورت واقعی RS-232 قدیمی وصل کرد.

UART TTL/CMOS ≠ RS-232. سطح ولتاژ و قطبیت الکتریکی می‌تواند کاملاً متفاوت باشد.

مقایسه کامل I2C، SPI و UART

ویژگیI2CSPIUART
Clock مشترکداردداردندارد
خطوط پایه معمولSDA + SCLSCK + MOSI + MISO + CSTX + RX
چند دستگاه روی باسخیلی مناسبممکن، با CSهای بیشترمعمولاً Point-to-Point
روش انتخاب دستگاهAddressChip Selectمعمولاً لینک مستقیم
Full Duplexخیر، SDA مشترک دوطرفهمعمولاً بلهبله با TX/RX مستقل
ACK داخلی پروتکلداردذاتاً نداردذاتاً ندارد
Pull-up ویژه باسمعمولاً لازم استمعمولاً نهمعمولاً نه
پیچیدگی سیم‌کشی چند Deviceکمبیشتربرای هر لینک جدا
کاربرد نمونهSensor / OLED / RTCTFT / Flash / ADCGPS / Debug / Modem

کدام پروتکل سریع‌تر است؟

اگر فقط یک پاسخ بسیار کلی بخواهیم، SPI در بسیاری از پروژه‌های Embedded برای Throughput بالا انتخاب رایجی است. اما مقایسه «سرعت پروتکل» بدون دیتاشیت دقیق می‌تواند گمراه‌کننده باشد.

چرا؟ I2C سرعت‌های استاندارد تعریف‌شده دارد؛ SPI سقف ثابت جهانی ندارد و محدودیت آن وابسته به قطعات است؛ UART هم Baud Rateهای قابل پشتیبانی متفاوتی در سخت‌افزارهای مختلف دارد.

کدام را برای پروژه خودمان انتخاب کنیم؟

برای سنسورها و چند Device با سیم کم، معمولاً اول I2C را بررسی کن.

یک راهنمای خیلی سریع

📟OLED کوچک + چند SensorI2C
🖥️TFT سریعSPI
🛰️GPS ModuleUART
💾Flash Memory سریعSPI
🕒RTC + EEPROMI2C
🛠️Debug SerialUART

مثال عملی با ESP32 / Arduino

این مثال‌ها برای فهم API هستند؛ پایه‌ها و Address/Mode واقعی را با برد و دیتاشیت خودتان تطبیق دهید.

مثال I2C: اسکن آدرس‌ها

Arduino / ESP32I2C Scanner
#include <Wire.h>

void setup() {
  Serial.begin(115200);
  Wire.begin();

  Serial.println("I2C Scan:");

  for (uint8_t address = 1; address < 127; address++) {
    Wire.beginTransmission(address);
    uint8_t error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("Device found at 0x");
      if (address < 16) Serial.print("0");
      Serial.println(address, HEX);
    }
  }
}

void loop() {
}

Scanner به شما کمک می‌کند ببینید چه Addressهایی روی باس ACK می‌دهند. اگر هیچ دستگاهی پیدا نشد، تغذیه، GND، SDA/SCL و Pull-upها را بررسی کنید.

مثال SPI: انتقال یک Byte

ArduinoSPI Transfer
#include <SPI.h>

const int CS_PIN = 5;

void setup() {
  Serial.begin(115200);

  pinMode(CS_PIN, OUTPUT);
  digitalWrite(CS_PIN, HIGH);

  SPI.begin();
}

void loop() {
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));

  digitalWrite(CS_PIN, LOW);
  uint8_t received = SPI.transfer(0xA5);
  digitalWrite(CS_PIN, HIGH);

  SPI.endTransaction();

  Serial.println(received, HEX);
  delay(1000);
}
SPI_MODE0 و 1MHz فقط مثال هستند. Clock، Mode و ترتیب Bit باید مطابق دیتاشیت Client انتخاب شوند.

مثال UART: ارسال پیام

Arduino / ESP32UART 115200
void setup() {
  Serial.begin(115200);
}

void loop() {
  Serial.println("Hello from MAKATRONIC98");
  delay(1000);
}

سطح ولتاژ را فراموش نکنید

پروتکل صحیح به معنی ولتاژ صحیح نیست. یک ESP32 معمولاً منطق 3.3V دارد و یک ماژول دیگر ممکن است 5V یا 1.8V باشد.

3.3V MCU3.3V Sensorمعمولاً مستقیم
3.3V MCU5V Signalنیاز به بررسی دقیق

در I2C این موضوع حساس‌تر هم می‌شود چون Pull-up تعیین می‌کند سطح HIGH باس به چه ولتاژی بالا برود. Level Shifterهای مناسب I2C برای اتصال دامنه‌های ولتاژ متفاوت استفاده می‌شوند.

خطاهای رایج هر پروتکل

I2C
  • Pull-up فراموش شده
  • Address اشتباه
  • SDA و SCL جابه‌جا
  • ظرفیت باس زیاد
  • Level Voltage نامناسب
  • Clock Stretching ناسازگار
SPI
  • CS اشتباه
  • SPI Mode اشتباه
  • Clock بیش از حد
  • MOSI/MISO جابه‌جا
  • دو Client هم‌زمان MISO را Drive می‌کنند
  • سیم بلند و Signal Integrity ضعیف
UART
  • TX به TX وصل شده
  • GND مشترک نیست
  • Baud Rate متفاوت
  • Parity/Stop Bit متفاوت
  • سطح ولتاژ اشتباه
  • UART با RS-232 اشتباه گرفته شده

Logic Analyzer چطور به ما کمک می‌کند؟

Logic Analyzer یکی از بهترین ابزارها برای فهم و عیب‌یابی این پروتکل‌هاست. به‌جای اینکه فقط ببینیم «کار نمی‌کند»، می‌توانیم Timing و Byteهای واقعی روی سیم را ببینیم.

CH0I2C SDA CH1I2C SCL
START0x3C WACK0x00ACKSTOP

Decoder نرم‌افزار Logic Analyzer می‌تواند در I2C آدرس و ACK، در SPI Byteها، و در UART داده را با Baud Rate مشخص Decode کند.

آیا I2C از SPI بهتر است؟

سؤال «کدام بهتر است؟» معمولاً جواب مطلق ندارد. طراحی خوب یعنی پروتکل را بر اساس نیاز انتخاب کنیم:

سیم کم + چند سنسورI2C
سرعت بالا + نمایشگر/FlashSPI
ارتباط ساده دو دستگاهUART

اصطلاحات مهمی که باید حفظ باشیم

SDAخط داده I2C
SCLخط Clock در I2C
ACKتأیید دریافت در I2C
SCKClock در SPI
MOSIHost به Client
MISOClient به Host
CS / SSانتخاب Client در SPI
TXارسال UART
RXدریافت UART
Baudنرخ سمبل/زمان‌بندی UART

سه اشتباه مفهومی مهم

«I2C همیشه فقط دو سیم دارد»

از نظر سیگنال باس SDA و SCL دو خط اصلی هستند؛ اما در مدار واقعی تغذیه و GND هم وجود دارند و ممکن است Interrupt یا Reset جداگانه نیز بین ماژول و MCU داشته باشیم.

«SPI همیشه دقیقاً چهار سیم است»

ساختار رایج SCK/MOSI/MISO/CS است، اما بعضی کاربردها MISO ندارند، برخی دستگاه‌ها چند Data Line دارند، و با چند Client تعداد CSها بیشتر می‌شود.

«UART همان Serial Monitor است»

Serial Monitor یک ابزار نرم‌افزاری است. UART Peripheral سخت‌افزاری است که داده سریال Asynchronous را ایجاد یا دریافت می‌کند. روی بعضی بردها USB-to-UART بین کامپیوتر و MCU قرار دارد.

سؤالات متداول

برای سنسور، I2C بهتر است یا SPI؟

اگر سرعت خیلی بالا لازم ندارید و چند سنسور با سیم کم می‌خواهید، I2C اغلب راحت‌تر است. اگر سنسور SPI دارد و نرخ نمونه‌برداری بالا مهم است، SPI می‌تواند مناسب‌تر باشد.

چرا I2C به Pull-up نیاز دارد؟

چون خطوط باس در حالت‌های معمول توسط خروجی‌های Open-drain به LOW کشیده می‌شوند و Pull-up مسئول بالا بردن خط به HIGH است.

آیا می‌توان دو دستگاه I2C با آدرس یکسان وصل کرد؟

روی یک Bus معمولی، دو Target با آدرس یکسان هم‌زمان قابل تفکیک نیستند؛ مگر Address قابل تغییر باشد یا از Multiplexer/Switch I2C استفاده کنید.

SPI حداکثر چه سرعتی دارد؟

یک سقف واحد برای همه SPIها وجود ندارد. حداکثر SCK را دیتاشیت Host و Client، کیفیت سیگنال و طراحی PCB مشخص می‌کنند.

چرا UART متن عجیب نشان می‌دهد؟

اول Baud Rate، Data Bits، Parity و Stop Bit را بررسی کنید. Baud اشتباه یکی از دلایل بسیار رایج نمایش کاراکترهای نامفهوم است.

TX را باید به RX وصل کنیم؟

در UART دو دستگاه معمولاً TX هر دستگاه به RX دستگاه مقابل وصل می‌شود و GND مشترک نیز لازم است.

کدام پروتکل برای OLED بهتر است؟

بستگی به خود نمایشگر دارد. OLEDهای کوچک زیادی با I2C عرضه می‌شوند؛ اگر سرعت Refresh بالاتر مهم باشد و مدل نمایشگر SPI داشته باشد، SPI می‌تواند گزینه مناسب‌تری باشد.

جمع‌بندی؛ سه پروتکل را با سه سؤال به یاد بسپارید

I2C «آدرس تو چیست؟»

دو خط مشترک، چند دستگاه، ACK و Address.

SPI «کدام Client انتخاب شده؟»

Clock سریع، خطوط ارسال/دریافت جدا و Chip Select.

UART «روی چه سرعتی توافق کردیم؟»

بدون Clock مشترک، TX/RX و Frame مبتنی بر Baud Rate.

اگر این سه سؤال در ذهنتان بماند، هنگام دیدن یک ماژول جدید خیلی سریع می‌توانید ساختار ارتباطش را تشخیص دهید. بعد از آن فقط کافی است دیتاشیت همان قطعه را برای Pinout، سرعت، Address، Mode و Timing دقیق بخوانید.

آموزش I2C روی ESP32 از صفر آموزش SPI و SPI Modeها UART چیست؟ از Baud Rate تا RS-485 Logic Analyzer چیست و چگونه استفاده می‌شود؟ CAN Bus چیست؟ I2C Scanner و رفع خطاهای باس

منابع فنی

نکات I2C با Specification رسمی NXP، مباحث SPI با مستندات Microchip و قالب UART با راهنمای فنی Texas Instruments تطبیق داده شده‌اند.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *