فهرست مطالب:

اتوبوس I2C برای ATtiny و ATmega: 8 مرحله
اتوبوس I2C برای ATtiny و ATmega: 8 مرحله

تصویری: اتوبوس I2C برای ATtiny و ATmega: 8 مرحله

تصویری: اتوبوس I2C برای ATtiny و ATmega: 8 مرحله
تصویری: LDmicro 14: I2C LCD & DS3231 Real-Time Clock (Microcontroller PLC Ladder Programming with LDmicro) 2024, جولای
Anonim
اتوبوس I2C برای ATtiny و ATmega
اتوبوس I2C برای ATtiny و ATmega

من عاشق میکروکنترلرهای Atmel AVR هستم! از زمان ایجاد سیستم توسعه گتو که در این دستورالعمل توضیح داده شده است ، من به هیچ وجه از آزمایش با AVR ATtiny2313 و به ویژه ATmega168 لذت نبرده ام. من حتی تا آنجا نوشتم که یک دستورالعمل در مورد استفاده از سوئیچ ها به عنوان ورودی نوشتم و مفهوم سیستم توسعه گتو را به CPLD گسترش دادم. در یک پروژه اخیر ، برای تنظیم مقادیر کنترل به چندین سوئیچ نیاز داشتم. AVR ها پین های ورودی/خروجی کافی نداشتند ، بنابراین مجبور شدم به چیزی فکر کنم. می توانستم یک سیستم ورودی پیچیده با صفحه کلید و صفحه نمایش را امتحان کنم ، اما منابع ATtiny2313 تمام می شد. خوشبختانه ، Atmel راهی برای حل این مشکل با استفاده از رابط کاربری که می تواند به تراشه های اضافی (مانند حافظه یا پورت های ورودی/خروجی) با یک رابط ساده دو سیم متصل شود ، ارائه کرده است. درست است ، فقط با استفاده از دو پین ورودی/خروجی در AVR می توانیم به تعداد زیادی پین ورودی/خروجی اضافی و منابع دیگر نیز دسترسی پیدا کنیم. این رابط دو سیمه به طور رسمی به عنوان گذرگاه مدار یکپارچه یا فقط گذرگاه I2C شناخته می شود و هنگامی که هنوز نیمه هادی های فیلیپس بود توسط NXP اختراع شد. اگر این دستورالعمل را می خوانید ، احتمالاً نام گذرگاه I2C را شنیده اید و حتی ممکن است از آن در PIC یا میکروکنترلرهای دیگر استفاده کرده باشید. در حالی که از نظر مفهومی بسیار ساده است و توسط منابع سخت افزاری در AVR ها پشتیبانی می شود ، رانندگان نرم افزار هنوز برای استفاده از گذرگاه I2C ضروری هستند. Atmel یادداشت های برنامه را ارائه می دهد (منابع را بعداً در این دستورالعمل مشاهده کنید) ، اما اینها ناقص هستند و هیچ نمونه ای را فراتر از ارتباط با دستگاه AVR دیگر نشان نمی دهند. هدف از این دستورالعمل آموزش نحوه ایجاد درایورهای I2C برای AVR ها در عوض ، من نسخه های گسترده ای از درایورهای Atmel را برای دستگاه های ATtiny2313 و ATmega168 ارائه می دهم ، الزامات و محدودیت هایی را که هنگام استفاده از آنها اعمال می شود ، توضیح خواهم داد و نمونه های کارکرد دستگاه های I2C را به شما نشان خواهم داد. پس از کار با این دستورالعمل ، می توانید از گذرگاه I2C با موفقیت در پروژه های AVR خود استفاده کنید. بدیهی است ، اگر فقط به یکی از آنها علاقه دارید ، می توانید درایورهای کوچک یا MEGA را نادیده بگیرید. برای علاقمندان به کسب اطلاعات بیشتر در مورد گذرگاه I2C ، پیوندهایی را به مطالب مناسب ارائه می دهم.

مرحله 1: به هر حال همه این موارد I2C چیست؟

این همه چیز I2C به هر حال چیست؟
این همه چیز I2C به هر حال چیست؟
این همه چیز I2C به هر حال چیست؟
این همه چیز I2C به هر حال چیست؟
این همه چیز I2C به هر حال چیست؟
این همه چیز I2C به هر حال چیست؟
این همه چیز I2C به هر حال چیست؟
این همه چیز I2C به هر حال چیست؟

گذرگاه I2C یک اتصال ساده دو سیمه است که می تواند چندین دستگاه را به هم متصل کرده و به آنها امکان تبادل داده را بدهد. در ساده ترین شکل آن یک دستگاه اصلی وجود دارد که با چندین دستگاه برده ارتباط برقرار می کند. همه دستگاهها به موازات دو سیم گذرگاه I2C متصل می شوند. این دو سیم با نام های SCL و SDA شناخته می شوند. SCL خط ساعت است و توسط دستگاه اصلی کنترل می شود. SDA خط داده دو جهته است. برای انتقال داده ها ، استاد یک آدرس برده همراه با یک پرچم خواندن/نوشتن یک بیت ارسال می کند. در صورت تمایل به نوشتن ، استاد به ارسال داده ها به برده آدرس داده شده ادامه می دهد. در صورت درخواست خواندن ، برده با داده پاسخ می دهد. برای هماهنگی معاملات ، خطوط SCL و SDA توسط master و slave دستکاری می شوند تا چندین شرط را نشان دهند. اینها شامل START ، STOP ، ACK (تصدیق) و NAK (بدون تأیید) است. جزئیات این شرایط توسط رانندگان اداره می شود. عاشقان واقعی در بین شما می توانند تمام جزئیات را در پیوندهای ارائه شده در انتهای این دستورالعمل بیاموزند. الزامات الکتریکی بسیار ساده است. استاد و برده ها باید از سطح یکسان برای Vcc استفاده کنند ، زمینه ها باید متصل شوند و خطوط SCL و SDA باید تا Vcc کشیده شوند. مقدار مقاومتهای کششی دقیقاً با محاسبه بر اساس ظرفیت کل در گذرگاه تعیین می شود ، اما عملاً می تواند تقریباً هر مقدار بین 1.8K تا 10K باشد. من با 5.1K شروع می کنم و از مقادیر پایین تر استفاده می کنم تا کار کند. این معمولاً مشکلی ایجاد نمی کند مگر اینکه تعداد زیادی دستگاه یا طول سیم طولانی بین دستگاه ها داشته باشید. نرخ داده اسمی در گذرگاه I2C 100 کیلوبیت بر ثانیه است. نرخ 400 کیلوبیت بر ثانیه ، 1 مگابیت بر ثانیه و فراتر از آن نیز ممکن است ، اما توسط رانندگان این دستورالعمل پشتیبانی نمی شود. همه دستگاه های I2C با سرعت 100Kbits/ثانیه کار خواهند کرد. ATtiny2313 و ATmega168 هریک گذرگاه I2C را به طور متفاوتی پیاده سازی می کنند. ATtiny2313 از سخت افزار Universal Serial Interface (USI) استفاده می کند - که می تواند برای گذرگاه SPI نیز استفاده شود. ATmega168 سخت افزاری را برای گذرگاه I2C که به عنوان رابط دو سیم (TWI) معروف است اختصاص داده است. پس از نوشتن درایورها ، این تفاوتها عمدتا برای کاربر شفاف است. یک تفاوت مهم در نرم افزار وجود دارد: درایور ATmega168 I2C قطع می شود در حالی که برای ATtiny2313 اینطور نیست. این بدان معناست که یک برنامه ATmega168 نیازی به منتظر ماندن انتقال داده های I2C ندارد ، بلکه فقط باید قبل از شروع انتقال دیگر یا تا زمانی که داده ها از عملیات خواندن به دست آمده منتظر بمانند. مثالها و بحثی که باید انجام شود باید این را روشن کند. آدرسهای I2C 7 بیت هستند ، بنابراین اگر هر یک آدرس منحصر به فردی داشته باشند ، حداکثر 127 دستگاه می توانند در گذرگاه باشند. همانطور که در شکل نشان داده شده است ، این آدرس 7 بیتی یک بیت به چپ منتقل می شود و کمترین مقدار بیت برای علامت گذاری خواندن یا نوشتن دستگاه در آدرس استفاده می شود. بنابراین آدرس برده کامل یک بایت 8 بیتی است. آدرس واقعی تا حدی به صورت داخلی به دستگاه تعیین می شود و قابل تغییر نیست (4 مهم ترین بیت) ، و تا حدی با بیت هایی که ممکن است به پین های دستگاه وصل شوند (3 حداقل بیت مهم) که می توانند بالا یا پایین برای تنظیم گره خورده باشند ، تعیین می شود. یک آدرس خاص به نظر می رسد گیج کننده است ، اما یک مثال این را روشن می کند. برگه اطلاعات PCA8574A نشان می دهد که چهار بیت مهم آدرس I2C همیشه 0111 خواهد بود. سه بیت بعدی با تنظیمات پین های AD0 ، AD1 و AD2 تعیین می شود. این پین ها می توانند به زمین یا منبع تغذیه مثبت (5 ولت) متصل شوند تا به ترتیب 0 یا 1 را نشان دهند. بنابراین محدوده آدرس های احتمالی 38 تا 3F هگزادسیمال است ، همانطور که در شکل دیگر از برگه اطلاعات PCA8574 نشان داده شده است. بنابراین با تغییر تنظیمات بیت آدرس ، حداکثر 8 PCA8574A می تواند همزمان در گذرگاه I2C قرار گیرد. هر کدام فقط به آدرس برده خاص خود پاسخ می دهند. اگر حتی بیشتر پورت های ورودی/خروجی مورد نیاز است ، می توان از PCA8574 استفاده کرد. تنها تفاوت بین PCA8574 و PCA8574A این است که محدوده آدرس برده I2C PCA8574 20 تا 27 هگزادسیمال است. تعیین آدرس یک دستگاه معین می تواند گیج کننده باشد زیرا برخی از برگه های داده بیت خواندن/نوشتن را بخشی از نشانی. برگه اطلاعات را با دقت بخوانید و به خاطر داشته باشید که آدرس برده 7 بیت خواهد بود. بیت خواندن/نوشتن باید جداگانه مورد بررسی قرار گیرد. باز هم ، یک مثال کمک خواهد کرد. برگه اطلاعات 24C16 EEPROM که با آن آزمایش می کنیم می گوید که چهار بیت اول (مهمترین) آدرس برده 1010 است. سه بیت بعدی را می توان با A0 ، A1 و A2 تعیین کرد. اما توجه داشته باشید که برگه اطلاعات 24C01 تا 24C08 را نیز شامل می شود که EEPROM های کوچکتر هستند. شکل از برگه داده نشان می دهد که تنظیمات این بیت های آدرس با افزایش اندازه نادیده گرفته می شود و برای 24C16 کاملاً نادیده گرفته می شود. یعنی سه بیت آخر اهمیتی ندارد و 24C16 واقعاً از همه آدرسهای برده I2C 50 تا 57 هگزادسیمال استفاده می کند. طیف وسیعی از آدرس های برده در واقع بخش های مختلف داخل 24C16 را پوشش می دهد. 256 بایت اول در آدرس 50h ، 256 بعدی در 51h و به همین ترتیب تا 256 آخر در 57h - در مجموع 2K بایت است. از آنجا که آدرس RAM PCF8570 که ما نیز آزمایش می کنیم در این محدوده است ، 24C16 و PCF8570 نمی توانند با هم استفاده شوند.

مرحله 2: چند دستگاه I2C سفارش دهید

اکنون که کمی در مورد گذرگاه I2C می دانید و می خواهید از آن استفاده کنید ، چرا به برخی از دستگاه های I2C سفارش ندهید تا با آنها آزمایش کنید تا هنگام آماده شدن نرم افزار در راه شما باشند؟ دستگاه های مناسب شامل I/ O Interface Expander (مورد علاقه من) ، Static Ram و EEPROM. موارد دیگر وجود دارد ، اما اینها شروع خوبی هستند. پردازنده های AVR مورد استفاده ما ATtiny2313 و Atmega168 (مورد استفاده در آردوینو) هستند. اگر با این موارد تازه کار هستید ، به این دستورالعمل عالی نگاه کنید تا در مورد آنها بیاموزید و سیستم توسعه Ghetto خود را بسازید. شماتیک ATmega168 در دستورالعمل حاضر نحوه پیاده سازی سیستم توسعه گتو برای این پردازنده را نشان می دهد. کابل پورت موازی همان کابل ATtiny2313 است. (من نسخه USB سیستم توسعه Ghetto را امتحان نکرده ام ، بنابراین مطمئن نیستم که چگونه به گذرگاه I2C در آن دسترسی پیدا می کنم. در مورد آردوینو نیز همینطور است.) در اینجا شماره قطعات Digikey آمده است. بندر گسترش: IC I2C I/O EXPANDER 568-4236-5-ND رام: IC SRAM 256X8 W/I2C 568-1071-5-NDEEPROM: IC EEPROM SERIAL 16K CAT24C16LI-G-ND

مرحله 3: درایورهای I2C

در اینجا شرح عملکرد راننده برای گذرگاه I2C آمده است. اینها با استفاده از Atmel Apps Notes برای مبتدیان توسعه یافته اند. من نمی توانستم بدون آنها به عنوان پایه ای برای ساختن این کار را انجام دهم. توسعه با استفاده از WinAVR و کامپایلر gcc C انجام شد. محدودیت های نرخ ساعت در زیر برای هر پردازنده توضیح داده شده است. از آنجا که من نمی توانم تمام ترکیبات طعم پردازنده / نرخ ساعت را آزمایش کنم ، فقط به آنچه می توانم آزمایش کنم پایبند هستم و سعی می کنم محدودیت ها و محدودیت ها را نشان دهم. در اینجا عملکردهای راننده و نحوه استفاده از آنها آمده است. لطفاً برای جزئیات بیشتر و مشاهده عملکردهای مورد استفاده در برنامه های کامل ، به مثالها نگاه کنید. برای ATtiny2313: Clock مورد نیاز: درایورها برای سرعت کلاک 1 مگاهرتز (نرخ پیش فرض) برای ATtiny2313 طراحی شده اند. اگر می خواهید با نرخ های دیگر اجرا شود ، باید ثابت ها را در درایورها تنظیم کنید. در صورت نیاز به کمک در این مورد به من ایمیل بزنید. همچنین می توانید نکاتی را از یادداشت های برنامه های Atmel در پیوندهای Resources Step دریافت کنید. USI_TWI_Master_Initialise () این عملکرد سخت افزار USI را برای عملکرد حالت I2C آماده می کند. در ابتدای برنامه خود یکبار با آن تماس بگیرید. باطل را برمی گرداند و هیچ آرگومانی وجود ندارد. USI_TWI_Get_State_Info () این تابع اطلاعات خطای I2C را برمی گرداند و در صورت بروز خطا در هنگام معامله I2C استفاده می شود. از آنجا که این عملکرد فقط یک کد خطا را برمی گرداند ، من از عملکرد TWI_Act_On_Failure_In_Last_Transmission (TWIerrorMsg) برای فلش LED خطا استفاده می کنم. کدهای خطا در USI_TWI_Master.h تعریف شده است. در اینجا نحوه تماس با آن آمده است: TWI_Act_On_Failure_In_Last_Transmission (USI_TWI_Get_State_Info ()) USI_TWI_Start_Read_Write () این تابع برای خواندن و نوشتن تک بایت برای دستگاه های I2C استفاده می شود. همچنین برای نوشتن چند بایت استفاده می شود. استفاده از این تابع 6 مرحله دارد. 1) در برنامه خود یک بافر پیام برای نگه داشتن آدرس برده و بایت داده ارسال شده یا دریافتی اعلام کنید. پیام بدون امضا charBuf (MESSAGEBUF_SIZE) ؛ 2) آدرس Slave را به عنوان اولین بایت در بافر قرار دهید. آن را یک بیت به چپ و OR را در بیت خواندن/نوشتن تغییر دهید. توجه داشته باشید که بیت خواندن/نوشتن برای خواندن 1 و برای نوشتن 0 خواهد بود. این مثال برای Read است. messageBuf (0) = (TWI_targetSlaveAddress << TWI_ADR_BITS) | (TRUE << TWI_READ_BIT) ؛ 3) هنگام انجام یک نوشتن ، بایت را در مکان بعدی در بافر قرار دهید. 4) با تابع USI_TWI_Start_Read_Write با بافر پیام و اندازه پیام به عنوان argument argumentt.temp = USI_TWI_Start_Read_Write (messageBuf، 2) ؛ 5) مقدار برگشتی (temp در این مورد) را می توان آزمایش کرد تا ببیند آیا خطایی رخ داده است. اگر چنین است ، همانطور که در بالا توضیح داده شد ، رسیدگی می شود. در صورت درخواست Read ، بایت خوانده شده در مکان دوم بافر قرار می گیرد. اگر قرار است چند بایت (مانند دستگاه حافظه) نوشته شود ، می توان از همین روال استفاده کرد. راه اندازی بافر و فراخوانی روال کمی متفاوت است. دومین بایت در بافر آدرس حافظه شروع است که باید برای آن بنویسید. داده هایی که باید نوشته شوند در بایت های بعدی خواهند بود. اندازه پیام اندازه ای خواهد بود که همه داده های معتبر را شامل می شود. بنابراین اگر قرار است 6 بایت نوشته شود ، اندازه پیام 8 خواهد بود (آدرس برده + آدرس حافظه + 6 بایت داده). USI_TWI_Start_Random_Read () این تابع برای خواندن چندین بایت از یک دستگاه I2C استفاده می شود ، معمولاً فقط برای خاطره ای به نوعی استفاده از این روال با دو استثنا بسیار شبیه به روال قبلی است. تنظیم بیت خواندن/نوشتن اهمیتی ندارد. فراخوانی این روال همیشه باعث عملیات خواندن می شود. اندازه پیام باید 2 به علاوه تعداد بایت های خوانده شده باشد. اگر خطایی رخ نداد ، داده ها در محل دوم در بافر قرار می گیرند. برای ATmega168: Clock Requirement: درایورها برای سرعت کلاک 4 مگاهرتز برای ATmega168 طراحی شده اند. کد مثال نحوه تنظیم این نرخ ساعت را نشان می دهد. اگر می خواهید با نرخ های دیگر اجرا شود ، باید ثابت ها را در درایورها تنظیم کنید. در صورت نیاز به این کار به من ایمیل بزنید. TWI_Master_Initialise () این عملکرد سخت افزار TWI را برای عملکرد حالت I2C راه اندازی می کند. در ابتدای برنامه خود یکبار با آن تماس بگیرید. باطل برمی گردد و هیچ استدلالی وجود ندارد. مطمئن شوید که وقفه ها را با فراخوانی swi () پس از راه اندازی اولیه فعال کنید. TWI_Get_State_Info () این تابع اطلاعات خطای I2C را برمی گرداند و در صورت بروز خطا در هنگام معامله I2C استفاده می شود. از آنجا که این عملکرد فقط یک کد خطا را برمی گرداند ، من از عملکرد TWI_Act_On_Failure_In_Last_Transmission (TWIerrorMsg) برای فلش LED خطا استفاده می کنم. کدهای خطا در TWI_Master.h تعریف شده اند ، اما برای علامت دهی روی LED خطا اصلاح شده اند. برای جزئیات کد نمونه را ببینید. در اینجا نحوه تماس با آن آمده است: TWI_Act_On_Failure_In_Last_Transmission (TWI_Get_State_Info ()) توجه داشته باشید که بررسی خطا با اطمینان از کامل بودن معامله I2C (عملکرد زیر توضیح داده می شود) و سپس آزمایش کمی در کلمه وضعیت جهانی. TWI_Start_Read_Write () TWI_Start_) دو تابع همانند توابع مربوطه که در بالا توضیح داده شد عمل می کنند اما با چند استثنا. آنها هیچ مقدار خطایی را بر نمی گردانند. خواندن داده ها به بافر منتقل نمی شود. انجام این کار با عملکردی که در ادامه توضیح داده می شود انجام می شود. هنگام فراخوانی TWI_Start_Random_Read ، پیام اندازه باید تعداد بایت های داده درخواست شده به علاوه یک باشد ، نه دو. درایور I2C برای ATmega168 دارای وقفه است. یعنی معاملات I2C شروع می شود و سپس به طور مستقل اجرا می شود در حالی که روال اصلی همچنان اجرا می شود. وقتی روال اصلی می خواهد داده هایی را از یک تراکنش I2C که شروع شده است بخواهد ، باید بررسی کند که آیا داده ها در دسترس هستند یا خیر. در مورد بررسی خطا نیز وضعیت مشابه است. قبل از بررسی خطاها ، روال اصلی باید مطمئن باشد که تراکنش I2C کامل شده است. دو تابع بعدی برای این اهداف استفاده می شود. TWI_Transceiver_Busy () قبل از بررسی خطاها ، با این تابع تماس بگیرید تا ببینید آیا تراکنش I2C کامل شده است یا خیر. برنامه های مثال نحوه استفاده از این را نشان می دهد. TWI_Read_Data_From_Buffer () با این تابع تماس بگیرید تا داده ها را از بافر دریافت درایور I2C به بافر پیام منتقل کنید. این عملکرد قبل از انتقال داده ها از انجام کامل تراکنش I2C اطمینان حاصل می کند. در حالی که یک مقدار با این تابع برگردانده می شود ، به نظر من بررسی بیت خطا به طور مستقیم قابل اطمینان تر است. در اینجا نحوه تماس با آن آمده است. اندازه پیام باید یک عدد بیشتر از تعداد بیت داده مورد نظر باشد. داده ها در messageBuf از مکان دوم شروع می شوند. temp = TWI_Read_Data_From_Buffer (messageBuf، messageSize)؛

مرحله 4: بیایید بسازیم

بیایید بسازیم!
بیایید بسازیم!
بیایید بسازیم!
بیایید بسازیم!
بیایید بسازیم!
بیایید بسازیم!
بیایید بسازیم!
بیایید بسازیم!

با بارگیری فایل I2C Schematics.zip شروع کنید. ممکن است بخواهید یک پوشه I2C در محل کار خود ایجاد کنید تا شماتیک و فایلهای برنامه مثال را نگه دارد. قالب ها را در این فهرست باز کنید. پوشه ای به نام I2C Schematics پیدا خواهید کرد. فایلی با نام tiny I2C.pdf را باز کنید. این شماتیک سیستم توسعه ATtoy2313 Ghetto Ghetto و PCA8574A I/O Port Expander را نشان می دهد (دارای جعبه خط کشی بزرگ در اطراف آن است). مدار Port Expander روی یک تخته نان ساخته شده است. عکسها را ببینید تا ببینید این مدارها چگونه به نظر می رسند. آنها واقعاً بسیار ساده هستند. بخش ATtiny2313 طرح کلی فقط سیستم توسعه یکنواخت است که دارای سه چراغ چشمک زن (LED1 ، 2 ، و 3 ، به علاوه R4 ، 5 و 6) و یک دکمه فشاری (S1) ، به علاوه یک جزئیات اضافی این جزئیات افزودن جامپرها (JP4 ، 5 و 6) است که می تواند حذف شود تا اتصال خطوط SCL و SDA گذرگاه I2C امکان پذیر شود. جامپرها باید برای برنامه نویسی در محل باشند ، سپس برداشته شوند تا SCL و SDA متصل شوند. عکسها نشان می دهد که جامپرها در جای خود قرار گرفته و برداشته شده اند. اگر می خواهید از گذرگاه I2C استفاده کنید ، قرار دادن این جهنده ها به شما بستگی دارد ، فقط باید آنها را در سیستم توسعه Ghetto خود قرار دهید. گذرگاه I2C باید قطع شود و جامپرها برای برنامه نویسی قرار داده شوند. توجه داشته باشید که برای گذرگاه I2C فقط باید به JP4 و JP6 اهمیت دهید. اگر فکر می کنید که می خواهید از گذرگاه SPI استفاده کنید JP5 را قرار دهید. بوردبورد PCA8574A I/O Port Expander بسیار ساده است. اتصالات Vcc (+5 ولت) و Gnd (زمین) را ارائه کرده و AD0 ، 1 و 2 را به زمین وصل کنید (آدرس برده I2C را 38 هگز می کند). سپس 4 چراغ چشمک زن و 4 سوئیچ DIP را وصل کنید. (اگر سوئیچ DIP ندارید ، فقط می توانید از سیم استفاده کنید. به ترتیب به زمین وصل شوید یا به ترتیب سیگنال را روشن یا خاموش کنید.) در نهایت ، مقاومت های کششی (R11 و 12) را از SDA و SCL به Vcc وصل کنید. اینها به صورت 3.3K نشان داده می شوند ، اما هر مقدار از 1.8K تا 5.1K باید کار کند (شاید تا 10K اما من آن را امتحان نکرده ام). هنگامی که ATtiny2313 را برنامه ریزی کردید ، می توانید جامپرها را حذف کرده و SDA و SCL را برای آزمایش متصل کنید. حالا برای ATmega168. تنها چروک در اینجا این است که شما ممکن است یک سیستم توسعه گتو برای این پردازنده نساخته باشید. اگر اینطور است ، شماتیک ارائه شده من (MEGA I2C.pdf) نحوه کار را به شما نشان می دهد. این فقط یک جایگزینی از نسخه ATtiny2313 است. اگر از قبل برنامه ریزی کرده اید ، می توانید مطمئن شوید که کابل برنامه نویسی شما برای هر دو سیستم مناسب است. تفاوت اصلی در افزودن C2 و C3 است. برای قرار دادن اینها تصاویر را ببینید ، آنها باید بسیار نزدیک به تراشه باشند. یکی از آنها در واقع زیر تراشه است. اینها به خصوص از ایجاد نویز در مبدل آنالوگ به دیجیتال جلوگیری می کند. نیازی به قرار دادن جامپرها ندارید مگر اینکه قصد دارید از گذرگاه SPI استفاده کنید زیرا آنها برای گذرگاه I2C روی این تراشه مورد نیاز نیستند. توجه داشته باشید که بردبرد PCA8754A بدون تغییر خواهد بود. شما فقط SDA و SCL را به هم وصل می کنید و می روید! راحت ، ها؟

مرحله 5: بیایید کدگذاری و آزمایش کنیم

بیایید کد و تست کنیم!
بیایید کد و تست کنیم!
بیایید کد و تست کنیم!
بیایید کد و تست کنیم!
بیایید کد و تست کنیم!
بیایید کد و تست کنیم!

زمان ساخت رانندگان و برنامه های نمونه فرا رسیده است. ما کار خود را با ATboardy2313 و PCB8574A breadboard آغاز می کنیم. فایل I2C.zip را در فهرست کار I2C خود بارگیری کرده و از حالت فشرده خارج کنید. یک پوشه جدید به نام I2C خواهید داشت. در آن USI I2C (برای ATtiny2313) و TWI I2C (برای ATmega168) پیدا می کنید. در USI I2C ، پوشه I_O Port را پیدا خواهید کرد. آن پوشه شامل کد اولین برنامه نمونه ما و درایورهای USI I2C است. با استفاده از WinAVR ، کد را کامپایل کرده و در ATtiny2313 بارگذاری کنید. یک نفس عمیق بکشید و برق را روشن کنید. در اینجا چیزی است که انتظار می رود: هنگام روشن شدن ، LED 1 در پورت PD6 ATtiny2313 دو بار چشمک می زند. تا زمانی که دکمه (S1) را فشار ندهید هیچ اتفاق دیگری رخ نمی دهد. هر بار که دکمه فشار داده می شود ، سوئیچ ها خوانده می شوند و تنظیمات آنها روی LED های متصل به PCA8574A نمایش داده می شود. مقدار سوئیچ ها را تغییر دهید ، دکمه را فشار دهید و LED ها باید تغییر کنند. این کار را ادامه دهید تا زمانی که هیجان دیدن کارکرد آن را پشت سر بگذارید. اگر (خدای نکرده!) همه چیز مطابق انتظار کار نمی کند ، سیم کشی خود را با دقت بررسی کنید. خطاهای I2C با چشمک زدن در LED3 (PD4) نشان داده می شود و احتمالاً به این معنی است که باید بررسی کنید که آیا SDA و SCL به پین های صحیح متصل شده اند و به درستی کشیده شده اند یا خیر.اگر هنوز کار نمی کند ، بقیه این بخش را بخوانید تا با اشکال زدایی آشنا شوید. حالا برگردید و اجازه دهید نگاهی به کد بیاندازیم. فایل USI_I2C_Port.c را باز کنید. این کد برنامه نمونه است. (USI_TWI_Master.c و USI_TWI_Master.h شامل درایورها هستند - می توانید آنها را نادیده بگیرید مگر این که کنجکاو باشید.) از مثال برای راهنمایی برنامه های I2C خود استفاده کنید. بیشتر اوقات ، برنامه نحوه راه اندازی و استفاده از درایورهای I2C ، از جمله تنظیم را به شما نشان می دهد. آدرس برده و بقیه بافر پیام را دریافت کرده و داده ها را از آن خارج کنید. همچنین خواهید دید که چگونه دکمه را حذف می کنم و حلقه while را راه اندازی می کنم. چند جزئیات از برنامه وجود دارد که لازم به ذکر است. توجه داشته باشید که داده های سوئیچ ها قبل از نوشتن روی LED ها در Port Expander وارونه هستند. همچنین توجه داشته باشید که پورت های ورودی در Port Expander باید به صورت High نوشته شوند تا درست کار کنند. این جزئیات در برگه اطلاعات PCA8574A شرح داده شده است. همیشه برگه ها را با دقت بخوانید! استفاده از اشکال زدایی مشروط بیشتر مورد توجه است. در نزدیکی شروع فایل برنامه عبارت // #DEBUG تعریف شده و در سراسر کد دستورهای #ifdef DEBUG پاشیده شده است. تا زمانی که DEBUG تعریف نشده باشد (دو خط کوچک خط را به یک نظر تبدیل می کند و از تعریف آن جلوگیری می کند) ، کد داخل دستورات #ifdef به #endif کامپایل نمی شود. اما اگر همه چیز آنطور که انتظار دارید کار نمی کند ، کد را مجدداً کامپایل کرده و با #define DEBUG بدون نظر کامپایل کنید. چشمک های بیشتری روی LED ها خواهید دید که می توانید برای پیگیری اجرای برنامه آنها را رمزگشایی کنید و به شما کمک می کند تا دقیقاً بدانید کجا اشتباه است. در واقع ، من توصیه می کنم این کار را امتحان کنید تا ببینید چه اتفاقی می افتد. آنچه می بینید این است که LED 2 (در PD5) با پیشرفت اجرا در برنامه چشمک می زند. مقدار خوانده شده از سوئیچ ها قبل از نمایش در LED های Port Expander روی LED 1 (PD6) چشمک می زند. شما باید بتوانید برنامه را با استفاده از این LED ها پیگیری کنید. در ادامه با ATmega168 کار خواهیم کرد. اگر فقط به ATtiny2313 علاقه دارید این بخش را رد کنید. هنوز با منه؟ خوب به پوشه TWI_I2C بروید ، دایرکتوری کاری خود را به IO_Port تغییر دهید و TWI_I2C_Port.c را کامپایل کرده و در ATmega168 بارگذاری کنید. خطوط SDA و SCL را از ATtiny2313 جدا کرده و آنها را به ATmega168 وصل کنید. اتصال برق و زمین ، و برق. عمل باید یکسان باشد! بازی کنید تا هیجان فروکش کند ، سپس اجازه دهید کد را بررسی کنیم. TWI_I2C_Port.c را باز کنید. کد تقریباً مشابه است به جز در هنگام خطا و قرار دادن درایورهای وقفه رانده شده. در اینجا تفاوتها وجود دارد: توجه داشته باشید که ساعت باید روی 4 مگاهرتز تنظیم شود تا گذرگاه I2C به درستی کار کند. sei () ؛ دستور وقفه ها را پس از راه اندازی اولیه درایورهای I2C روشن می کند. برای بررسی خطاها ، یک بیت وضعیت خاص آزمایش می شود. در حین خواندن ، تابع TWI_Read_Data_From_Buffer باید فراخوانی شود تا داده های خوانده شده به بافر پیام منتقل شوند. در حین نوشتن ، در حالی که (TWI_Transceiver_Busy ()) باید مورد استفاده قرار گیرد تا قبل از بررسی خطاها ، مطمئن شوید که انتقال کامل است. این دو عملکرد اخیر در توضیح درایورها در بالا توضیح داده شده است. به غیر از این ، کد تقریباً مشابه ATtiny2313 است. اگر می خواهید با آن آزمایش کنید ، DEBUG نیز همین کار را می کند.

مرحله 6: استفاده از حافظه I2C

استفاده از حافظه I2C
استفاده از حافظه I2C
استفاده از حافظه I2C
استفاده از حافظه I2C
استفاده از حافظه I2C
استفاده از حافظه I2C
استفاده از حافظه I2C
استفاده از حافظه I2C

اکنون که یاد گرفته ایم از گذرگاه I2C برای خواندن و نوشتن یک I/O Port Expander استفاده کنیم ، بیایید به سراغ استفاده از حافظه های I2C ، هم RAM و هم EEPROM برویم. تفاوت اصلی این است که چندین بایت را می توان با یک فرمان I2C روی حافظه خواند یا نوشت. برای آمادگی برای این آزمایشات ، ما باید سخت افزار را کمی تغییر دهیم و چند مدار جدید روی تخته نان بسازیم. مدار Port Expander را نگه دارید زیرا از آن برای نمایش مقادیر حافظه استفاده می کنیم. سوئیچ های DIP را از PCA8574A بردارید و روی آن پین ها چشمک زن قرار دهید. اگر چراغهای چشمک زن کافی ندارید ، آنهایی را که روی P4 تا P7 قرار دارند به P0 تا P3 منتقل کنید. (مقادیر نمایش داده شده به اندازه کافی کوچک هستند.) حالا به I2C Ram.pdf شماتیک نگاه کنید و PCF8570 را روی تخته نان متصل کنید. به تصویر هم نگاه کنید. حتماً پین 7 را به Vcc وصل کنید. سیم های SDA و SCL را از PCA8574A اجرا کنید. هیچ مقاومت کششی اضافی لازم نیست. اگر شما نیز به EEPROM علاقه دارید ، آن مدار را با استفاده از I2C EEPROM.pdf برای 24C16 ایجاد کنید ، اما هشدار دهید که در مثال از ATmega168 استفاده می شود. این مدار واقعاً ساده است. همانطور که در بالا توضیح داده شد ، بیت های آدرس باید نادیده گرفته شوند. فقط برق و زمین را وصل کنید. SDA و SCL را هنوز متصل نکنید زیرا آزمایش با Ram را تمام نکرده ایم. آزمایش های حافظه خود را با ATtiny2313 متصل به PCA8574A Port Expander و PCF8570 Ram شروع می کنیم. این برنامه برخی از اعداد را در Ram می نویسد ، سپس آنها را می خواند و آنها را در Port Expander نمایش می دهد. دایرکتوری کاری خود را تحت RAM USI I2C به RAM تغییر دهید. از فایل make برای کامپایل و بارگیری USI_I2C_RAM.c استفاده کنید. توجه داشته باشید که فایل های درایور I2C مشابه پرونده هایی است که قبلاً استفاده کردیم. برق را وصل کنید و باید یک چشمک زدن روی LED 1 (PD6) مشاهده کنید. داده ها در 4 بایت اول حافظه نوشته می شوند. دکمه را فشار دهید و دو بایت بازخوانی و نمایش داده می شود. شما باید یک چراغ LED را روی Port Expander (P0) ، دو ثانیه مکث و سپس دو چراغ LED (P0 و P1) مشاهده کنید. دو ثانیه مکث دیگر و LED ها باید خاموش شوند. دوباره دکمه را فشار دهید تا ترتیب از نو شروع شود. اشکال زدایی مشابه روش توصیف شده در بالا است. بیایید نگاهی به کد بیاندازیم. USI_I2C_RAM.c را باز کنید. باید شبیه کد قبلی باشد. تفاوتهای اصلی جزئیات خواندن و نوشتن حافظه است. به نحوه بارگیری بافر پیام قبل از تماس که در واقع نوشتن را نگاه می کند ، نگاه کنید. اولین بایت آدرس برده با بیت خواندن/نوشتن مناسب است. اما بایت بعدی آدرس حافظه ای است که در آن شروع به نوشتن داده می شود. سپس بایت های واقعی داده ها می آیند که به طور متوالی در آدرسی که مشخص کرده ایم در حافظه بارگذاری می شوند. اندازه پیام را 6 تعیین می کنیم. بنابراین نوشتن را در آدرس 00 شروع می کنیم و مقادیر 01 ، 03 ، 02 و 06 را در مکان های حافظه 00 تا 03 می نویسیم. برای خواندن داده ها از حافظه باید از تابع USI_TWI_Start_Random_Read استفاده کنیم. بافر پیام آدرس برده را در بایت اول و آدرس شروع را در بایت دوم دریافت می کند. سپس تابع را با اندازه پیام روی تعداد بایت برای خواندن بعلاوه 2 فراخوانی کنید. توجه داشته باشید که بیت خواندن/نوشتن مهم نیست زیرا خواندن بدون در نظر گرفتن آن انجام می شود. داده های بازگردانده شده در مکان دوم در بافر پیام شروع می شود. پس از خواندن داده ها ، برای نمایش بر روی Port Expander وارونه شده و یک بایت در یک نوبت برای آن نوشته می شود و بین مقادیر مکث می شود. در نهایت ، LED های Port Expander خاموش می شوند. نوشته های مربوط به Port Expander مشابه آنچه در نمونه های قبلی انجام شده است. برای سرگرمی ، می توانید عبارت DEBUG #define را در بالا کامنت کنید و تعداد زیادی LED چشمک زن را ببینید. پس از یک آزمایش موفق دیگر ، با هیجان سرخ می شویم ، اجازه دهید به ATmega168 و یک EEPROM برویم. دایرکتوری کاری خود را به EEPROM تحت TWI I2C تغییر دهید. از فایل make برای کامپایل و بارگیری TWI_I2C_EEPROM.c استفاده کنید. توجه داشته باشید که فایل های درایور I2C مشابه پرونده هایی است که قبلاً برای PCA8574A استفاده کردیم. برای آزمایش برنامه ، ATtiny2313 را جدا کرده و ATmega168 را وصل کنید. اتوبوس I2C را به Ram وصل کرده و روشن کنید. نتایج متفاوت است زیرا ما در حال نوشتن و خواندن داده های بیشتر هستیم. LED 1 در PD7 هنگام راه اندازی باید چشمک بزند. دکمه را فشار دهید و داده ها از حافظه خوانده شده و نمایش داده می شوند. LED های PCA8574 باید دنباله زیر را چشمک بزنند: P1 ، P0 & P2 ، (همه خاموش) ، P0 & P1 ، P1 & P2. در نهایت LED های پورت باید همه خاموش شوند. دوباره دکمه را فشار دهید تا این کار تکرار شود. اوه ، اما صبر کنید ، شما می گویید. آیا این برنامه برای EEPROM نیست؟ از آنجا که ما به یک دستگاه حافظه در همان آدرس I2C دسترسی داریم ، یک برنامه مشابه برای Ram و EEPROM کار می کند. برق را خاموش کرده و SDA و SCL را از Ram به EEPROM منتقل کرده و برنامه را دوباره اجرا کنید. باید دقیقاً یکسان عمل کند. توجه داشته باشید که EEPROM و Ram نمی توانند همزمان به گذرگاه I2C متصل شوند زیرا آدرس آنها یکسان است. (افراد باهوش شما ممکن است بیت های آدرس قابل برنامه ریزی را در Ram تغییر دهند ، اما باز هم جواب نمی دهد. 24C16 از کل بلوک آدرس های قابل برنامه ریزی برای Ram استفاده می کند.) خوب ، بیایید به این آخرین برنامه نگاه کنیم. به TWI_I2C_EEPROM.c را باز کنید. اولین چیزی که باید به آن توجه کنید این است که من نحوه برخورد با 24C16 EEPROM کامل را نشان داده ام. در 256 قطعه بایت در 8 آدرس برده مختلف I2C قابل دسترسی است. ببینید چگونه MEMORY_ADDR به عنوان آدرس شروع در 50 هگزادسیمال تعریف شده است. به همین دلیل رم کار کرد اگر می خواهید به بلوک های دیگر 24C16 دسترسی پیدا کنید ، از آدرس های دیگر همانطور که اشاره کردم استفاده کنید. نگاهی به نحوه تنظیمات من برای نوشتن روی حافظه بیاندازید. ابتدا آدرس برده با مجموعه بیت خواندن/نوشتن در بافر ، سپس آدرس شروع 00 ، سپس 16 بایت داده قرار می گیرد. تابع TWI_Start_Read_Write برای نوشتن داده ها (مانند قبل) با اندازه پیام روی 18 تنظیم شده است. وقتی دکمه فشار داده می شود ، از TWI_Start_Random_Read و TWI_Read_Data_From_Buffer برای بازخوانی اطلاعات استفاده می کنیم. هر سوم بایت روی LED های Port Expander نمایش داده می شود. در نهایت ، LED ها خاموش می شوند تا منتظر فشار بعدی دکمه باشید. شاید تعجب کنید که چرا من نوشتن 16 بایت را انتخاب کردم. اگر برگه اطلاعات را با دقت بخوانید ، خواهید دید که 24C16 هر زمان که 16 بایت دریافت می کند ، یک چرخه نوشتن را انجام می دهد ، حتی اگر بایت های بیشتری ارسال شود. بنابراین به نظر می رسید از آن عدد خوبی استفاده کنید. اگر می خواهید این مقدار را افزایش دهید ، باید اندازه MESSAGEBUF_SIZE را تغییر دهید. همچنین باید مقدار TWI_BUFFER_SIZE را در TWI_Master.h تغییر دهید. این به این دلیل است که درایور داده ها را از بافر پیام برای استفاده در روال سرویس وقفه کپی می کند. تبریک می گویم! شما اکنون آماده استفاده از اتوبوس I2C در پروژه های خود هستید!

مرحله 7: منابع وب

در اینجا پیوندهایی به برگه های داده برای قطعات مورد استفاده برای آزمایش ها آمده است. اگر چیز دیگری دریافت نمی کنید ، قطعاً باید این موارد را دریافت کنید. (آنها دوست دارند در URL های خود از براکت مربع استفاده کنند ، بنابراین نمی توانم آنها را به درستی در اینجا قرار دهم. متأسفیم.] برای رسیدن به منطقه I2C ، Interface را از لیست محصولات انتخاب کنید. می توانید به سایت I2C آنها دسترسی پیدا کنید و دسترسی به تمام برگه های داده و یادداشت های برنامه ای که ارائه می دهند. شرح گذرگاه I2C و جزئیات فنی به ویژه در اینجا آمده است. برگه های داده ATtiny2313 و ATmega168 (کتابهای داده؟) را از Atmel دریافت کنید. یادداشت های برنامه Atmel در اینجا است. به AVR310 و AVR315 نگاه کنید. کد را نیز بگیرید. برای موارد بیشتر I2C اینجا را ببینید.

مرحله 8: یادداشت هایی برای گیک ها

برای علاقه مندان واقعی که می خواهند جزئیات را بدانند ، موارد زیر را باید در نظر داشته باشید اگر به Atmel Apps Notes و کد درایور نگاه کنید:- روش آدرس دهی و فرمان دادن به دستگاه I2C جزء مشخصات نیست! به غیر از آدرس برده و بیت خواندن/نوشتن ، دستورات ، حالت ها و غیره مشخص نشده و مختص دستگاه خاصی است. برای روشن تر شدن این موضوع ، توجه داشته باشید که طرح مورد استفاده در مثال Atmel فقط در مورد آن مثال کاربرد دارد و تقریباً غیر استاندارد است.- پیاده سازی USI از چند جهت مهم با اجرای TWI متفاوت است. + با USI ، زمانبندی توسط نرم افزار ارائه می شود. با TWI توسط یک تولید کننده نرخ بیت ارائه می شود. + روش USI از وقفه ها استفاده نمی کند. TWI انجام می دهد این امر تا حدودی منطقی است زیرا خانواده مگا (با استفاده از TWI) می تواند کارهای دیگر زیادی انجام دهد و نباید توسط انتقال I2C فریب داده شود. نسخه قطع شده برای USI قطعاً امکان پذیر است ، فقط در این دستورالعمل اجرا نشده است. + سخت افزار USI برای I2C بهینه نشده است و فقط می تواند انتقال 8 بیت را انجام دهد. این بدان معناست که برای ارسال بیت نهم (NACK یا ACK) دو انتقال لازم است. سخت افزار TWI به طور خودکار این کار را انجام می دهد. این کار پیاده سازی درایور USI را کمی پیچیده می کند. + تشخیص خطا برای TWI در سخت افزار انجام می شود. USI نیاز به مدیریت نرم افزاری دارد که کار را تا حدودی پیچیده می کند. سخت افزار TWI پیکربندی پورت را مستقیماً کنترل می کند. سخت افزار USI نیاز دارد که بیت های پورت قبل از استفاده از پورت پیکربندی شوند. این را در روال Master_Initialize برای USI مشاهده خواهید کرد.-Atmel ادعا می کند که می توان از کشش های پورت AVR برای کشش های گذرگاه I2C استفاده کرد. من راهی برای عملی کردن این روش پیدا نکرده ام. استفاده از دو مقاومت خارجی یک طرح بسیار ساده به نظر می رسد ، بنابراین من زمان زیادی را صرف این کار نکردم.

توصیه شده: