یکی از انواع پرکابرد پروتکل سریال که برای تبادل داده در فاصلهی کوتاه بین ICهای مختلف، توسعه داده شده پروتکل I2C است. در این پروتکل تنها با استفاده از دو مسیر الکتریکی با نامهای SDA (برای دیتا) و SCL (برای کلاک) ، میتوانیم بین چندین آیسی ارتباط برقرار کنیم.
این پروتکل برای اولین بار در دههی 80 توسط NXP معرفی شد. یکی از بهترین منابع هم برای درک نحوهی کارکرد این پروتکل داکیومنت UM10204 با عنوان “I2C-bus specification and user manual” ازاین شرکت میباشد. در ادامه قراره به توضیح قسمتهایی از این پروتکل بپردازیم.
همانطور که در ابتدا هم اشاره کردیم I2C Bus شامل دو خط SDA و SCL است. طبقهی خروجی همهی ICهای روی باس به صورت Open Collector هستند و لازم است هر دو خط SDA و SCL با مقاومت پول آپ مناسب به VCC متصل شوند.

در ارتباط I2C معمولاً یک Master داریم که کنترل کنندهی اصلی ارتباط است و چندین Slave که هر کدام آدرس مختص خود را دارند و به سیگنالهای فرستاده شده از سمت Master پاسخ میدهند.
در نظر داشته باشید که حتا اگر چند Master بر روی باس حضور داشته باشند، در هر لحظه تنها یکی از آنها میتواند کنترل باس را در دست بگیرد و با یکی از Slaveها ارتباط داشته باشد.
هر گاه قرار باشد ارتباطی شکل بگیرد، لازم است ابتدا بر روی باس وضعیت Start را داشته باشیم. این وضعیت را همیشه Master ایجاد میکند. در انتهای ارتباط هم Master است که با ایجاد وضعیت Stop به آن پایان میدهد.
به وضعیتی که هیچ دادهای بر روی خط در حال تبادل نیست، Idle گفته میشود. در این وضعیت ولتاژ هر دو خط باید VCC باشد. به خاطر داشتن این نکته میتواند در خطایابی بسیار کمکمان کند.
یکی از ویژگیهایی که این پروتکل دارد این است که به ازای هر بایتی که گیرنده دریافت میکند، یک سیگنال ACK برای تصدیق این دریافت به سمت فرستنده برمیگرداند. توجه کنید که گیرنده یا فرستنده میتواند Master یا Slave باشد.
حالا به تصویر زیر دقت کنید:

در این تصویر رنگ قرمز از سمت Master است و رنگ آبی از سمت Slave. در ابتدا مشاهده میکنید که وضعیت Start که با S نشان داده شده از سمت Master ارسال شده. بعد از این وضعیت Slaveهای روی خط منتظر ارسال آدرس میمانند تا ببینند Master قرار است با کدامشان ارتباط را برقرار کند. دادهها همیشه از سمت بیت پرارزش ارسال میشوند. به همین دلیل 7 بیت بعدی که آدرس Slave مدنظر را در خودش دارد با شروع از A7 ارسال میشود. بیت بعدی مشخص میکند که قرار است Master بر روی Slave بنویسد یا از آن بخواند. خط بالای حرف W اشاره به این دارد که در صورت صفر بودن این بیت قرار است مستر Write کند و به عکس در صورت یک بودن قرار است Read کند.
بعد از ارسال این هشت بیت، اگر همه چیز به خوبی پیش رفته باشد و ما بر روی خط Slaveای مطابق با آدرس فرستاده شده داشته باشیم که این پیام را دریافت کرده، نوبت به این Slave میرسد تا با ارسال ACK به فرستنده بفهماند که پیام را دریافت کرده.
حالا دو حالت پیش رو داریم، حالت اول قرار است که Master بر روی Slave بنویسد و همانطور که مشاهده میکنید بایت بعدی هم به رنگ قرمز از سمت Master ارسال شده. در انتها هم یک ACK از سمت گیرنده که Slave است را شاهد هستیم و از آنجا که احتمالا Master دیگر نمیخواسته دادهای را ارسال کند، وضعیت Stop را بر روی خط ایجاد کرد.
حالت دوم هم مشابه حالت اول است. با این تفاوت که این بار دادهها از سمت Slave میآیند و Master در حال Read است. در نتیجه این Master است که اینبار گیرنده است و باید بعد از دریافت بایت، ACK را برای Slave ارسال کند.
اما بپردازیم به نمودارها، در I2C به طور کلی قاعده این است که وضعیت خط SDA هنگامی باید تغییر کند که SCL در وضعیت Low قرار دارد. تنها استثنا برای این قاعده Stop و Start است. در واقع از طریق همین استثنا هست که Slave متوجه این دو رخداد میشوند. همانطور که در تصویر هم مشخص است در وضعیت Start ما ابتدا SDA را صفر کرده و بعد از آن SCL را صفر میکنیم. در Stop هم به همین صورت ابتدا SDA صفر میشود و بعد از آن SCL.
Clock stretching:
در این پروتکل Slave میتواند با نگه داشتن کلاک در حالت ریست Master را مجبور به صبر کردن کند. به این ویژگی Clock stretchingگفته میشود. به عنوان مثال در حافظهی EEPROM مدت زمانی را IC برای پروگرام کردن اطلاعات دریافتی بر روی حافظه نیاز دارد و در این زمان دادهی جدید نباید به سمت IC ارسال شود. گاهی طراح تراشه به کمک همین ویژگی مانع از ارسال اطلاعات جدید از سمت پردازنده میشود.
Repeated Start:
گاهی لازم میشود که بعد از آنکه Master نوشتن را انجام داد، شروع به خواندن کند. به عنوان مثال در حافظههای EEPROM هنگامی که میخواهیم مقدار پروگرام شده در آدرسی از حافظه را بخوانیم، باید ابتدا برای EEPROM آدرس این خانه از حافظه را بنویسیم و سپس در عملیات بعد مقدار آن را ازش بخوانیم. اتفاق نامطلوبی که ممکن است در بین این دو عملیات رخ بدهد، گرفته شدن باس توسط یک Master دیگر است. برای جلوگیری از این اتفاق کاری که انجام میدهند به این صورت است که در انتهای عملیات اول Stop توسط Master بر روی خط نمیشود تا خط به حالت Idle نرود. اما برای عملیات دوم همانند قبل Start ارسال میشود و از آنجا که این Start بعد از اتمام ارتباط فرستاده نشده به آن repeated start میگویند.
سرعت ارتباط:
برای جایی که ما نیاز به سرعت بالا داریم، اصولاً طراحان آیسی به سراغ I2C نمیروند. به عنوان مثال در حافظههای Flash یا حتا RAM زیاد میبینیم که از SPI یا QSPI به عنوان جایگزین ارتباط موازی استفاده شده تا I2C. اما با این حال پیشرفت تکنولوژی و نیاز بیشتر ما به سرعتهای بالاتر باعث شده ما شاهد Modeهای مختلف با حداکثر سرعتهای متفاوت باشیم. توجه کنید که امکان دارد آیسی مدنظر ما همهی این Mode ها را پشتیبانی نکند و برای دانستن این موضوع باید به دیتاشیت تراشه مراجعه کرد.
مقدار مقاومت Pull up مناسب چقدر است؟
عوامل تعیین کننده در مقدار مقاومت، سرعت ارتباط و ظرفیت خازنی خط هستند. هر کدام از خطهای باس I2C را میتوان به صورت یک مدار RC مدل کرد. C میشود ظرفیت خازنی خط که حاصل جمع Capacitance ورودی پایهی آیسیها و خود مسیر ارتباطی است. قاعدتاً خیلی اندازهاش دست ما نیست و میتوان با مراجعه به دیتاشیت آیسیها مقداری سرانگشتی را برایش در نظر گرفت.
اما R بخش غیرقابل صرف نظرش میشود مقاومتی که ما به عنوان Pull up خط میگذاریم. میدانیم که در یک مدار RC، مدت زمان شارژ یا دشارژ خازن وابسته است به ثابت زمانی T = R*C. این یعنی با انتخاب مقاومت کمتر میتوانیم با سرعت بالاتری خط را صفر و یک کنیم. اما ماجرا به این سادگی نیست که کمترین مقاومت ممکن را در نظر بگیریم. چراکه کاهش مقاومت، افزایش توان مصرفی را هم به دنبال دارد. در نتیجه در نهایت باید در یک مصالحه بین افزایش توان مصرفی و کلاک بالاتر(امکان صفر و یک شدن سریعتر) مقاومت نهایی را انتخاب کنیم. اگر میخواهید جزئیات بیشتری در این خصوص بدانید به اپلیکیشن نوت SLVA689 از شرکت تگزاس اینسترومنت مراجعه کنید.
دیجیلاگیست محلی برای کسانی که به دنیای دیجیتال و آنالوگ علاقه دارند
بسیار عالی . چند مدل از oled هارو با ارتباط i2c راه اندازی کردم ولی سرعت رفرش تصویر پایین بود. و برای سرعت بالاتر و ارتباط با حافظه ها spi بهتر عمل میکنه و عملا i2c برای ارتباط کنترلی با دیتا کمتر مناسب تره . مرسی مهندس توضیحاتتون عالی بود 🙏
دقیقاً🙏