در این بخش در مورد سومین پروتکل پرکاربرد در دنیای میکروکنترلرها، یعنی پروتکل I2C توضیح دهیم.
در نگاه اول شاید I2C از دو پروتکل دیگر کمی پیچیدهتر باشد اما قصد داریم به طور ساده روش کارکرد این پروتکل و راه اندازی آن در آردوینو را بررسی کنیم.
کاربرد پروتکل I2C :
پروتکل I2C Inter-integrated circuit یکی از انواع ارتباط سریال است که برای ارتباط برقرار کردن بین میکروکنترلرهای مختلف یا برای دریافت داده از سنسورهای پیشرفته دیجیتالی مورد استفاده قرار میگیرد.
از این پروتکل در مسافتهای کوتاه (در حد فواصل روی PCB) استفاده میشود.
به عنوان مثال تعدادی از سنسورهای معروف که از این پروتکل استفاده میکنند عبارت است از: DS3231 ، LM75 ، ADXL345 ، انواع ماژولها و…
مشخصات I2C :
- تعداد پایههای کم
- انعظاف پذیری بالا
- امکان اتصال 112 میکروکنترلر یا سنسور
- 10Kbit/s (سرعت کم) 100Kbit/s (سرعت استاندارد)
- مناسب برای مسافت های کوتاه، حداکثر فاصله ارتباط در حد چند متر
پایههای مورد استفاده در ارتباط :
در این ارتباط تنها از دو پایه برای دریافت و ارسال داده استفاده میشود که این مسئله در مقابل پروتکلهایی مانند SPI که حداقل از سه پایه برای ارتباط استفاده میکند، یک مزیت محسوب میشود.
SDA : پایه مربوط به ارسال و دریافت داده.
SCL : پایه مربوط به پالس ساعت برای همزمان کردن ارتباط بین فرستندهها و گیرندهها
نکته : ممکن است در سنسورها و ماژولهای مختلف از اسامی متفاوتی برای پایهها استفاده شود که در این مورد باید به دیتاشیت آن قطعه مراجعه شود.
در بردهای آردوینو : Uno, Pro Mini : A4 (SDA), A5 (SCL) Mega, Due : 20 (SDA), 21 (SCL) Leonardo, Yun : 2 (SDA), 3 (SCL)
مستر و اسلیو :
مشابه ارتباط SPI ، در این ارتباط نیز باید حداقل یک مستر و حداقل یک اسلیو وجود داشته باشد. از جمله مهم ترین وظایف مستر، تولید پالس ساعت بر روی پایه SCL و آدرس دهی اسلیوهای شبکه است.
شکل زیر ارتباط فیزیکی واحدهای اسلیو و مستر را نشان میدهد.
نکته مهم در این شکل، وجود مقاومتهای پول آپ (بالاکش) برای خطوط SDA و SCL است که با توجه به مکانیزم طبقه خروجی واحدهای I2C ، وجود این مقاومتها لازم است. مقدار متداول برای این مقاومتها 4.7K اهم است.
انواع روشهای ارتباط I2C در آردوینو :
با توجه به این که در این پروتکل تنها از یک پایه برای ارسال و دریافت داده استفاده میشود، برای ایجاد ارتباط I2C دو حالت وجود دارد:
- مستر فرستنده، اسلیو گیرنده
- مستر گیرنده، اسلیو فرستنده
حالت اول، مستر فرستنده، اسلیو گیرنده :
در این حالت از توابع زیر برای ارتباط استفاده میشود : (قبل از استفاده از این توابع، باید فایل هدر Wire.h را به برنامه اضافه کنید)
- (begin(Address : در ارتباط I2C ، اسلیوها باید دارای یک آدرس 7 بیتی باشند تا توسط مستر شناخته شوند. اگر این تابع را برای سمت مستر استفاده میکنیم نیازی به استفاده تعیین آدرس وجود ندارد ولی در سمت اسلیو باید در داخل پرانتز و به جای Address مقدار آدرس دلخواه را قرار دهیم.
- (beginTransmission(Address : از این تابع برای شروع ارتباط با اسلیوی که دارای آدرس Address میباشد استفاده میشود.
- (write(X : از این تابع برای ارسال داده مورد نظر (x) به سمت اسلیو استفاده میشود.
- endTransmission : از این تابع برای اتمام ارتباط استفاده میشود.
مثال :
توسط ارتباط I2C ، یک عبارت رشتهای را توسط مستر ارسال کرده و در سمت اسلیو دریافت و در خروجی سریال چاپ کنید.
کد سمت مستر:
#include <Wire.h> void setup() { Wire.begin(); { short age = 0; void loop() { Wire.beginTransmission(2); Wire.write("age is = "); Wire.write(age); Wire.endTransmission(); delay(1000); }
کد سمت اسلیو :
#include <Wire.h> void setup() { Wire.begin(2); Wire.onReceive(receiveEvent); Serial.begin(9600); } void loop() { delay(250); } void receiveEvent(int howMany) { while (Wire.available()>1) { char c = Wire.read(); Serial.print(c); } }
حالت دوم، مستر گیرنده، اسلیو فرستنده:
در این حالت، مستر درخواست مورد نیاز خود را به اسلیو (توسط آدرس) ارسال میکند و در بایتهای بعدی اسلیو دادههای مورد نیاز مستر را ارسال میکند.
از توابع زیر برای این نوع ارتباط استفاده میشود:
- :(Wire.requestFrom(address,number of bytes از این تابع برای درخواست داده از اسلیو استفاده میشود. آرگومان اول این تابع آدرس اسلیو و آرگومان دوم آن تعداد بایتهای مورد نیاز است. پس از ارسال این تابع، دادههای ارسال شده توسط اسلیو توسط دو تابع () available و () wire.read بررسی و خوانده میشوند.
تابع مورد استفاده در سمت اسلیو:
- (onRequest(handler : از این تابع برای پاسخگویی به درخواستهای اسلیو استفاده میشود.
مثال :
در طرف مستر، یک بایت را از اسلیو با آدرس 2 درخواست کنید و پس از دریافت، آن را در خروجی سریال چاپ کنید.
در طرف اسلیو، با هر بار درخواست مستر، تعداد درخواست رخ داده را به سمت مستر ارسال کند.
کد سمت مستر:
#include <Wire.h> { Wire.begin(); Serial.begin(9600); // start serial for output } void loop() { Wire.requestFrom(2, 1); while (Wire.available()) { char c = Wire.read(); Serial.print(c); } delay(500); }
کد سمت اسلیو:
#include <Wire.h> void setup() { Wire.begin(2); Wire.onRequest(requestEvent); } Byte x = 12; void loop() { delay(100); } void requestEvent() { Wire.write(x); x++; }
امیدوارم این بخش آموزشی برایتان مفید بوده باشد.
منابع :
toturialspoint.com