۳-۹ معرفی توابع I2C در CodeVision
۲۹ بهمن ۱۳۹۷معرفی داریور موتور استپر MSD02
۲۹ بهمن ۱۳۹۷
این ماژول از خانوادهی ماژولهای بسیار پر کاربرد SRF است که برای اندازهگیری فاصله از آنها استفاده میشود. این ماژول برای فواصلی از ۳ سانتیمتر تا ۶ متر ساخته شده است و دقتی در حد سانتیمتر دارد.
همانطور که در شکل ۴ میبینید مشخصات راه اندازی این ماژول آورده شده است.
دو پایهی SDA و SCL باید به ترتیب به پایههای SDA و SCL انتخاب شده در میکرو متصل شوند و همچنین تغذیهی ماژول نیز همانند شکل فراهم شود. برای خواندن اطلاعات از یک چنین ماژولی باید به برگه اطلاعات ( Data sheet ) آن نگاهی بیندازیم.
در این نوع ماژولها رجیسترهایی در نظر گرفته شدهاند که با نوشتن مقدار خاصی در آنها میتوانیم نوع اطلاعات بازگشتی و تنظیمات این نوع ماژولها را تنظیم کنیم. مثلا به جدول ارائه شده در برگه اطلاعات SRF08 نگاه کنید:
طبق اعلام کارخانهی سازندهی این ماژول در صورت نوشتن مقدار 0X51 در رجیستری به آدرس 0x00 ماژول با یک تاخیر حدود 70 میلی ثانیهای، خروجیای بر حسب سانتیمتر را به ما میدهد. همچنین طبق استاندارد اعلام شده توسط کارخانه سازنده در صورت ارسال اطلاعات به ترتیب زیر این امر امکان پذیر است:
۱- آدرس خود ماژول
۲- آدرس رجیستر
۳- داده هایی که می خواهیم روی رجیستر بریزیم که مشخص کننده ی نوع داده ی بازگشتی است
بنابراین با دانستن این ترتیب به نحو زیر بخشی از عمل دریافت اطلاعات از ماژول را انجام میدهیم که همان اعلام نوع درخواست است.
#include <mega8.h> #include <delay.h> #asm .equ__i2c_port = 0x18 //PORTB .equ__sda_bit = 0 .equ__scl_bit = 1 #endasm #include <i2c.h> int Range1; int Range2; . . . viod srf08_write(char device_addr , char register_addr , char data) { i2c_start(); i2c_write(device_addr); i2c_write(register_addr); i2c_write(data); i2c_stop(); delay_ms(100); }
با استفاده از تابع ()srf08_write میتوانیم اطلاعات را برای ماژول ارسال کرده و تنظیمات مربوطه را انجام دهیم.
در ورودیهای این تابع بخش device_addr باید آدرس ماژول که در حالت اولیه همان 0x00 است قرار داد، در بخش register_addr آدرس رجیستری که میخواهیم روی آن داده را بریزیم میآید که ما در اینجا چون میخواهیم کار با فاصله را انجام دهیم طبق گفتهی کارخانهی سازنده با رجیستر 0x00 کار میکنیم. سپس در بخش دیتا همانطور که در جدول ۱ دیدیم مقدار 0x51 را قرار میدهیم چراکه میخواهیم اطلاعات ما بر حسب سانتیمتر باشد.
حال ماژول آمادهی ارسال اطلاعات است اگر طبق ترتیب زیر اطلاعات جدیدی را برای ماژول بفرستیم میتوانیم اطلاعات محاسبه شده در ماژول را بخوانیم.
۱- ارسال آدرس ماژول
۲- ارسال آدرس رجیستر خواندن که در اینجا 0x02 است.
۳- ارسال آدرس ماژول +1
۴- دوبار خواندن خط داده که اولین خواندن برای خواندن بایت پرارزش بالایی فاصله ی محاسبه شده است و دومین خواندن برای خواندن بایت پایینی یا کم ارزشتر فاصله ی محاسبه شده است.
int srf08_read(char device_addr , char register_addr) { int range; char vh,vl; i2c_start(); i2c_write(device_addr); i2c_write(register_addr); i2c_write(device_addr + 1); delay_ms(100); vh = i2c_read(1); //ack vl = i2c_read(0); //nack i2c_stop(); range = vh*256 + vl; return range; }
در نهایت پس از دریافت این دو بایت آنها را کنار هم قرار داده و مقدار فاصله محاسبه میشود (خط ۱۳).
حال برای کار با این دو تابع در حالت کلی برای محاسبهی فاصله به صورت زیر عمل میکنیم.
while(1) { srf08_write(0xE0 , 0x00 , 0x51); Range1 = srf08_read(0xE0 , 0x02); srf08_write(0xF8 , 0x00 , 0x51); Range1 = srf08_read(0xF8 , 0x02);
با استفاده از قطعه کد بالا میتوانیم از سنسور با آدرس 0xE0 و یا 0xF8 مقدار فاصله را بخوانیم. با این روش میتوانید از دیگر قابلیتهای این ماژول استفاده کنید.
در ماژولهایی که با پروتکل I2C کار میکنند معمولا کار مشابه است و شما با یاد گرفتن کار با این ماژول اغلب در کار با دیگر ماژول ها موفق خواهیدبود.
11 Comments
سلام مرسی بابت کدتون. من اینو با atmega16 تست کردم و ال ای دی چشمک میزنه به طور مرتب در زمان “ping” ولی خروجی عی که دریافت میکنم همون۲۵۵ عه. ممنونم میشم راهنمایی کنید مشکل از کجا میتونه باشه.
با سلام
احتمالا مشکل اصلی شما از ارسال آدرس غلط برای ماژول است، برای اطمینان از آدرس ماژول طبق dataSheet تعداد چشمک زدن های LED وقتی ماژول روشن می شود که نشانگر آدرس ماژول است را بشمارید. به این نحو که بعد از یک چشمک طولانی تعداد چشمک های کوچکتر نمایان گر آدرس فعلی ماژول هستند.
بعد از اطمینان از آدرس ماژول از طریق جدول بالا به تست خود ادامه دهید. مثلا اگر LED بعد از روشن شدن ماژول و یک چشمک طولانی و ۳ چشمک کوتاه زد طبق جدول آدرس ماژول 0xE6 خواهد بود. همچنین نکته ی بسیار مهمتر SDA و SCL باید هر کدام به صورت جداگانه با یک مقاومت ۲۷۰ اهم با ۵ ولت Pull up شوند. نکته ی نهایی اینکه دقت کنین که GND میکروکنترلر و ماژول باید یکی باشند. این کد بارها بر روی موارد مختلف چک شده و از صحت کد نگران نباشید.
بسیار ممنونم که وقت گذاشتید. ولی در هنگام روشن شدن ماژول فقط یک چشمک میزند و در برنامه هم (0xE0) گذاشتم. وپایه های scl و sda رو هم با مقاومت پول آپ کردم وبرنامه هم دقیقا همینه. ولی نتیجه نمیگیرم. به نظرتون میتونه مشکل از کلاک میکرو باشه؟من رو ۸۰۰۰ تنظیمش کردم
۳ نکته وجود داره که باید بهشون توجه کنین:
۱- آیا Ground بین میکروکنترلر و ماژول مشترک است یا خیر؟ هردو باید به یک منبع تغذیه متصل باشند. ( به خاطر داشته باشید هر جا که قصد ارسال و یا دریافت اطلاعات از هر پروتکلی رو دارین باید Ground مشترک باشد)
۲- اطمینان حاصل کنین که میکرو در مد TWI و در حالت Master قرار دارد
۳- فرکانس میکروکنترلر خودتون رو بر روی ۴MhZ تنظیم کنین و هنگام پروگرم کردن میکرو مطمئن بشین که فیوز بیت ها برای ۴Mhz تنظیم شده اند. (فرکانس میکرو ۴۰۰۰۰۰۰ هرتز) نحوه ی تنظیم فیوز بیت ها در دیتا شیت میکروکنترلر آورده شده با عنوان Internal Clock Fuse Bits
مرسی که پاسخگو هستین واقعا . داداش اینو برای یه دوستی میخوام یه مدته دارم روش کار میکنم و ای ۲۵۵ یا -۲۵۵ میده. نکاتی که گفته بودینو چک کردم. تنظیمات i2cعیش درسته و اتصلاعاتم برقرارن و مقاومت های پول آپ هم درستن ولی درمورد سومی که گفتین من کریستال ۸mhz داشتم اونو گذاشتم وتنظیمات تو کدویژن رو بر حسب همون نوشتم اشکالی پیش میاد؟ دیگه واقعا نمیدونم چیکار باید بکنم و واقعا تمام تلاشمو دارم میکنم… نظرتون چیه؟
میتونید ایملتون رو بدین من به دوستم بدم ؟ واقعا کارش گیره
نکته ای که وجود دارد این است که تنظیم کلاک به تنهایی در کدویژن کافی نیست و شما تنها این تنظیمات را در سطح نرم افزار انجام داده اید، لازم است که برای این کار تنظیمات کلاک در سطح سخت افزاری نیز انجام گیرد، به این مفهوم که اولا اگر شما می خواهید از کریستال داخلی میکروکنترلر استفاده کنین طبق جدول زیر به هنگام پروگرم کردن میکرو کنترلر باید فیوز بیت هایی با نام CKSEL به ترتیب در حالت ۱ یا ۰ قرار گیرند. به جدول زیر نگاه کنین:
https://robotmakers.ir/wp-content/uploads/2015/09/AVR-Fusebits.png
طبق جدول بالا شما باید قبل از پروگرم کردن میکرو در نرم افزار پروگرمر خود مقادیر این فیوز بیت ها را تنظیم کرده و سپس میکرو را پروگرم کنین. مثلا برای تنظیم کلاک ۸ مگاهرتز شما باید مقادیر زیر را به رجیسترهای CKSEL بدهید.
CKSEL0=0
CKSEL1=0
CKSEL2=1
CKSEL3=0
این در حالی است که شما از کریستال داخلی میکرو کنترلر استفاده می کنین. برای تنظیمات I2C نیز توصیه می شود PORTA را به عنوان SDA و SCL در نظر بگیرید. به تلاش خود ادامه دهید 😉
سلام دوباره 🙂
من راه انداختم به لطف خدا و دستتونم درد نکنه 🙂 فقط یه مشکلی ک دارم اینه ک. تا ۱۳۰ سانتی فقط میخونه میتونید کمک کنید؟
با سلام
سوال شما در اینجا پاسخ داده شد. لطفا از این پس سوالات خود را در فروم ما مطرح نمایید. با تشکر
بدون میکرو نمیشه راه اندازی بشه؟
سلام
ماژول SRF08 اطلاعات فاصله رو از طریق پروتکل I2C ارسال میکنه که حتما باید توسط یک میکرو راه اندازه بشه.