در این آموزش در مورد پروتکل I2C فرا خواهید گرفت، این که چرا باید از آن استفاده کنید، و این که چگونه آن را راه اندازی کنید. پروتکل Inter-Integrated Circuit یا به اختصار I2C پروتکلی است که برای ارتباط چندین مدار مجتمع(چیپ) دیجیتال “slave” با یک یا چند چیپ “master” طراحی شده است. مانند پروتکل SPI، I2C نیز برای ارتباطات در فاصله کوتاه درون یک دستگاه طراحی شده است. مانند رابط های سریال آسنکرون(مثل RS-232 یا UART)، این پروتکل نیز تنها به دو سیم سیگنال برای تبادل اطلاعات نیاز دارد.
چرا پروتکل I2C ؟
برای فهمیدن دلیل استفاده از پروتکل I2C ، ابتدا آن را با دیگر گزینههای موجود مقایسه میکنیم تا تفاوتهای آن مشخص شود.
عیب پورت های سریال چیست؟
به دلیل اینکه پورتهای سریال آسنکرون هستند(سیگنال کلاکی فرستاده نمیشود)، دستگاههای استفاده کننده از آن باید از قبل بر سر یک نرخ انتقال دادهی مشخص توافق کنند. همچنین هر دو دستگاه باید کلاکهایی نزدیک به همان نرخ انتقال داشته باشند – اختلاف زیاد بین نرخهای کلاک در هر یک از دو سمت منجر به از دست رفتن داده میشود.
پورتهای سریال آسنکرون نیاز به سخت افزار اضافی دارند. – UART در هر یک از دو طرف برای پیادهسازی دقیق نرمافزاری در صورت نیاز نسبتا سخت و پیچیده است. حداقل یک بیت شروع و یک بیت پایان بخشی از هر فریم داده است، به این معنی که برای انتقال هر 8 بیت داده به زمانی معادل با انتقال 10 بیت داده نیاز است، که به شدت نرخ انتقال داده را پایین میآورد.
یک ایراد بنیادی دیگر در در پورتهای سریال آسنکرون این است که آنها به طور ذاتی برای ارتباط بین دو، و فقط دو دستگاه طراحی شدهاند. با این که اتصال چندین دستگاه به یک پورت ممکن است، تداخل در باس یا bus contention ( هنگامی که دو دستگاه همزمان میخواهند روی یک خط داده ارسال کنند) همواره یک مشکل است و باید با استفاده از سخت افزار خارجی و بسیار بااحتیاط با آن برخورد شود تا از آسیب رسیدن به دستگاههای متصل جلوگیری شود.
در آخر، نرخ تبادل داده یک مشکل است. با این که از نظر تئوری محدودیتی در ارتباطات سریال آسنکرون وجود ندارد، بیشتر دستگاههای USART تنها از مجموعهای از باود ریتهای ثابت استفاده میکنند، که بالاترین آنها معمولا حدود 230400 بیت بر ثانیه است.
عیب پروتکل SPI چیست؟
بزرگترین ایراد SPI تعداد پایههای مورد نیاز است. وصل کردن فقط یک master به یک slave از طریق SPI نیاز به 4 سیم دارد؛ هر slave اضافهی دیگر یک پایه I/O chip select در سمت master نیاز دارد. افزایش سریع تعداد اتصالات پایهها این پروتکل را در شرایطی که تعداد زیادی دستگاه slave باید به یک master متصل شوند بی استفاده میکند. همچنین، تعداد زیاد اتصالات برای هر دستگاه رسم PCB های فشرده را سخت میکند. SPI تنها به یک master روی باس اجازه میدهد، اما از تعداد دلخواه slave پشتیبانی میکند(تنها محدود به ظرفیت دستگاههای متصل به باس و تعداد پایههای chip select موجود).
SPI برای ارتباطات full-duplex(ارسال و دریافت همزمان داده) با نرخ انتقال بالا مناسب است زیرا از سرعتهایی بیشتراز 10MHz(و بنابراین، 10میلیون بیت بر ثانیه) در بعضی دستگاهها پشتیبانی میکند. سخت افزار در هر طرف معمولا یک شیفت رجیستر ساده است، که امکان پیاده سازی نرم افزاری آسان آن را فراهم میکند.
پروتکل I2C – بهترین های هر دو دنیا
پروتکل I2C تنها به دو سیم نیاز دارد، مانند ارتباط سریال آسنکرون، اما این دو سیم میتوانند از 1008 دستگاه salve پشتیبانی کنند. همچنین، بر خلاف SPI، از یک سیستم دارای چند master نیز پشتیبانی میکند که به بیش از یک master اجازه میدهد تا با تمامی دستگاههای روی باس ارتباط برقرار کند(البته masterها نمیتوانند با یکدیگر صحبت کنند و همچنین باید از خطوط باس نیز به طور نوبتی استفاده کنند).
نرخ انتقال داده در این پروتکل بین ارتباط سریال آسنکرون و SPI قرار میگیرد؛ بیشتر دستگاههای پروتکل I2C در 100تا400 کیلوهرتز کار میکنند. پروتکل I2C نیز مقداری اطلاعات اضافه ارسال میکند؛ برای هر 8بیت داده فرستاده شده، یک بیت اضافی متا داده (بیت “ACK/NACK”، که بعدا در مورد آن بحث خواهد شد) نیز باید ارسال شود.
سخت افزار موردنیاز برای اجرای I2C پیچیده تر از SPI است، اما از ارتباط سریال آسنکرون ساده تر است. این پروتکل میتواند به صورت نسبتا ساده در نرم افزار پیاده سازی شود.
تاریخچه پروتکل I2C
I2C اولین بار در سال 1982 توسط فیلیپس برای چیپهای این شرکت توسعه داده شد. مشخصات اولیهی آن تنها تا 100کیلوهرتز تعیین شده بود، و تنها از آدرسهای 7بیتی پشتیبانی میکرد که تعداد دستگاههای روی باس را به 112 عدد محدود میکرد(چندین آدرس رزرو شده وجود دارد که هیچ وقت برای آدرسهای معتبر پروتکل I2C از آنها استفاده نمیشود). در سال 1992، اولین مشخصات به طور عمومی اعلام شد، که در آن حالت سریع 400کیلوهرتزی و پشتیبانی از آدرسهای 10بیتی اضافه شده بود. بسیاری از اوقات(برای مثال در Atmega328 روی بسیاری از بردهای سازگار با آردوینو)، پشتیبانی از دستگاهها برای I2C در همین نقطه به پایان میرسد. 3 حالت اضافه دیگر نیز تعریف شده است: fast-mode plus با سرعت 1مگاهرتز، high-speed mode با سرعت 3.4مگاهرتز، و ultra-fast mode با سرعت 5 مگاهرتز.
علاوه بر I2C “vanilla”، اینتل نسخه را در سال 1995 با نام “System Management Bus” یا به اختصار SMBus معرفی کرد. SMBus نسخهی دقیق تری برای بیشینه کردن قابل پیشبینی بودن ارتباطات بین ICهای سازگار در مادربوردها میباشد. مهم ترین تفاوت SMBus این است که سرعت در آن از 10 تا 100 کیلوهرتز محدود شده است، در حالی که پروتکل I2C میتواند از دستگاههایی با سرعت 0 تا 5 مگاهرتز پشتیبانی کند. SMBus از یک حالت clock timeout پشتیبانی میکند که ارتباطات کم سرعت را غیرمجاز میداند، با این حال بسیاری از دستگاههای SMBus از این ارتباطات پشتیبانی میکنند تا سازگاری آنها با سیستمهای پروتکل I2C به حداکثر برسد.
پروتکل I2C در سطح سخت افزاری
سیگنال ها، هر باس I2C از دو سیگنال تشکیل شده است: SCL و SDA. SCL سیگنال کلاک و SDA سیگنال دیتا میباشد. کلاک سیگنال همواره توسط Master باس تولید میشود؛ گاهی اوقات ممکن است بعضی از دستگاههای slave کلاک را به اجبار پایین بکشند تا فرستادن اطلاعات بیشتر توسط master را به تاخیر بیاندازند(یا تا زمان بیشتری برای آماده سازی داده قبل از این که master آن را کلاک بزند درخواست کنند). این عمل “clock stretching” نام دارد و در صفحهی پروتکل توضیح داده شده است.
برخلاف ارتباطات UART یا SPI، درایورهای باس I2C “open drain” هستند، به این معنی که میتوانند خط سیگنال مربوطه را پایین بکشند، اما نمیتوانند آن را بالا ببرند. بنابراین، هیچ اختلال در باسی نمیتواند به وجود بیاید که در آن یک دستگاه در تلاش است تا خط را بالا بکشد در حالی که دیگری میخواهد آن را پایین بکشد، و در نتیجه، احتمال آسیب به درایورها یا اتلاف توان بیش از حد در سیستم از بین میرود. هر خط سیگنال دارای یک مقاومت پول آپ میباشد، که سیگنال را هنگامی که هیچ دستگاهی آن را پایین نمیکشد بالا نگه دارد.
به دو مقاومت پول آپ رو دو خط ارتباط دقت کنید.
انتخاب مقاومت به دستگاههای روی باس بستگی دارد، اما به عنوان یک قانون کلی بهتر است با 4.7کیلواهم شروع کنید و در صورت نیاز آن را کاهش دهید. I2C پروتکل تقریبا مقاومی است، و میتواند در فاصلههای کوتاه(2تا3متر سیم) استفاده شود. برای فواصل بیشتر، یا سیستمهای با تعداد زیادی دستگاه، مقاومتهای با مقدار کمتر مناسبتر هستند.
سطوح سیگنال پروتکل I2C
از آنجایی که دستگاههای روی باس سیگنال را بالا نمیکشند، پروتکل I2C تا حدی امکان انعطاف پذیری در اتصال دستگاهها با ولتاژهای I/O مختلف را فراهم میکند. به طور کلی، در یک سیستم که در آن یک دستگاه با ولتاژ بالاتری از یک دستگاه دیگر کار میکند، ممکن است بتوان بدون هیچ مدار تغییر سطحی آنها را از طریق I2C به هم وصل کرد. نکته در این است که باید مقاومتهای پول آپ را به ولتاژ کمتر از بین دو ولتاژ متصل کرد. این کار فقط در بعضی موارد جواب میدهد، که در آنها ولتاژ پایینتر بین دو سیستم از سطح منطقی high سیستم با ولتاژ بالاتر بیشتر باشد – برای مثال، یک آردوینوی 5ولت و یک شتاب سنج 3.3ولت.
اگر اختلاف ولتاژ بین دو سیستم خیلی زیاد باشد(مثلا5ولت و 2.5 ولت)، SparkFun استفاده از یک برد ساده مبدل سطحI2C را پیشنهاد میکند. از آنجایی که این برد شامل یک خط enable نیز میباشد، میتوان از آن برای قطع کردن ارتباط با دستگاههای انتخاب شده نیز استفاده کرد. این کار در مواردی که بیش از یک دستگاه با یک آدرس به یک master متصل شده است کاربرد دارد – دسته Wii Nunchuck مثال خوبی از این مورد است.
پروتکل
ارتباط از طریق پروتکل I2C پیچیده تر از UART یا SPI است. فرستادن سیگنالها باید از پروتکل خاصی پیروی کند تا به عنوان ارتباط I2C معتبر شناخته شوند. خوشبختانه، بیشتر دستگاهها این جزئیات را در نظر گرفته و آنها را رعایت میکنند و به شما اجازه میدهند تا روی دادهای که میخواهید ارسال کنید تمرکز کنید.
اصول پروتکل I2C
پیامها به دو دسته فریم تقسیم میشوند: یک فریم آدرس، که در آن master مشخص میکند به کدام slave پیام میفرستد، و یک فریم یا بیشتر برای داده، که پیامهای 8 بیتی هستند که از master به slave یا برعکس منتقل میشوند. داده بعد از اینکه SCL پایین میرود روی خط SDA قرار میگیرد، و بعد از اینکه SCL بالا میرود نمونه برداری میشود. زمان بین لبه کلاک و خواندن/نوشتن داده توسط دستگاهها تعیین میشود و بسته به چیپ متفاوت است.
وضعیت شروع
برای شروع ارسال فریم آدرس، دستگاه master خط SCL را بالا نگه داشته و SDA را پایین میکشد. این کار به تمامی دستگاههای slave روی باس اعلام میکند که یک ارسال به زودی انجام میشود. اگر دو master در یک زمان قصد ارسال داده را داشته باشند، دستگاهی که اول SDA را پایین میکشد برنده است و کنترل باس را در اختیار میگیرد. فرستادن چندین دستور شروع توسط یک master پشت سر هم بدون اینکه کنترل باس را به master دیگری بدهد نیز ممکن است که در ادامه در مورد آن صحبت میکنیم.
فریم آدرس
فریم آدرس همیشه در هر مرتبه ارتباط جدید ابتدا ارسال میشود. برای یک آدرس 7بیتی، آدرس به صورت MSB ارسال میشود و بعد از آن یک بیت R/W ارسال میشود که تعیین میکند این عمل خواندن (1) یا نوشتن (0) است.
نهمین بیت این فریم بیت NACK/ACK است. این بیت در همهی فریمها وجود دارد، چه داده چه آدرس. بعد از اینکه هشت بیت اول فریم ارسال میشود، کنترل SDA به دست دستگاه دریافت کننده داده میشود. اگر این دستگاه قبل از نهمین پالس کلاک SDA را پایین نکشد، این طور برداشت میشود که دستگاه گیرنده داده را دریافت نکرده است یا نتوانسته است آن را رمزگشایی کند. در این صورت، انتقال داده متوقف شده و تصمیم این که چه کاری انجام شود با master سیستم است.
فریم داده
بعد از این که فریم آدرس ارسال شد، ارسال داده میتواند شروع شود. Master به تولید پالس کلاک با وقفههای منظم ادامه میدهد، و بسته به بیت R/W داده توسط slave یا master روی SDA قرار داده میشود. تعداد فریمهای داده دلخواه است، و بیشتر دستگاههای slave به طور خودکار رجیستر داخلی را افزایش میدهند، به این معنی که خواندن یا نوشتنهای پشت سر هم بع ترتیب از رجیسترهای بعدی انجام میشود.
وضعیت توقف
هنگامی که تمامی فریمهای داده ارسال شدند، master یک وضعیت توقف ایجاد میکند. وضعیت توقف با یک تغیر وضعیت از 0->1 (low به high) روی SDA بعد از یک تغیر وضعیت از 0->1 روی SCL و ثابت ماندن SCL تعریف میشود. در طی نوشتن معمولی ،هنگامی که SCL بالاست مقدار SDA نباید تغیر کند تا از وضعیت توقف اشتباهی جلوگیری شود.
آدرس های 10 بیتی در پروتکل I2C
در یک سیستم آدرس دهی 10بیتی، به دو فریم برای ارسال آدرس slave نیاز است. اولین فریم از کد b11110xyz تشکیل میشود، که در آن ‘x’ بیت MSB آدرس slave، y بیت 8 آدرس slave، و z بیت R/W که در بالا توضیح داده شد میباشد.بیت ACK اولین فریم توسط تمامی slave هایی که دو بیت اول آدرس آنها با بیتهای ارسال شده یکسان است فرستاده میشود. مانند انتقال 7بیتی معمولی، یک فریم دیگر بلافاصله ارسال میشود که شامل بیتهای 7:0 آدرس میباشد. در این مرحله، slave فراخوانی شده باید با یک بیت ACK پاسخ دهد. در غیر اینصورت حالت خطا دقیقا مانند یک سیستم 7بیتی میباشد.
توجه داشته باشید که دستگاههای با آدرس 10بیتی میتوانند به همراه دستگاههای 7بیتی روی یک باس وجود داشته باشند، زیرا بخش ‘11110’ آدرس در هیچ قسمتی از یک آدرس 7بیتی معتبر وجود ندارد.
وضعیت های شروع مکرر
بعضی اوقات، لازم است به یک دستگاه master اجازه داده شود تا چندین پیام را پشت سرهم و بدون اجازه دادن به دیگر دستگاههای master روی باس ارسال کند. برای این کار، وضعیت شروع مکرر تعریف شده است.
برای انجام شروعهای مکرر، در حالی که SCL پایین است SDA بالا میرود، SCL بالا میرود، و سپس هنگامی که SCL بالاست SDA مجددا پایین کشیده میشود. بخاطر اینکه هیچ وضعیت توقفی روی باس وجود نداشت، ارتباط قبلی تکمیل نشده بود و بنابراین master کنونی به در دست گرفتن کنترل باس ادامه میدهد.
در این مرحله، ارسال پیام بعدی میتواند شروع شود. نحوه چینش این پیام جدید نیز مانند هر پیام دیگری است – یک فریم آدرس و سپس فریمهای داده. هر تعداد شروعهای مکرر مجاز است، و master تا زمان ارسال وضعیت توقف کنترل باس را به دست دارد.
تعریض کلاک پروتکل I2C
گاهی اوقات، نرخ تبادل دادهی master از توانایی slave برای تامین آن داده تجاوز میکند. این مشکل میتواند به دلیل آماده نبودن داده(برای مثال، هنوز یک تبدیل آنالوگ به دیجیتال را انجام نداده است) یا بخاطر کامل نشدن عملیات قبلی(برای مثال، یک EEPROM که نوشتن روی حافظه non-volatile را تمام نکرده است و نمیتواند قبل از اتمام آن به دیگر درخواستها پاسخ دهد) باشد.
در این شرایط، بعضی از دستگاههای slave عملی به نام “clock stretching” یا تعریض کلاک را انجام میدهند. به طور کلی، تمامی کلاکها توسط master زده میشود و slave ها با توجه به پالسهای کلاک master فقط داده را از روی باس برداشته یا آن را روی باس میگذارند. در هر لحظه از فرآیند انتقال داده، slave فراخوانی شده میتواند بعد از اینکه master خط SCL را آزاد کرد آن را پایین نگه دارد. در این صورت master ادامه کلاک زنی و انتقال داده را متوقف کرده تا زمانی که Slave خط SCL را آزاد کند.
مطالب پیشنهادی
مواردی که خواندن آنها قبل از این آموزش مفید است:
منابع و مطالعه بیشتر
I2C پروتکل نسبتا پیچیدهای است، و منابع زیادی وجود دارد که میتواند در یادگیری هر چه بهتر آن به شما کمک کند. در ادامه بعضی از این منابع ذکر شده است.
- مقاله ویکیپدیا در مورد I2C – نقطه مناسبی برای شروع مطالعه در مورد I2C.
- مقالات استاندارد – شرکت نیمه هادی فیلیپس چندین سال پیش به NXP تغیر نام داد. این لینک مربوط به مقالات رسمی I2C میباشد.
- ابزارهای لینوکس برای I2C – مجموعهای از ابزارها برای کار با I2C و باسهای مرتبط در محیطهای لینوکسی، مانند pcDuino یا Raspberry Pi.
Source: SparkFun
همچنین توصیه میکنم راه اندازی I2C در آردوینو ، تفاوت مدار آنالوگ و دیجیتال، اینترنت اشیاء و آموزش های آردوینورا نیز بخوانید.
اگر این نوشته برایتان مفید بود لطفا کامنت بنویسید.
سپاس از لطفتون و خدا قوت،خیلی عالی و روان بود.کاملاً مختصر و مفید.
ممنون از توضیحاتتون.بدونید که مطالبتون با دقت خونده میشه.
ممنون. مقاله خوبی بود. کوتاه و اموزنده.
دمت گرم داداش عالی بود
مثل همیشه عالی…
ارادت 🙂
عالی کامل روان
خیلی خوب بود
چقدر نگارش متن ضعیف و بد بود، ای کاش حداثل سواد ادبیاتی در حد نوشتن جمله رو میداشتید که بشه از آموزشتون حداثل استفاده رو کرد.
سلام
توضیحات بسیار خوبی دادید. لطفا اگر نمونه برنامه برای میکروکنترلرهای AVR دارید در اختیار ما بگذارید.
با تشکر