پروتکل SPI در AVR
- 3.11k بازدید
- نوشته شده توسط منشورسیمین
- آموزش های مهندسی الکترونیکی
امروز به یکی دیگه از پروتکل های ارتباط سریال به نام SPI رسیدیم. که طبق روال گذشته ابتدا اون رو به طور مفصل توضیح می دیم و بعد طی چند مثال بحث را براتون جا می ندازیم. در نهایت هم با یک شبیه سازی در محیط پروتئوس به شما این اطمینان رو می دیم که کد نوشته شده داره درست کار می کنه.
SPI از کلمات serial peripheral interface گرفته شده و به معنای واسط ارتباط سریال بین قطعات جانبی یک گذرگاه است که در بسیاری از مدارهای مجتمع از جمله سنسورها، بسیاری از حافظه ها و انواع گوناگونی از نمایشگرها پیاده سازی شده است. قطعاتی که SPI را پشتیبانی می کنند به جای استفاده از ۸ پایه تنها از دو پایه برای انتقال اطلاعات استفاده می نمایند. یکی با نام MOSI و دیگری با نام MISO. علاوه بر این دو پایه در SPI دو پایه دیگر نیز در انتقال اطلاعات نقش دارند. یکی از این پایه ها برای همزمان کردن انتقال داده ها بین دو طرف استفاده می شود که SCK نام دارد و پایه دیگر که SS نام دارد برای اعلام آغاز و پایان انتقال داده کاربرد دارد.
در جدول زیر نام اختصاری پایه ها و نام کامل آن ها را ملاحضه می کنید:
نام اختصاری | نام کامل |
MOSI | Master output slave input |
MISO | Master input slave output |
SCK | Serial clock |
SS | Slave select |
لازم به ذکر است که در SPI یک Master یا فرمانده وجود و دارد ولی می توان چندین Slave یا فرمانبر داشت. master کنترل کننده ی اصلی است که تمام عملیات ها را کنترل می کند و به سایر slave ها فرمان های لازم را می دهد.
SPI چگونه کار می کند؟
پروتکل SPI شامل دو shift register می باشد که یکی در Master و دیگری در Slave قرار دارد. هم چنین یک مولد پالس ساعت در Master قرار دارد که پالس ساعت را برای ثبات های جا بجایی یا shift register ها فراهم می کند. در شکل زیر می توانید این رجیستر ها و هم چنین نحوه اتصال پایه ها بین Master و Slave را مشاهده کنید.
دقت داشته باشید که MOSI در Master باید به پایه هم نام خودش در Slave یعنی MOSI وصل شود. همین قانون برای MISO هم وجود دارد. این موضوع به این دلیل تذکر داده شد که بعضی ها به اشتباه MOSI را به MISO وصل می کنند.
مولد پالس ساعت در Master پالس ساعت را برای هر دو ثبات جابه جایی که در Master و Slave قرار دارند فراهم می کند و بر روی پایه SCK قرار می دهد. رجیسترهای جابجایی در SPI هشت بیت طول دارند. بنابراین بعد از هشت پالس ساعت اطلاعات داخل دو ثبات جابجایی باهم دیگر تعویض می شود. به این صورت وقتی که Master بخواهد یک بایت اطلاعات را ارسال کند، آن را داخل رجیستر جابجایی خود قرار می دهد و سپس هشت پالس ساعت تولید می کند؛ پس از هشت پالس ساعت محتویات دو رجیستر جابجایی باهم تعویض می شوند و بدین صورت اطلاعات به دستگاه Slave منتقل می شود و اطلاعات ارسالی از Slave هم در Master دریافت می شود. (این انتقال تمام دوطرفه است.)
تنظیمات و استفاده از SPI در AVR
انواع مختلفی از AVR ارتباط SPI را پشتیبانی می کنند. در AVR سه رجیستر برای کار با واحد SPI در نظر گرفته شده است. این سه عبارتند از:
- رجیستر وضعیت یا (SPSR(SPI STATUS REGISTER
- رجیستر کنترل یا (SPCR(SPI CONTROL REGISTER
- رجیستر داده یا (SPDR(SPI DATA REGISTER
رجیستر وضعیت SPI
همانطور که می بینید بیت های ۱ تا ۵ رزو هستند و در مقدار دهی مقدار صفر را میگیرند.
بیت (SPIF(Spi Intrrupt Flag :
این بیت، بیت وقفه SPI می باشد که در صورت یک شدن آن به شرطی که پرچم وقفه عمومی و پاسخ دهی به وقفه SPI یک باشد باعث فراخوانی سرویس وقفه مربوط به SPI می شود. این پرچم در حالت Master در دو صورت یک می شود. در هنگامی که فرایند انتقال اطلاعات پایان یابد و یا زمانی که پایه SS حالت ورودی داشته باشد و از خارج صفر گردد.
بیت (WCOL(Write COLision flag:
این پرچم زمانی یک می شود که در حین انجام عمل انتقال اقدام به نوشتن بر روی ثبات SPDR کنیم.
بیت SPI2IX:
در حالت Master یک کردن این بیت باعث دو برابر شدن سرعت SPI می شود.
نکته: توجه داشته باشید که بیت های SPIF و WCOL در صورتی که ابتدا رجیستر وضعیت را بخوانیم و سپس اقدام به خواندن از رجیستر داده کنیم به صورت خودکار صفر خواهند شد. همچنین بیت SPIF در صورت اجرای وقفه و پرش به سرویس وقفه به صورت خودکار صفر می شود.
رجیستر کنترل SPI
بیت (SPIE(SPI Interrupt Enable:
یک کردن این بیت امکان پاسخ دهی به وقفه ی مربوط به SPI را فعال می کند.
بیت (SPE(SPI Enable:
یک کردن این بیت واحد SPI را فعال می کند.
بیت (DORD(Data OrDer:
به وسیله این بیت می توان مشخص کرد که ابتدا بیت پر ارزش تر ارسال شود یا بیت کم ارزش تر. البته معمولا ابتدا بیت کم ارزشتر ارسال می شود ولی یک کردن این بیت باعث می شود که در موقع ارسال ابتدا بیت کم ارزش تر ارسال شود.
بیت (MSTR(Master/Slave Select:
اگر قصد داشته باشیم در حالت فرمانده کار کنیم باید این بیت را یک کنیم در غیر این صورت حالت کاری فرمانبر انتخاب خواهد شد. اگر در حالت کاری Master پایه ss ورودی شود و از خارج مقدار آن صفر شود بیت MSTR صفر شده و پرچم SPIF یک می شود. کاربر برای برگشتن به حالت Master باید دوباره این بیت را یک کند.
بیت (CPOL(Clock POLarity:
این بیت سطح ولتاژ پالس ساعت را در هنگام عدم فعالیت یا Idle نشان می دهد. سطح پالس ساعت در هنگام عدم فعالیت و در صورت صفر بودن این بیت صفر و در صورت یک بودن آن یک خواهد بود.
بیت (CPHA(Clock PHAse:
با صفر بودن این بیت نمونه برداری در لبه اول پاس ساعت و با یک شدن آن نمونه برداری در لبه دوم پالس ساعت صورت می پذیرد.
بیت های SPR0 و SPR1:
این دو بیت فرکانس SCK را در حالت Master مشخص می کنند.
در جدول زیر نحوه تنظیم این دو بیت را به همراه بیت SP2IX جهت دستیابی به فرکانس های مختلف مشاهده می کنید:
SPI2X | SPR0 | SPR1 | نرخ فرکانس ساعت SPI |
۰ | ۰ | ۰ | fosc/4 |
۰ | ۰ | ۱ | fosc/16 |
۰ | ۱ | ۰ | fosc/64 |
۰ | ۱ | ۱ | fosc/128 |
۱ | ۰ | ۰ | fosc/2 این حالت توصیه نمی شود |
۱ | ۰ | ۱ | fosc/8 |
۱ | ۱ | ۰ | fosc/32 |
۱ | ۱ | ۱ | fosc/64 |
رجیستر داده واحد SPI
رجیستر داده SPI یا SPDR یک رجیستر خواندنی و نوشتنی ۸ بیتی است. اطلاعاتی که داخل این رجیستر ریخته می شود روی رجیستر جابجایی SPI نوشته خواهد شد. هم چنین برای خواندن اطلاعات موجود بر روی رجیستر جابجایی SPI باید اطلاعات را از این رجیستر بخوانیم.
باید توجه داشته باشیم که قبل از ارسال کامل داده قبلی، نباید داده جدیدی بر روی این رجیستر بنویسیم؛ در غیر این صورت با داده قبلی دچار تداخل می شود و پرچم WCOL یک می گردد. هم چنین برای خواندن داده دریافتی قبل از آنکه داده بعدی به طور کامل دریافت شود فرصت داریم.
پایه SS در AVR
همان طور که قبلا توضیح داده شد این پایه برای شروع و یا پایان دادن به یک فرایند انتقال اطلاعات در SPI به کار می رود. اگر در حالت Master این پایه ورودی باشد از خارج باید در سطح یک بماند در غیر این صورت اگر صفر شود میکروکنترلر از حالت Master به حالت Slave تغییر حالت داده و بیت MSTR صفر می شود همچنین بیت SPIF یک شده و یک وقفه ایجاد می شود. ولی اگر درحالت Master این پایه خروجی باشد مانند هر پایه دیگری می توان سطح آن را صفر یا یک کرد بدون آنکه تاثیری بر روی واحد SPI بگذارد. پس برای اطمینان از اینکه میکروکنترلر در حالت Master مانده و به طور ناخواسته به حالت Slave نرود بهتر است در حالت Master این پایه خروجی باشد.
اگر میکروکنترلر در حالت Slave باشد این پایه در حالت ورودی قرار می گیرد و نمی توان آن را به حالت خروجی تغییر داد. در واقع واحد SPI کنترل آن را به دست می گیرد. در این حالت اگر این پایه از خارج صفر شود واحد SPI فعال شده و پین MISO در صورتی که توسط کاربر تنظیم شده باشد، خروجی می شود و سایر پین ها ( MOSI و SCK و SS ) ورودی می شوند. اگر این پایه از خارج یک شود واحد SPI غیرفعال شده و پایه های مربوط به SPI به ورودی تبدیل می شوند ضمن اینکه تمام داده هایی که هنوز دریافت آن ها تکمیل نشده پاک خواهند شد.
مراحل انجام عمل ارسال داده(نوشتن) با SPI
مراحل زیر بعد از تنظیم رجیسترهای واحد SPI برای کار در حالت Master انجام می شود.
- پایه SS برای آغاز انتقال داده صفر می شود.
- ۸ بیت داده که توسط ۸ پالس ساعت همزمان می شود ارسال می گردد. بایت اول بایت آدرس است که همیشه اول ارسال می شود. بیت با ارزش آن یعنی بیت ۷ ابتدا ارسال شده و برای گیرنده مشخص می کند که فرمانبر قصد چه عملیاتی را دارد. اگر این بیت یک باشد هدف از آدرس دهی نوشتن یا ارسال داده و اگر صفر باشد هدف دریافت داده می باشد.
- پس از آنگه Slave هشت بیت آدرس مربوط به خود را دریافت کرد منتظر دریافت داده می شود.
- دستگاه Slave هشت بیت داده را که توسط ۸ پالس ساعت همزمان می شود دریافت می کند.
- دستگاه Master پایه SS را برای نشان دادن پایان انتقال یک می کند.
اگر بخواهیم داده ای را با یک دستگاه جانبی بوسیله SPI بفرستیم باید میکروکنترلر را در حالت کاری Master تنظیم کنیم. برای این کار لازم است که ابتدا بیت MSTR را یک کرده و با مقداردهی بیت های SPI2X, SPR1 و SPR0 تنظیمات توضیح داده شده را انجام دهیم و سپس در آخر بیت SPE را یک می کنیم. در این حالت نوشتن یک بایت بر روی SPDR باعث فعال شدن پالس ساعت و ارسال اطلاعات می شود و با تکمیل ارسال بیت SPIF یک می شود. در اینجا محتویات رجیستر های جابه جایی Master و Slave با هم جابه جا می شوند. یعنی با ارسال یک بایت همزمان یک بایت هم دریافت می کنیم.
برای درک بهتر توضیحات بالا یک مثال را مطرح کرده و بررسی می کنیم.
مثال۱: برنامه ای بنویسید که واحد SPI را برای کار در مد صفر (یعنی بیت های CPOL و CPHA صفر باشند) و حالت کاری فرمانده با ۱/۴ فرکانس کریستال (۸MH) تنطیم کند و سپس حرف A را ارسال کرده و داده دریافت شده را روی پورت A نمایش دهد.
راهنمایی: توجه کنید که در حالت فرمانده باید پایه هایی از پورت که به MOSI,SCK و SS تعلق دارند خروجی شوند و پورت مربوط به MISO باید ورودی شود.
نحوه نوشتن چند بایت پشت سر هم
فرایند بالا مربوط به ارسال یک کاراکتر می باشد. اگر بخواهیم بدون قطع کردن ارتباط(یک کردن SS) چندین بایت را پس از یک بار آدرس دهی به Slave بفرستیم باید آدرس اولین خانه از Slave را که قرار است عملیات نوشتن از آنجا شروع شود بفرستیم و سپس داده ها را یکی یکی و به ترتیب ارسال کنیم بدون اینکه پایه SS را یک کنیم. همچنین دقت شود که بیت ۷ از آن باید به نشانه عملیات نوشتن ۱ باشد. بعد از ارسال تمامی داده ها پایه SS را برای خاتمه دادن به تبادل یک می گنیم.
مراحل انجام عمل خواندن
- صفر کردن پایه SS برای آغاز انتقال داده.
- ارسال ۸ بیت آدرس. توجه کنید که برای نشان دادن عمل خواندن باید بیت ۷ آدرس صفر باشد.
- پس از دریافت آدرس توسط Slave، دستگاه Master آماده ارسال داده می شود.
- Slave هشت بیت داده را همزمان با ارسال ۸ پالس ساعت ارسال می کند.
- Master پایه SS برای نشان دادن پایان انتقال داده یک می کند.
فرایند بالا جهت دریافت یک بایت از Slave به کار می رود. اگر نیاز باشد که در یک برقراری ارتباط بین Slave و Master چندین بایت از Slave به Master منتقل شود باید در مرحله دوم آدرس اولین خانه حافظه از دستگاه Slave که قرار است اطلاعات از آنجا دریافت شود ارسال گردد همچنین بیت ۷ آن باید به نشانه عملیات خواندن صفر باشد. بعد از آن داده ها پشت سر هم و بدون نیاز به آدرس دهی مجدد برای Master ارسال می گردد.
تنظیم میکرکنترلر در حالت Slave
اگر بخواهیم میکروکنترلر در حالت Slave قرار بگیرد باید بیت MSTR صفر باشد. در حالت Slave نیازی به تنظیم فرکانس پالس ساعت نیست چون پالس ساعت توسط Master تامین می شود. تنها باید بیت های CPHA, DORDو CPOL مطابق با Master تنظیم شوند تا بر سر موقعیت مکانی و زمانی پالس ساعت و همچنین این که ابتدا بیت با ارزش بالا ارسال شود یا بیت با ارزش پایین توافق شود. بعد از اینکه داده دریافت شد بیت SPIE یک می شود.
مثال۲:برنامه ای بنویسید که SPI برای کار در مد صفر (یعنی بیت های CPOL و CPHA صفر باشند) و حالت کاری فرمانبر آماده کند و سپس حرف A را ارسال کرده و داده دریافت شده را روی پورت A نمایش دهد.
راهنمایی: در حالت Slave پایه پورت مربوط به MISO باید خروجی و پایه پورت های MOSI و SCK باید ورودی باشند.
نکته مهم: برای اتصال بیش از دو دستگاه به یکدیگر از طریق SPI یکی از دستگاه ها باید در حالت Master و دیگران در حالت Slave باشند. در این صورت از طریق آدرسی که بر روی خط قرار می گیرد Master می تواند با یک Slave مشخص تبادل داده کند. یک روش دیگر برای آن که بتوان Slave مشخصی را انتخاب کرد صفر کردن پایه SS از Slave مورد نظر و یک کردن همین پایه در سایر Slave هاست. در این صورت Slave ی که پایه SS آن صفر شده به Master پاسخ می دهد. البته روش دوم پایه های بیشتری را از میکروکنترلر Master اشغال می کند بنابر این روش اول معمولتر است.
در پایان پروژه ای ساده برای آشنایی با نحوه اتصال SPI بین دو میکروکنترلر و تبادل داده میان آن ها آورده شده است. در این پروژه که کدنویسی آن به زبان C و در محیط کدویژن نوشته شده دو میکروکنترلر وضعیت پورت D یکدیگر را که تحت تاثیر حالت کلیدها قرار می گیرند از طریق رابط SPI باهم تبادل می کنند و بر روی پورت C خود به نمایش می گذارند.