بخش چهاردهم آموزش AVR : آموزش کامل ارتباط سریال I2C

بخش چهاردهم آموزش AVR : آموزش کامل ارتباط سریال I2C

مقدمه

همانطور که در قسمت های قبلی آموزش گفته شد ، در میکروکنترلرهای AVR ارتباط سریال در 4 پروتکل زیر وجود دارد :

  1. USART : پایه های Rx و Tx
  2. SPI : پایه های MISO ، MOSI ، SCK و SS
  3. I2C : پایه های SDA و SCL
  4. USB : پایه های D+ و D-

نکته : تنها برخی از میکروکنترلرهای AVR از ارتباط USB پشتیبانی می کنند و در Atmega32 ارتباط USB وجود ندارد.

i2c_bus


معرفی ارتباط سریال I2C

I2C مخفف عبارت Inter Integrated Circuit به معنای مدار مجتمع یکپارچه می باشد. به علت اینکه در این پروتکل تنها از دو سیم برای ارتباط دو یا چند وسیله استفاده می شود ، این پروتکل را ارتباط دو سیمه ( TWI ) مخفف Two Wire Interface نیز می نامند. این پروتکل توسط شرکت philips در سال 1982 طراحی و به کار گرفته شد.

از خصوصیات این رابط در میکروکنترلرهای AVR میتوان به موارد زیر اشاره نمود :

  1. رابطی انعطاف پذیر ، قدرتمند و با سرعتی نسبتا مناسب که فقط نیاز به دو خط انتقال دارد.
  2. قابلیت پشتیبانی از مدهای عملکرد Master و Slave در حالت های فرستنده و گیرنده.
  3. دارای 7 بیت آدرس دهی که قابلیت ارتباط یک Master با حداکثر 128 Slave را فراهم می کند.
  4. پشتیبانی از ارتباط تعدادی Master با هم ( Multi Masters )
  5. حداکثر سرعت انتقال اطلاعات تا 400KHz
  6. حذف نویز مدارات روی گذرگاه
  7. محدودیت در نرخ چرخش ( SlewRate ) در خروجی درایور ها
  8. بیدار شدن خودکار میکروکنترلر از حالت Sleep به محض ارسال آدرس آن
  9. قابلیت فراخوانی عمومی همه Slave ها توسط Master

 


شبکه بندی Master و Slave ها در پروتکل I2C

i2c_architecture

همانطور که در شکل فوق مشاهده می کنید ، در این پروتکل تمامی دستگاه ها به دو سیم SDA و SCL متصل شده و هر یک از خطوط توسط یک مقاومت بالاکش PullUp به منبع تغذیه وصل می شوند. خط SDA برای انتقال دیتای سریال ( Serial Data ) و خط SCL برای انتقال کلاک سریال ( Serial Clock ) به کار می رود. طبق استاندارد ، مقدار مقاومت پول آپ برای منبع تغذیه 5 ولت برابر 4.7K و برای منبع تغذیه 3.3 ولت برابر 1.5K می باشد.

نکته : استفاده از پروتکل I2C در فواصل بسیار کوتاه میان Master و Slave ها ( کمتر از 20 سانتی متر ) امکان پذیر است. برای فواصل طولانی تر باید تقویت سیگنال صورت گیرد. بنابراین در ارتباطات i2c با فاصله بین 20 تا 70 سانتی متر میتوان از مدار تقویت کننده زیر به جای مقاومت های پول آپ استفاده کرد.

i2c_pullup


قالب بندی ارتباط در پروتکل I2C

i2c_frame

ابتدا به منظور جلوگیری از تداخل دستگاه ها با یکدیگر ، به هر دستگاه یک آدرس منحصر به فرد بین 0 تا 127 اختصاص می یابد. سپس برای ارسال داده به یکی از دستگاه های متصل به باس I2C ، دستگاه Master ابتدا پالس 7 بیتی مربوط به آدرس دستگاه مورد نظر را به صورت سریال ( از MSB با ارزشترین بیت تا LSB کم ارزش ترین بیت ) به همراه یک بیت برای تعیین خواندن از Slave یا نوشتن بر روی آن ( Read/Write ) به باس SDA ارسال می کند و سپس بعد از دریافت آن توسط Slave مورد نظر ، یک بیت مبتنی بر تایید در دسترس بودن Slave به Master ارسال می شود (Aknowledge) سپس دستگاه Master داده های مورد نظر را در قالب 8 بیتی ارسال می کند و پس از ارسال هر بسته 8 بیتی یک بیت Aknowledge دریافت می کند. دریافت داده نیز تقریبا همین قالب را دارد با تفاوت یک بیت که نشان دهنده دریافت است.

باس SCL همواره در حال ارسال کلاک از Master به تمام Slave ها است. به صورتی که هر بیتی که از باس SDA از Master ارسال می گردد ، تنها در لبه های کلاک SCL توسط Slave ها خوانده می شود. در شکل زیر دو باس SDA و SCL را به همراه عملکرد آن مشاهده می کنید.

i2c_protocol

بنابراین قالب دیتا در پروتکل I2C به صورت سه وضعیت زیر می باشد :

وضعیت Start/Stop

در حالت عادی هر دو خط SCL و SDA در وضعیت سکون ( High ) قرار دارند. زمانی که قصد ارسال/دریافت توسط Master را داشته باشیم ، ابتدا یک لبه پایین رونده به منظور شروع ارسال/دریافت توسط Master ایجاد می شود. بعد از وضعیت شروع ، گذرگاه مشغول می باشد و هیچ Master دیگری نباید سعی کند کنترل گذرگاه را بر عهده بگیرد. در پایان عملیات نیز یک لبه بالا رونده به منظور توقف ارسال/دریافت رو گذرگاه قرار می گیرد و از آن به بعد دوباره گذرگاه به حالت آزاد ( عادی ) بر می گردد.

وضعیت ارسال آدرس

در وضعیت آدرس ، یک بسته بندی 9 بیتی بر روی گذرگاه داده از فرستنده به گیرنده ارسال می شود. این 9 بیت تشکیل شده است از 7 بیت آدرس به همراه یک بیت کنترل خواندن یا نوشتن Raed/Write و یک بیت به نام ACK است که گیرنده برای فرستنده ارسال می کند تا مشخص شود کد آدرس دریافت شده صحیح است. بنابراین زمانی که Slave آدرس خود را تشخیص داد ، باید با پایین بردن خط SDA در نهمین سیکل کلاک SCL ، بیت ACK را ارسال نماید. اگر بیت مربوط به R/W یک شده باشد ، زمانی که از وضعیت ارسال آدرس به وضعیت بعدی یعنی وضعیت ارسال/دریافت دیتا برویم ، عملکرد نوشتن Read روی Slave و در صورت صفر بودن این بیت عملکرد خواندن Write روی Slave اجرا می شود.

وضعیت ارسال/دریافت دیتا

در این وضعیت نیز یک بسته بندی 9 بیتی شامل 8 بیت دیتا و یک بیت ACK وجود دارد. تعداد داده ها ممکن است بیشتر از 8 بیت باشد. در این صورت تا زمان پایان همه داده ها ، سیستم در وضعیت ارسال/دریافت دیتا باقی می ماند تا اینکه تمامی داده های در بسته بندی 9 بیتی ارسال/دریافت شوند. در هر بار ارسال/دریافت گیرنده می بایست بعد از دریافت 8 بیت دیتا با Low نمودن خط SDA در نهمین سیکل کلاک SCL ، صحت دریافت را ACK نماید. در غیر این صورت با بالا رفتن خط SDA ، فرستنده متوجه عدم دریافت صحیح شده و دیتا را مجددا ارسال می نماید.

 


مدهای عملکرد واحد TWI

بر اساس فرستنده ( Transmitter ) یا گیرنده ( Reciever ) بودن هر میکرو و اینکه هر میکرو میتواند Master یا Slave باشد. 4 مد عملکرد در واحد TWI به صورت زیر بوجود می آید. یعنی هر یک از میکروکنترلرهای AVR می تواند یکی از چهار حالت زیر را به خود بگیرد :

MT ( یعنی Master و فرستنده ) : در این مد ابتدا توسط Master یک وضعیت Start ایجاد می شود. سپس بایت های داده به سمت گیرنده Slave ارسال می شود.

i2c_MT_mod

MR ( یعنیMaster و گیرنده ) : در این مد Master منتظر وضعیت Start می ماند و سپس تعدادی بایت از Slave ارسال و توسط Master دریافت می شود.

i2c_MR_mod

ST ( یعنی Slave و فرستنده ) : در این مد فرستنده یک Slave است که اطلاعاتی را به یک MR ارسال می کند.

i2c_ST_mod

SR ( یعنیSlave و گیرنده ) : در این مد گیرنده یک Slave است که اطلاعاتی را از یک MT دریافت می کند.

i2c_SR_mod


انواع دسترسی به رابط I2C در کدویژن

برای دسترسی به رابط دو سیمه و استفاده از آن در میکروکنترلرهای AVR بوسیله نرم افزار Codevision به دو صورت زیر میتوان عمل کرد :

  1. دسترسی به واسط I2C با استفاده از واحد سخت افزاری TWI
  2. دسترسی به واسط I2C به صورت نرم افزاری با اضافه کردن هدرفایل i2c.h

 

تفاوت های استفاده از واسط I2C سخت افزاری با نرم افزاری

1- در صورت استفاده از I2C سخت افزاری تنها میتوان پایه های SDA و SCL در میکروکنترلرهای AVR را استفاده نمود در حالی که در صورت استفاده از I2C نرم افزاری میتوان هر دو پایه دلخواه را به عنوان SDA و SCL تعریف و استفاده کرد.

2- در صورت استفاده از I2C نرم افزاری ، بخشی از CPU درگیر تولید پالس های SDA و SCL می شود در حالی که در صورت استفاده از I2C سخت افزاری ، یک واحد مجزا درگیر می شود و سرعت برنامه بیشتر می شود.

3- در صورت استفاده از I2C نرم افزاری ، با اضافه شدن هدرفایل مربوطه میتوان از توابع آماده موجود فقط در حالت های MR/MT استفاده کرد اما در استفاده از I2C سخت افزاری هدر فایل آماده ای نیست و باید با رجیسترها کار کرد. البته میتوان در هر چهار حالت توابع مورد نیاز را به صورت دستی وارد کرد.

 


فعالسازی رابط I2C در کدویزارد

در ابزار کدویزارد برای فعالسازی I2C سخت افزاری به سربرگ TWI و برای فعالسازی I2C نرم افزاری به سربرگ i2c می رویم. شکل زیر تفاوت آن را نشان می دهد.

i2c_TWI


راه اندازی I2C نرم افزاری

برای فعالسازی واحد ارتباطی دو سیمه نرم افزاری بعد از رفتن به سربرگ i2c ، ابتدا پورتی را که میخواهیم به صورت نرم افزاری از آن به عنوان رابط استفاده نماییم را انتخاب و سپس شماره پایه پورت دلخواه را در قسمت SDA Bit و SCL Bit به ترتیب برای خطوط SDA و SCL انتخاب می نماییم. در قسمت پایین سربرگ ابزار کدویزارد برای برخی از آی سی های پرکاربرد مانند LM75 ، DS1307 ، DS1621 ، PCF8563 و PCF8583 تنظیمات خاصی درنظر گرفته است که میتوان با فعال کردن آنها توابع خاصی را برای استفاده در پروژه خود به برنامه افزود.

i2c_codewizard

بعد از تولید کد توسط برنامه کدویزارد مشاهده می شود که هدرفایل i2c.h اتوماتیک به پروژه افزوده شده و تنظیمات مربوط به بیت های SDA و SCL قبل از آن اضافه شده است. با اضافه شدن این هدر فایل میتوان از توابع زیر در پروژه برای ارتباط سریال استفاده نمود.

 


توابع موجود در کتابخانه i2c.h

  1. تابع i2c_init

این تابع گذرگاه TWI نرم افزاری را روی مقادیر SDA و SCL اولیه فراخوانی و راه اندازی می کند. به همین دلیل باید قبل از فراخوانی توابع دیگر این تابع را صدا زد. الگوی این تابع به صورت زیر است :

  1. تابع i2c_start

با اجرای این تابع یک وضعیت Start ایجاد می شود و اگر گذرگاه I2C آزاد باشد ، مقدار یک توسط این تابع باز می گردد و در غیر این صورت مقدار صفر باز خواهد گشت. الگوی این تابع به صورت زیر است :

  1. تابع i2c_stop

با اجرای این تابع یک وضعیت stop بر روی گذرگاه I2C ایجاد می شود. الگوی این تابع به صورت زیر است :

  1. تابع i2c_read

این تابع از گذرگاه I2C یک بایت را می خواند. ورودی این تابع یک بیت ack است. در صورتی که ack=0 باشد بایت وارد شده صحیح ارزیابی نشده است و در صورتی که ack=1 باشد بایت وارد شده صحیح بوده است. الگوی این تابع به صورت زیر است :

  1. تابع i2c_Write

این تابع یک بایت را به گذرگاه I2C ارسال می کند. اگر گیرنده Slave بیت ACK را صادر کرده باشد ، این تابع مقدار یک را باز می گرداند و در غیر این صورت مقدار بازگشتی صفر خواهد بود. الگوی این تابع به صورت زیر است :

 

نکته : این توابع در میکروکنترلرهای سری Atxmega پشتیبانی نمی شود.

نکته : فرکانس I2C نرم افزاری ثابت بوده و قابل تنظیم نمی باشد. در صورتی که فرکانس کاری میکروکنترلر 1 مگاهرتز باشد ، فرکانس I2C نرم افزاری روی 62.5 کیلوهرتز است و هنگامی که فرکانس کاری میکروکنترلر روی 8 مگاهرتز باشد ، فرکانس I2C نرم افزاری روی 400 کیلوهرتز می باشد. ( همواره روی حداکثر فرکانس ممکن است )

نکته مهم : به علت محدودیت های استفاده از توابع I2C نرم افزاری ، فقط میتوان از این توابع در میکروکنترلر Master و در یکی از حالت های MR/MT استفاده نمود.

 

نتیجه : با استفاده از i2c نرم افزاری توسط یک میکروکنترلر Master میتوان با انواع Slave ها نظیر انواع سنسورها ، EEPROM ها و … ارتباط برقرار کرد اما Slave نمیتواند خود یک میکروکنترلر باشد که از i2c نرم افزاری استفاده می کند. بنابراین برای ارتباط میان چند میکروکنترلر بوسیله پروتکل I2C باید از واحد TWI سخت افزاری استفاده کرد.

 


نحوه استفاده از توابع i2c.h

بعد از انجام تنظیمات مربوط به I2C نرم افزاری در کدویزارد و تولید کد میتوان از توابع موجود در هدرفایل i2c.h برای ساخت توابع جدیدی در پروژه استفاده نمود. این توابع عبارتند از یک تابع READ_I2C برای خواندن از دستگاه اسلیوی که به گذرگاه I2c متصل است و یک تابع WRITE_I2C برای نوشتن در دستگاه اسلیوی که به گذرگاه I2C متصل است. ساختار درونی این دو تابع جدید برای هر وسیله ای که به گذرگاه متصل شده باشد متفاوت است. مثلا برای اتصال EEPROM به گذرگاه یک ساختاری باید رعایت شود و برای اتصال سنسورها یا وسیله های دیگر ساختار مخصوص به آن باید رعایت شود که چگونگی این ساختار از روی دیتاشیت آن قطعه بدست می آید. به مثال زیر که در آن یک EEPROM راه اندازی می شود و توابع ساخته شده در آن توجه کنید.

 


مثال عملی شماره 9

برنامه ای برای ارتباط با EEPROM سریال AT24CXX بنویسید که از طریق ارتباط نرم افزاری I2C ، دیتاهایی دلخواه را در EEPROM ذخیره کند و سپس آن ها را روی LCD کاراکتری نمایش دهد.

 


معرفی آی سی های سری AT24CXX

این سری که آی سی های 8 پایه ساخت شرکت Atmel می باشد ، یک حافظه EEPROM به حجم های 2 ، 4 ، 8 ، 16 ، 64 ، 128 ، 256 ، 512 و 1024 کیلوبایت را به صورت ارتباط I2C در اختیار کاربر قرار می دهد. عددی که در آخر نام قطعه مشاهده می شود نشان دهنده حجم آن می باشد برای مثال آی سی AT24C512 دارای 512 کیلوبایت حافظه است. در شکل زیر پایه های این سری را مشاهده می کنید.

AT24CXX_Pin

سه پایه A0,A1,A2 آدرس قطعه را مشخص می کند که شرکت اتمل برای اینکه امکان استفاده از چندین حافظه EEPROM در یک گذرگاه I2C را داشته باشیم ، آن را تعبیه کرده است. بنابراین تا 8 آی سی حافظه را میتوان روی گذرگاه قرار داد.

نکته : برخی از حافظه های سری AT24CXX سه آدرس قطعه ندارند و به جای آن دو یا یک یا صفر بیت آدرس دارند.

پایه حفاظت از نوشتن ( WP ) در صورتی که ولتاژ High داشته باشد ، دیگر نمیتوان در آی سی نوشت.

 


عملیات نوشتن در آی سی EEPROM

طبق گفته دیتاشیت ، برای نوشتن در این آی سی از پروتکل I2C به دو صورت خاص استفاده می شود. اولی برای نوشتن یک بایت در آن و دومی نوشتن یک صفحه ( page ) که متشکل از چندین بایت پشت سر هم ، می باشد.

نوشتن به صورت بایتی

AT24CXX_Byte_Write

در نوشتن به صورت بایتی ابتدا آدرس قطعه مشخص می شود ، سپس آدرس خانه ای از حافظه که میخواهیم در آن بنویسیم مشخص می شود و در نهایت دیتای مورد نظر برای ذخیره ارسال می شود. سیگنال DEVICE ADDRESS خود به صورت زیر می باشد :

AT24CXX_Device_Address

در شکل فوق که سیگنال DEVICE ADDRESS را برای حافظه های 2 تا 16 کیلوبایت مشاهده می کنید. برای بقیه حافظه ها نیز مشابه همین می باشد. به طوری که در همه آن ها ابتدا 1010 ارسال می شود و سپس آدرس قطعه به صورت A2,A1,A0 ارسال می شود. برای قطعاتی که دو یا یک یا صفر بیت آدرس دارند 0 یا 1 بودن آن اهمیتی ندارد.

 

نوشتن به صورت صفحه ای

AT24CXX_Page_Write

نوشتن صفحه ای همانند نوشتن بایتی است با این تفاوت که بعد از ارسال بایت اول ، بایت های دیتاهای بعدی (که در خانه بعد از WORD ADDRESS(N) در حافطه قرار خواهند گرفت ) ارسال می شود و سپس سیگنال STOP ارسال خواهد شد.

 


تابع نوشتن بایتی روی AT24CXX

با توجه به ساختار گفته شده برای نوشتن بایتی روی آی سی میتوان تابع WRITE_I2C را به صورت زیر تعریف کرد :

که در آن write_address_bus همان DEVICE ADDRESS می باشد که برای A2=0,A1=0,A0=0 برابر 160 است.

 


عملیات خواندن از آی سی EEPROM

طبق گفته دیتاشیت ، خواندن از EEPROM به سه صورت امکان پذیر است :

  1. خواندن از آدرس فعلی
  2. خواندن از آدرس مورد نظر
  3. خواندن متوالی

 

1- خواندن از آدرس فعلی

AT24CXX_Current_Address_Read

در این حالت دیتای آخرین آدرسی که وجود دارد برای Master ارسال می شود .

 

2- خواندن از آدرس مورد نظر

AT24CXX_Random_Read

در این حالت ابتدا آدرس قطعه با بیت R/W=0 به Slave ارسال شده و سپس آدرس خانه حافظه مورد نظر ارسال می گردد. سپس دوباره آدرس قطعه این بار با R/W=1 ارسال شده و سپس دیتایی که در آدرس فرستاده شده بود برای Master ارسال می گردد.

 

3- خواندن متوالی

AT24CXX_Sequential_Read

در این حالت از آخرین آدرس موجود یکی یکی دیتا ها را برای Master ارسال می کند.

 


تابع خواندن از آدرس مورد نظر آی سی EEPROM

با توجه به ساختار گفته شده برای خواندن از آی سی میتوان تابع READ_I2C را به صورت زیر تعریف کرد :

که در آن write_address_bus همان DEVICE ADDRESS می باشد که برای A2=0,A1=0,A0=0 برابر 160 و read_address_bus با R/W=1 و برابر 161 است.

 


حل مثال عملی شماره 9 :

مرحله اول : طراحی سخت افزار

در این مرحله LCD و آی سی EEPROM با هر حجم دلخواهی را از کتابخانه آورده و به هر پورت دلخواهی از میکرو متصل می نماییم. در اینجا از 24C512 استفاده کردیم.

i2c_proteus

مرحله دوم : طراحی نرم افزار

در شکل زیر تنظیمات کدویزارد برای این مثال را مشاهده می کنید.

i2c_Mesal9_codewizard

بعد از تولید کد توسط کدویزارد و حذف کدهای غیر ضروری برنامه اصلی را به صورت زیر خواهیم داشت :

 توضیح برنامه :

در این برنامه یک متغیر دلخواه 8 بیتی با مقدار 55 در همه خانه های حافظه EEPROM از آدرس 0 تا 99 ریخته می شود و سپس دوباره از آی سی خوانده شده و در آرایه کاراکتری buffer برای نمایش در LCD ریخته می شود. توابع خواندن و نوشتن در آی سی EEPROM به علت 512 کیلو بایتی بودن آن تغییر کوچکی کرده است به طوری که پهنای آدرس 16 بیتی است و در دو مرحله برای آی سی باید ارسال شود.

 

مرحله سوم : شبیه سازی در پروتئوس

i2c_Proteus_Mesal9

دانلود مثال عملی شماره 9

 


راه اندازی پروتکل I2C به صورت سخت افزاری

برای فعالسازی واحد ارتباطی دو سیمه پس از رفتن به سربرگ TWI ابتدا آن را با زدن تیک مربوطه فعال می کنیم. در صورتی که میکروکنترلر در یکی از مدهای SR/ST قرار خواهد داشت ، انتخاب گزینه General Call Recognition موجب پاسخگویی این میکروکنترلر به فراخوانی عمومی ( در آدرس 00Hex ) می گردد. برای پاسخ گویی معمولی میکروکنترلر در یکی از مدهای SR/ST باید آدرس آن را در بخش Slave Adress تنظیم نمود.

انتخاب گزینه General Acknowledge موجب تولید پالس ACK در سه حالت زیر خواهد شد :

  1. Slave آدرس خود را تشخیص داده باشد.
  2. یک فراخوانی عمومی دریافت شود ( باید گزینه General Call Recognition فعال بوده باشد )
  3. داده جدیدی در مد MR یا SR دریافت شود.

از بخش Bit Rate نیز جهت تنظیم حداکثر فرکانس پالس های روی خط SCL استفاده می شود. حداکثر فرکانس قابل انتخاب 400 کیلو هرتز است. اگر نیاز به فعال کردن وقفه سریال دوسیمه داشته باشید گزینه 2wire Interrupt را فعال نمایید تا تابع سابروتین وقفه زیر در ابتدای برنامه اضافه شود.

TWI_codewizard


نحوه استفاده از واحد TWI

برای استفاده از ارتباط I2C سخت افزاری ابتدا شبکه بندی دستگاه ها را به صورت استاندارد انجام داده و سپس تنظیمات کدویزارد را برای برنامه مورد نظر انجام می دهیم. حال در برنامه تولید شده توسط کدویزارد می بایست با رجیسترهای واحد TWI کار کرد. همانند توابعی که در قسمت قبل برای I2C نرم افزاری وجود داشت ، برای I2C سخت افزاری نیز وجود دارد که از آنها استفاده خواهیم کرد.

 


معرفی رجیسترهای واحد TWI

TWAR : مخفف TWI Address Register می باشد. یک رجیستر 8 بیتی است که 7 بیت پر ارزش آن آدرس Slave و بین 0 تا 127 است. همچنین بیت کم ارزش آن برای فعال/غیرفعال کردن قابلیت General Call یا فراخوانی عمومی است.

TWBR : مخفف TWI Bit Rate Register می باشد. عددی که در این رجیستر قرار می گیرد طبق رابطه زیر فرکانس کلاک کاری واحد TWI (فرکانس SCL) را مشخص می کند.

TWCR : مخفف TWI Control Register می باشد. بیت های این رجیستر به صورت شکل زیر می باشد.

TWI_TWCR

بیت TWIE( مخفف TWI Interrupt Enable ) : فعال/غیرفعال کردن وقفه واحد TWI

بیت TWEN( مخفف TWI Enable) : فعال/غیرفعال کردن کل واحد TWI

بیت TWWC( مخفف TWI Write Collision ) : اگر به هنگام یک بودن بیت TWINT اقدام به نوشتن بر روی بیت ثبات TWDR کنیم این بیت یک می شود.در صورت نوشتن بر روی TWDR وقتی که TWINT صفر است، این بیت صفر می شود.

بیت TWSTO( مخفف TWI Stop Condition Bit) : اگر در حالت Master باشیم با یک کردن این بیت یک وضعیت پایان ارسال می شود. به هنگام ارسال حالت آغاز این بیت به صورت سخت افزاری صفر می شود.

بیت TWATA( مخفف TWI Start Condition Bit) : اگر درحالت Master باشیم و این بیت را یک کنیم، در صورتی که گذرگاه آزاد باشد حالت آغاز ارسال می شود.

بیت TWEA( مخفف TWI Enable Acknowledge ) : یک کردن این بیت باعث فعال شدن تایید دریافت یا ACK می شود.

نکته : اگر این بیت را صفر کنیم دستگاه در هیچ حالتی تایید دریافت ارسال نخواهد کرد، گویی از خط جدا شده است.

بیت TWINT ( مخفف TWI Interrupt ) : وقتی که سخت افزار واحد TWI وظیفه جاری خود را به پایان برساند این بیت ۱ می شود. چنانچه وقفه فعال باشد یک شدن این بیت باعث اجرای وقفه TWI می شود. با صفر کردن این بیت واحد TWI  آغاز به کار می کند. دسترسی به ثبات های TWDR,TWSR و TWCR باید قبل از صفر کردن این بیت انجام شود. اگر در زمان یک بودن این بیت مقدار ثبات TWDR را تغییر دهیم تداخل به وجود می آید و بیت TWWC یک می شود. برای صفر کردن این بیت باید مقدار یک را درون آن بنویسیم.

TWDR : مخفف TWI Data Register می باشد. در این رجیستر آخرین داده دریافت شده قرار می گیرد. همچنین در حالت ارسال برای ارسال داده باید داده را در داخل آن قرار دهیم. تنها زمانی که مقدار TWINT یک است میتوان به این رجیستر دسترسی داشت.

TWSR : مخفف TWI Status Register می باشد. پنج بیت از این ثبات جهت نمایش وضعیت گذرگاه و وضعیت داخلی واحد TWI اختصاص دارد و دو بیت اول بیت های پیش تقسیم کننده پالس ساعت هستند. برای آنکه بتوانیم مقدار بیت های وضعیت را بدست آوریم باید دو بیت کم ارزش را صفر در نظر بگیریم.

 


راه اندازی واحد TWI در میکروکنترلر Master

برای استفاده راحت تر از قابلیت های واحد TWI در میکروکنترلر Master یک کتابخانه با نام twi_master.h ایجاد می کنیم. درون این کتابخانه یک سری ثوابت به صورت define و نیز یک سری توابع برای کار با واحد TWI تعریف شده است. با اضافه کردن این هدر فایل به صورت دستی به برنامه میکروکنترلر Master توابع زیر در برنامه قابل استفاده هستند. با استفاده از این توابع میتوان توابع دیگری بسته به برنامه مورد نظر ایجاد کرد.

  1. تابع twi_start

با اجرای این تابع یک وضعیت Start ایجاد می شود. الگوی این تابع به صورت زیر است :

  1. تابع twi_write

این تابع ورودی خود را به Slave ارسال می کند. الگوی این تابع به صورت زیر است :

  1. تابع twi _read

این تابع ابتدا وضعیت ACK را برای دریافت داده بوجود آورده و سپس دیتا را از Slave دریافت می کند و به خروجی تابع می فرستد. الگوی این تابع به صورت زیر است :

  1. تابع twi_stop

با اجرای این تابع یک وضعیت stop بر روی گذرگاه I2C ایجاد می شود. الگوی این تابع به صورت زیر است :


تابع مد Master در حالت گیرنده ( MR )

این تابع آدرس دستگاه Slave را به عنوان ورودی می پذیرد و منتظر دریافت داده از Slave مورد نظر می ماند. سپس دیتای مورد نظر را به خروجی تابع بر می گرداند.

 


تابع مد Master در حالت فرستنده ( MT )

این تابع که یک آدرس و یک دیتا در ورودی خود دریافت می کند ، ابتدا آدرس دستگاه Slave و سپس دیتای مورد نظر را به گذرگاه I2C ارسال می کند.

 


راه اندازی واحد TWI در میکروکنترلر Slave

برای هر تعداد میکرو کنترلر اسلیوی که در پروژه وجود دارد باید آدرس منحصر به فردی را در ابتدای برنامه به صورت دلخواه برای آن وارد نمود. برای این منظور #define Slave_address در برنامه وجود دارد. همچنین لازم است وقفه TWI آن در هنگام تنظیمات کدویزارد فعال شود. بعد از فعال شدن وقفه در زیر برنامه وقفه کد زیر نوشته می شود. در زیر برنامه وقفه متغیر TWIRecievedData مقدار دهی می شود که از آن در جاهای دیگر برنامه استفاده می شود.

 

تعریف وضعیت ها در میکروکنترلر Slave

کلیه وضعیت های موجود در پروتکل TWI که در رجیستر TWSR وجود دارد برای راحتی به عنوان ثابت در ابتدای برنامه تعریف می شود. چون همیشه به این ثوابت در برنامه احتیاج داریم ، آن ها را درون هدر فایل twi_slave.h می ریزیم.

 

زیر برنامه وقفه TWI در میکروکنترلر Slave

 


مثال عملی شماره 10 

برنامه ای برای ارتباط دو میکروکنترلر Master و Slave به صورت شبکه ، از طریق واسط TWI بنویسید ، به طوری که یک عدد برای یکدیگر ارسال کرده و عدد ارسالی روی LCD طرف دیگر نمایش داده شود.

حل :

مرحله اول : رسم سخت افزار در پروتئوس

 TWI_proteus 

مرحله دوم : تنظیمات کدویزارد

برای میکروکنترلر Master

TWI_codewizard_m10

برای میکروکنترلر Slave

یک آدرس دلخواه مثلا 45 قرار می دهیم.

TWI_m10_slave

مرحله سوم : تکمیل برنامه

برای میکروکنترلر Master :

 

برای میکروکنترلر Slave :

توضیح برنامه : در برنامه Master طبق پروتکل I2C ، ابتدا عدد 55 به تمامی Slave ها ( فراخوان عمومی ) ارسال می شود. سپس به میکروکنترلر Slave که آدرس آن 0x45 است ، دیتای 10 ارسال می شود و در نهایت میکروکنترلر Master دیتایی را از Slave دریافت کرده و روی LCD نمایش می دهد. میکروکنترلر Slave نیز طبق پروتکل I2C عمل می کند. تمام برنامه Slave درون تابع وقفه اتفاق می افتد. به طوری که در هر وقفه ، وضعیت کنونی میکرو شناسایی شده و طبق آن وضعیت به ارسال یا دریافت داده می پردازد. در صورت دریافت دیتا از جانب Master آن را روی LCD نمایش می دهد. در صورت درخواست Master برای ارسال دیتا عدد 44 برای آن ارسال می گردد.

 

مرحله چهارم : شبیه سازی

TWI_m10_proteus

دانلود سورس مثال عملی شماره 10

 



در صورتی که این مطلب مورد پسندتان بود لایک و اشتراک گذاری فراموش نشود.

این مطلب را با دوستانتان به اشتراگ بگذارید

پاسخ دهید

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

5 + پانزده =