پروتکل I2C در AVR
- 3.12k بازدید
- نوشته شده توسط منشورسیمین
- آموزش های مهندسی الکترونیکی
با سلام در این پست قصد داریم نحوه تبادل داده در میکروکنترلرهای AVR را با استفاده از پروتکل I2C توضیح دهیم که امیدوارم مورد استفاده عزیزان قرار بگیرد.
I2C یا (IIC (Inter integrated circuits یک نوع گذرگاه رابط است که در بسیاری از مدارهای مجتمع از جمله سنسورها، حافظه ها و rtc ها جهت تبادل داده پیاده سازی شده است. بسیاری این رابط را رابط دو سیمه یا (TWI(Two Wire Interfaceمی نامند.در میکرو کنترلر AVR دو پایه با نامهای SCK و SDA به این گذرگاه اختصاص داده شده است. پایه( SCK(serial clock برای ایجاد پالس جهت همزمانی ارتباط بکار می رود و پایه (SDA(serial data جهت ارسال و دریافت داده بکار می رود. پایه های مذکور از لحاظ الکتریکی کلکتور باز هستند.یعنی برای استفاده از آنها باید با یک مقاومت ۴٫۷ کیلو اهمی به مثبت مدار متصل شوند. اگر چندین دستگاه توسط دو خط مربوط به i2c به یکدیگر متصل شوند هر خط تنها وقتی یک می ماند که هیچکدام از دستگاه های متصل، آن را یک نکرده باشند. هنگامی که خط در حالت بیکاری باشد دو پایه i2c در حالت یک قرار می گیرند. در avr تا ۱۲۰ دستگاه مختلف می توانند از طریق رابط i2c به آن متصل شوند که به هر کدام از این اتصال ها یک گره میگویند. هرکدام از این دستگاه ها می توانند یا فرمانده باشند و یا فرمانبر.دستگاه فرمانده گره ای است گه وظیفه تولید پالس ساعت و آغاز و پایان تبادل داده را بر روی خط به عهده دارد. گره فرمانبر دریافت کننده پالس ساعت است و توسط فرمانده آدرسدهی می شود.هر فرمانبر و فرمانده می توانند در دو حالت دریافت کننده یا ارسال کننده عمل کنند.یعنی چهار حالت پیش می آید که عبارتند از: فرمانده ارسال کننده، فرمانده دریافت کننده، فرمانبر ارسال کننده، فرمانبر دریافت کننده.
ساختار داده در i2c
ساختار بیت
i2c یک پروتکل همزمان است و انتقال هر بیت بر روی خط داده بوسیله یک لبه پایین رونده خط ساعت همزمان می شود.بر اساس قوانین i2c تنها در زمانی می توان سطح منطقی خط داده را تغییر داد که سطح منطقی خط ساعت در حالت صفر باشد. البته حالتهای آغاز و پایان از این قانون مستثنی هستند.
حالت آغاز و حالت پایان
I2C یک پروتکل ارتباط محور است یعنی هر فرایند انتقال داده با یک حالت آغاز شروع شده و با یک حالت پایان خاتمه می یابد. توجه داشته باشید که ایجاد حالت آغاز و پایان تنها توسط گره فرمانده انجام می شود. به دلیل اینکه ارسال داده و ایجاد حالت های آغاز و پایان، همه بر روی خط داده انجام می شوند پس باید مابین آنها تفاوت هایی باشد. حالت های آغاز و پایان تنها در زمان بالا بودن خط ساعت ایجاد می شوند.حالت آغاز زمانی ایجاد می شود که در زمان بالا بودن خط ساعت یک لبه پایین رونده در خط داده ایجاد شود و حالت پایان هنگامی ایجاد می شود که در هنگام بالا بودن خط ساعت یک لبه بالا رونده در خط داده ایجاد شود.
قضیه از این قرار است که هنگامی که فرمانده بخواهد داده ای را به فرمانبر مشخصی ارسال کند ابتدا حالت آغاز را بر روی خط ایجاد میکند و پس از آن آدرس فرمانبر را بر روی خط داده قرار می دهد. در صورتیکه فرمانبر آدرس خود را دریافت کند بیت Ack را بر روی خط داده قرار می دهد. بیت ACK بیتی است که جهت تایید صحت دریافت آدرس و یا داده مابین فرمانده و فرمانبر مبادله می شود و مقدار آن صفر است.در مقابل بیت NACK وجود دارد که عدم صحت دریافت داده یا آدرس و یا عدم آمادگی برای تبادل را به اطلاع طرفین می رساند و مقدار آن یک است.مثلا فرمانده برای ارسال آدرس ۸ پالس ساعت ایجاد می کند و برای اطلاع از تایید دریافت آدرس یک پالس اضافی نیز تولید می کند(یعنی ۹ پالس) در این صورت در پالس نهم اگر فرمانبری آدرس خود را دریافت کرده باشد خط را صفر(acknowledge=ACK) می کند و در غیر این صورت خط در حالت یک(not acknowledge=NACK) می ماند. اگر فرمانده بیت ack را بر روی خط داده ببیند داده هشت بیتی را برای ارسال به فرمانبر با ایجاد ۸پالس ساعت بر روی خط قرار می دهد و برای اطمینان از اینکه فرمانبر داده را دریافت کرده و آماده دریافت داده بعدی هست با ایجاد پالس نهم بیت ACK یا NACK را از فرمانبر در یافت می کند.که اگر ACK دریافت شود به ارسال داده بعدی می پردازد و اگر NACK دریافت شود با ایجاد حالت پایان به ارتباط خاتمه می دهد. پس ساختار بسته داده و آدر س در I2C نه بیتی است که هشت بیت برای داده یا آدرس و یک بیت برای تایید یا عدم تایید دریافت(ACK/NACK) می باشد.
بسته آدرس در I2C که برای آدرس دهی فرمانبر ها استفاده می شود هشت بیتی است که بیت A0 از این ۸ بیت کنترل کننده عملیات خواندن یا نوشتن است. با ۷ بیت باقیمانده می توان تا حد اکثر ۱۲۸ فرمانبر مختلف را آدرس دهی کرد. با توجه به اینکه آدرس ۰۰۰۰۰۰۰ به فراخوانی عمومی اختصاص دارد و نیز آدرس هایی به صورت ۱۱۱XXX در AVR قبلا رزرو شده اند و قابل دسترسی نیستند پس در عمل در مجموع می توان ۱۱۹ فرمانبر مختلف را بر روی یک گذرگاه قرار داد.توجه داشته باشید که در I2C ابتدا بیت پرارزشتر ارسال می گردد. شروع ارتباط همیشه بوسیله دستگاه فرمانده و با ایجاد حالت آغاز بر روی خط انجام می شود. اگر بر روی یک خط چندین فرمانده وجود داشته باشد تنها یک فرمانده می تواند خط را در اختیار بگیرد. اگر دو یا چند فرمانده به طور همزمان حالت آغاز را بر روی خط ایجاد کنند طبق فرایندی به نام داوری(Arbitration) به یکی از فرمانده ها اولویت داده می شود و مابقی فرمانده ها تازمانی که خط اشغال باشد منتظر می مانند. تا زمانی که فرمانده غالب حالت پایان را ایجاد نکند خط اشغال محسوب می شود. اگر فرمانده غالب بخواهد بدون آزاد کردن خط فرمانبر جدیدی را آدرس دهی کند می تواند بدون ایجاد حالت پایان حالت آغاز دوباره ای را ایجاد کند. اگر یک فرمانبر نتواند با سرعتی که فرمانروا پالس ساعت را فراهم می کند اطلاعات را پردازش و آماده کند پس از دریافت و ارسال هر بیت از اطلاعات، فرمانبر می تواند خط scl را صفر کند. در این صورت فرمانروا قادر نخواهد بود که خط scl را یک کند(چون دستگاه ها باهم Wire-and شده اند). بنابراین فرمانروا مطلع می شود که فرمانبر به زمان بیشتری برای پردازش اطلاعات نیاز دارد. به این شیوه بسط دادن زمان یا Clock Stretching گفته می شود.
فرایند نوشتن از طریق i2c
۱- ایجاد حالت آغاز برای شروع عمل نوشتن.
۲-ارسال آدرس فرمانبر و پس از آن ارسال صفر به معنای فرمان عمل نوشتن.
۳- ارسال آدرس اولین خانه ای که باید عمل نوشتن در آن انجان شود.
۴-ارسال داده برای قرار گرفتن در خانه ای که آدرس آن را ارسال کردیم.
۵- ارسال حالت پایان برای خاتمه بخشیدن به فرایند انتقال. توجه کنید در مرحله ۴ می توان هرتعداد داده را که بخواهیم به ترتیب ارسال نماییم.در این صورت داده ها به ترتیب در خانه های حافظه فرمانبر قرار می گیرند. یعنی شماره آدرس خانه ها به صورت خودکار افزایش می یابد. البته این در صورتی است که پس از ارسال هر داده بیت ACK را از طرف فرمانبر دریافت کنیم.هرکجا که بیت NACK دریافت شود دو راه در پیش رو داریم. اول اینکه حالت آغاز را برای ایجاد یک ارتباط جدید ایجاد کنیم و دوم اینکه با ایجاد حالت پایان به ارتباط خاتمه دهیم.
فرایند خواندن از طریق i2c
۱- حالت آغاز را برای شروع فرایند انتقال ارسال می نماییم.
۲- آدرس فرمانبر و پس از آن صفر را به معنای فرمان عمل نوشتن ارسال می نماییم.
۳- آدرس اولین خانه ای را که قرار است از آن بخوانیم به عنوان اولین داده ارسال می نماییم.این عمل باعث مقداردهی اشاره گر داخلی I2C می شود.
۴- حالت آغاز مکرر را برای شروع فرایند انتقال ارسال می کنیم.
۵- آدرس فرمانبر و پس از آن یک را به معنای فرمان عمل خواندن ارسال می نماییم.
۶- داده را از خوانه ای که در مرحله ۳ آدرس آن را ارسال کردیم خوانده و سپس هر چند بایت داده که بخواهیم را از خانه های مجاور بعدی می خوانیم.
۷- حالت پایان را برای خاتمه بخشیدن به فرایند انتقال ارسال می نماییم. توجه کنید که در مرحله ۶ پس از در یافت هر بایت از داده بیت ACK توسط فرمانده باید بر روی خط قرار داده شود تا فرمانبر متوجه آمادگی فرمانده جهت دریافت داده ای بعدی بشود و آنها را به ترتیب برای فرمانده بفرستد. در هر کجا، اگر فرمانده بیت NACK را بر روی خط قرار دهد فرمانبر دیگر داده ای برای فرمانده نمیفرستد و فرمانده مجبور است برای برقراری دوباره ارتباط با همان فرمانبر فرایند را دوباره آغاز کند.پس بعد از مشاهده بیت NACK یا باید دوباره حالت آغاز را ایجاد کرد و یا با ایجاد حالت پایان خط را آزاد کنیم.
ثبات های مربوط به I2C در AVR
در متون فنی شرکت سازنده AVR به جای استفاده از عبارت I2C از عبارت TWI استفاده شده است.پس برای مطابقت بیشتر با متون AVR ما نیز از همین عبارت استفاده می کنیم. در AVR شش ثبات به واحد TWI اختصاص داده شده اند که عبارتند از:
۱- ثبات نرخ بیتی یا (TWBR(TWI Bit Rate Register
این ثبات یک ثبات ۸ بیتی است که با استفاده از آن می توان فرکانس ساعت پایه SCL را تنظیم کنیم. فزکانس این پایه تابع مقدار این ثبات و بیت های پیش تقسیم کننده در ثبات TWSR می باشد.ثبات TWSR بعدا توضیح داده خواهد شد. بوسیله فرمول زیر می توانیم فرکانس این پایه را مشخص کنیم.
۲- ثبات وضعیت TWI یا (TWSR(TWI Status Register
پنج بیت از این ثبات جهت نمایش وضعیت گذرگاه و وضعیت داخلی واحد TWI اختصاص دارد و دو بیت اول بیت های پیش تقسیم کننده پالس ساعت هستند.برای آنکه بتوانیم مقدار بیت های وضعیت را بدست آوریم باید دو بیت کم ارزش را صفر در نظر بگیریم.
۳- ثبات کنترل TWI یا (TWCR(TWI Control Register:
این ثبات یک ثبات ۸ بیتی است که بوسیله آن می توان عملکرد واحد TWI را کنترل کنیم.
یت (TWIE(TWI Interrupt Enable:
در صورتی که وقفه عمومی فعال باشد با یک کردن این بیت پاسخ گویی به وقفه TWI فعال می شود.
بیت (TWEN(TWI Enable:
با یک کردن این بیت واحد TWI فعال می شود.
بیت (TWWC(TWI Write Collision:
اگر به هنگام یک بودن بیت TWINT اقدام به نوشتن بر روی بیت ثبات TWDR کنیم این بیت یک می شود.در صورت نوشتن بر روی TWDR وقتی که TWINT صفر است، این بیت صفر می شود.
بیت (TWSTO(TWI Stop Condition Bit:
اگر در حالت فرمانده باشیم با یک کردن این بیت حالت پایان ارسال می شود.به هنگام ارسال حالت آغاز این بیت به صورت سخت افزاری صفر می شود.
بیت (TWSTA(TWI Start Condition Bit:
اگر درحالت فرمانده باشیم و این بیت را یک کنیم، در صورتی که گذرگاه آزاد باشد حالت آغاز ارسال می شود.
بیت (TWEA(TWI Enable Acknowledge:
یک شدن این بیت باعث فعال شدن تایید دریافت در شرایط زیر می شود:
- چنانچه در حالت فرمانبر واحد تطبیق آدرس آدرس خود را روی گذرگاه پیدا کند و یا به عبار دیگر توسط یک فرمانده آدرسدهی شود.
- در صورتی که در حالت فرمانبر و در حالی که بیت قبول فراخوانی عمومی یک است آدرس ۰۰۰۰۰۰۰ روی گذرگاه دریافت شود.در باره بیت قبول فراخوانی عمومی بعدا توضیح خواهیم داد.
- در صورتی که در حالت دریافت، چه در حالت فرمانده و چه در حالت فرمانبر یک بایت دریافت شود.
اگر این بیت را صفر کنیم دستگاه در هیچ حالتی تایید دریافت ارسال نخواهد کرد، گویی از خط جدا شده است.
بیت (TWINT(TWI Interrupt:
وقتی که سخت افزار واحد TWI وظیفه جاری خود را به پایان برساند این بیت ۱ می شود.چنانچه وقفه فعال باشد یک شدن این بیت باعث اجرای وقفه TWI می شود.با صفر کردن این بیت واحد TWI آغاز به کار می کند. دسترسی به ثبات های TWDR,TWSR و TWCR باید قبل از صفر کردن این بیت انجام شود. اگر در زمان یک بودن این بیت مقدار ثبات TWDR را تغییر دهیم تداخل به وجود می آید و بیت TWWC یک می شود.برای صفر کردن این بیت باید مقدار یک را درون آن بنویسیم.
ثبات داده یا (TWDR(TWI Data Register:
این ثبات یک ثبات ۸ بیتی است که آخرین داده دریافت شده داخل آن قرار می گیرد. همچنین در حالت ارسال برای ارسال داده باید داده را در داخل آن قرار دهیم.تاکید می کنیم که تنها زمانی که مقدار TWINT یک است اقدام به تغییر یا خواندن این ثبات می کنیم. حتی نمی توان ثبات داده را قبل از وقوع اولین وقفه و یک شدن بیت TWINT مقداردهی اولیه کرد.
ثبات آدرس یا (TWAR(TWI Address Register:
در صورتی که میکروکنترلر در حالت فرمانبر تنظیم شود نیاز به یک آدرس برای شناسایی شدن توسط فرمانبر دارد. آدرس مربوطه در این ثبات قرار میگیرد.این ثبات یک ثبات ۸ بیتی است که ۷ بیت پر ارزش آن مربوط به آدرس است و کم ارزشترین بیت آن یعنی بیت ۰ برای فعال سازی پاسخ گویی به وقفه عمومی به کار می رود.چنانچه این بیت ۱ باشد فرمانبر علاوه بر آدرس اختصاصی به فراخوانی عمومی با آدرس ۰۰۰۰۰۰۰ نیز پاسخ خواهد داد و در صورتی که این بیت یک باشد فراخوانی عمومی نادیده گرفته شده و فرمانبر تنها به آدرس موجود در ثبات (آدرس اختصاصی) پاسخ می دهد.
راه اندازی اولیه واحد TWI برای کار در حالت فرمانده:
۱- مشخص کردن فرکانس SCL با مقداردهی بیت های پیش تقسیم کننده در TWSR و مقداردهی ثبات TWBR طبق فرمولی که در بالا توضیح داده شد.
۲-با نوشتن ۱ بر روی بیت TWEN واحد TWI را فعال می کنیم.
ارسال حالت آغاز:
با یک کردن بیت های TWEN,TWSTA,TWINT از ثبات TWCR در حالت فرمانده، حالت آغاز ارسال می شود.پس از این کار باید به طور پیاپی بیت TWINT را جهت اطمینان از ارسال حالت آغاز بررسی کنیم.
ارسال داده:
برای ارسال یک بایت از داده پس از ارسال حالت آغاز مراحل زیر را طی می کنیم:
۱- کپی کردن بایت داده به داخل ثبات TWDR .
۲- یک کردن بیت های TWEN و TWINT از ثبات TWCR برای آغاز ارسال داده.
۳- بررسی پیاپی بیت TWINT تا زمان حصول اطمینان از ارسال داده.(این بیت باید یک شود) به این نکته توجه کنید که پس از ارسال حالت آغاز باید بلافاصله آدرس با بیت نوشتن یا آدرس با بیت خواندن ارسال شود.منظور از آدرس، آدرس دستگاه فرمانبر است.
دریافت داده:
برای دریافت داده پس از ارسال حالت آغاز باید مراحل زیر را طی کنیم:
۱- یک کردن بیت های TWEN و TWINT از ثبات TWCR برای آغاز دریافت داده.
۲- بررسی پیاپی بیت TWINT تا زمان حصول اطمینان از دریافت داده.(این بیت باید یک شود)
۳- خواندن بایت داده از داخل ثبات TWDR.
ارسال حالت پایان:
برای پایان بخشیدن به ارتباط باید حالت پایان را ارسال کنیم.برای این کار باید بیت TWSTO در ثبات TWCR یک شود.توجه داشته باشید که پس از ارسال حالت پایان دیگر نمی توان پرچم TWINT را بررسی کرد.در واقع این کار سودی ندارد.
اگر بخواهیم میکرو کنترلر را درحالت فرمانبر تنظیم کنیم باید مراحل زیر را انجام دهیم
ارسال داده در حالت فرمانبر:
۱- ابتدا با مقدار دهی ثبات آدرس ، آدرس فرمانبر را مشخص می کنیم. ۲-با نوشتن ۱ بر روی بیت TWINT واحد TWI را فعال می کنیم. ۳- یک کردن بیت های TWEN,TWINT,TWEA برای فعال کردن واحد TWI و ایجاد تایید دریافت در صورت مشاهده آدرس خود بر روی گذرگاه. پس آنکه فرمانبر آدرس خود را بر روی گذرگاه مشاهده کند بیت TWINT را یک می کند. اگر فرمانده قصد خواندن داشته باشد برای ارسال داده به آن باید ابتدا بایت داده به داخل ثبات داده کپی شود و سپس بیت های TWEN,TWEA و TWINT برای آغاز ارسال داده یک شود.در صورتی که پس ارسال داده انتظار دریافت بیت ACK از طرف فرمانده را نداشته باشیم می توانیم بیت TWEA را یک نکنیم.البته این کار هیچ تاثیری بر ایجاد ACK از طرف فرمانده ندارد. در نهایت با بررسی پیاپی پرچم TWINT از ارسال داده مطمئن می شویم.
دریافت داده در حالت فرمانبر:
یک فرمانبر پس از آنکه توسط فرمانده برای عمل نوشتن فراخوانی شد مراحل زیر را برای در یافت داده انجام می دهد. ۱- یک کردن بیت های TWEN,TWINT برای آغاز دریافت داده.اگر فرمانبر بخواهد پس از دریافت داده ACK ارسال کند باید بیت TWEA نیز یک شود. ۲-بررسی پیاپی پرچم TWINT تا زمان حصول اطمینان از دریافت داده.این پرچم باید یک شود. ۳-خواندن بایت داده از درون ثبات TWDR. همانطور که گفتیم در TWI ثباتی وجود دارد به نام ثبات وضعیت(TWSR) که بوسیله آن می توانیم از وضعیت واحد TWI مطلع شویم. یعنی در هر عملیات از واحد TWI مانند عملیات آغاز و مراحلی که در بالا توضیح داده شد، این ثبات توسط واحد TWI به صورت خودکار مقداردهی می شود.ما می توانیم با بررسی مقدار آن از وضعیت ارتباط مطلع شویم.جداول عددی مربوط به هر حالت ممکن در ادامه آمده است.البته به یاد داشته باشید که در خواندن مقدار ثبات وضعیت دو بیت کم ارزشتر که جهت تنطیم فرکانس ساعت TWI استفاده می شوند باید حذف شوند.
جدول وضعیت های مربوط به حالت فرمانده ارسال کننده:
مقدار ثبات TWSR | وضعیت واحد TWI |
۰x08 | حالت آغاز ایجاد شده است |
۰x18 | آدرس فرمانبر با بیت نوشتن ارسال شده و ACK توسط فرمانده دریافت شده است. |
۰x20 | آدرس فرمانبر با بیت نوشتن ارسال شده و NACK توسط فرمانده دریافت شده است. |
۰x28 | داده ارسال شده و ACK توسط فرمانده دریافت شده است. |
۰x30 | داده ارسال شده و NACK توسط فرمانده دریافت شده است. |
جهت روشن شدن موضوع به طوور نمونه با توجه به جدول بالا در حالت فرمانده ارسال کننده پس از آنکه بیت های TWEN,TWIN,TESTA جهت ایجاد حالت آغاز یک شدند باید بیتTWINT به طور پیاپی بررسی شود.پس از آنکه این بیت یک شد ثبات وضعیت خوانده می شود.بعد از حذف دوبیت کم ارزش این ثبات اگر عدد مربوطه ۰X08 باشد یعنی حالت آغاز به درستی ارسال شده است. به این نکته توجه داشته باشید که عدد درون ثبات وضعیت همیشه در هر مرحله ای پس از یک شدن بیت TWINT معتبر است و تا زمانی که این بیت را صفر نکنید می توانید در مورد ثبات وضعیت تصمیم گیری کنید. در ادامه جداول مربوط به حالت های دیگر آورده شده است.
وضعیت های مربوط به حالت فرمانده دریافت کننده:
مقدار ثبات TWSR | وضعیت واحد TWI |
۰x08 | حالت آغاز ایجاد شده است |
۰x40 | آدرس فرمانبر با بیت خواندن ارسال شده و ACK توسط فرمانده دریافت شده است. |
۰x48 | آدرس فرمانبر با بیت خواندن ارسال شده و NACK توسط فرمانده دریافت شده است. |
۰x50 | داده دریافت شده و ACK توسط فرمانده ارسال شده است. |
۰x58 | داده دریافت شده و NACK توسط فرمانده ارسال شده است. |
وضعیت های مربوط به حالت فرمانبر ارسال کننده:
مقدار ثبات TWSR | وضعیت واحد TWI. |
۰xA8 | آدرس اختصاصی با بیت خواندن دریافت شده و ACK ارسال شده است. |
۰xB8 | بایت داده ارسال شده و ACK دریافت شده است.امکان ادامه فرایند انتقال وجود دارد. |
۰xC0 | بایت داده ارسال شده و بیت NACK دریافت شده است. |
۰xC8 | بایت داده ارسال شده و ACK دریافت شده.ولی امکان ادامه فرایند انتقال وجود ندارد. |
وضعیت های مربوط به حالت فرمانبر دریافت کننده:
مقدار ثبات TWSR | وضعیت واحد TWI. |
۰x60 | آدرس اختصاصی با بیت نوشتن دریافت شده و ACK ارسال شده است.برای فراخوانی عمومی عدد وضعیت ۰x70 می باشد. |
۰x80 | بایت داده دریافت شده و ACK ارسال شده است.برای فراخوانی عمومی عدد وضعیت ۰x90 می باشد. |
۰x88 | بایت داده دریافت شده و بیت NACK ارسال شده است.برای فراخوانی عمومی عدد وضعیت ۰x98 می باشد. |
۰xA0 | حالت پایان یا آغاز مجدد از طرف فرمانده دریافت شده است |
کد برنامه فرمانبر
کد برنامه فرمانده
امیدوارم که مجموعه آموزش های ارتباط سریال براتون مفید بوده باشه.
بخش بعدی: پروتکل SPI در AVR
موفق باشید!!