پروتکل SPI

پروژه: پیاده‌سازی پروتکل SPI

پروتکل SPI یکی از پرکاربردترین استانداردهای ارتباطی برای فواصل کوتاه و سرعت نسبتا زیاد است. در بخش دیجیتال بسیاری از پروژه‌های صنعتی یا نظامی، حداقل یک ارتباط SPI وجود دارد. در اولین قسمت بخش جدید “پروژه هفته“، به معرفی پروتکل SPI و ملزومات پیاده‌سازی آن در FPGA می‌پردازم.

پروتکل SPI چیست؟

کلمه SPI مخفف عبارت Serial Peripheral Interface است که اشاره دارد به یک پروتکل ارتباطی سریال. از این پروتکل در ارتباطات با فاصله کوتاه استفاده می‌شود و نوع ارتباط آن سنکرون است. در کامل‌ترین حالت، چهار سیم یا مسیر ارتباطی برای پیاده‌سازی این پروتکل به کار می‌رود.

به کمک این چهار سیم، امکان ایجاد یک ارتباط Full duplex به صورت Master/Slave فراهم می‌شود. اگر بیش از دو وسیله به کمک این پروتکل به یکدیگر متصل شوند، همواره یکی از آنها master و بقیه slave خواهند بود. شکل زیر، دیاگرامی از نحوه ارتباط بین دو وسیله را در پروتکل SPI نشان می‌دهد.

 

بلوک‌دیاگرام SPI

 

از آنجاییکه این یک ارتباط سریال سنکرون است، یکی از چهار خط ارتباطی پروتکل SPI سیگنال کلاک است. وسیله‌ای که سیگنال کلاک را ارسال می‌کند master نامیده می‌شود و وسیله‌ای که آن را دریافت می‌کند slave نام دارد. دومین خط ارتباطی، سیگنال انتخاب slave یا slave select) SS) است. این سیگنال در صورتیکه که فقط یک slave در سیستم وجود داشته باشد، می‌تواند همیشه فعال باشد و در این حالت نقش جدی در برقراری ارتباط ندارد.

دو سیگنال دیگر این ارتباط، برای انتقال داده‌ها از master به slave و بالعکس استفاده می‌شوند. سیگنال MOSI که مخفف Master Output Slave Input است برای انتقال داده‌ها از master به slave و سیگنال MISO که مخفف Master Input Slave Output است برای انتقال داده‌ها از slave به master استفاده می‌شود.

همانطور که در ابتدا هم اشاره کردم، این یک ارتباط سریال سنکرون است و بنابراین، انتقال هر بیت از داده‌ها بین master و slave همزمان با لبه کلاک رخ می‌دهد. کلاک این ارتباط، در سمت master تولید شده و به slaveها ارسال می‌شود. چه در slave و چه در master، دریافت و ارسال بیت‌های داده‌ها باید همزمان با این کلاک انجام شود.

در مورد سیگنال‌های ارتباطی پروتکل SPI به دو نکته توجه کنید. نکته اول اینکه در بعضی از سیستم‌ها، برای برقراری ارتباط SPI از سه سیم به جای چهار سیم استفاده می‌شود. در این حالت، به جای دو سیم برای انتقال داده‌ها بین master و slave، از یک سیم استفاده می‌شود. در نتیجه، پروتکل از حالت full duplex به half duplex تغییر ماهیت می‌دهد.

نکته دوم در مورد سیگنال‌های پروتکل SPI مربوط به نامگذاری آنها است. در مراجع مختلف، ممکن است برای سیگنال SCLK از CLK یا SCK استفاده شود. به جای سیگنال MOSI ممکن است از SDI یا DI استفاده شود و به جای سیگنال MISO از SDO یا DO استفاده شود.

اما سرعت یک ارتباط SPI را چه عاملی تعیین می‌کند؟ در ارتباطات آسنکرون، مثل پروتکل RS232، سرعت ارتباط باید از قبل بین دو وسیله که با هم در ارتباط هستند مشخص باشد. در غیر اینصورت، ارتباط با مشکل مواجه خواهد شد. اما در مورد ارتباط SPI، تعیین کننده سرعت ارتباط، همان سیگنال کلاک است که از master ارسال می‌شود. بنابراین نیازی به توافق قبلی بین master و slave نیست. البته هر مدار دیجیتالی، دارای یک حداکثر فرکانس کلاک قابل اعمال است و بنابراین، فرکانس کلاک SPI هم نمی‌تواند از آن مقدار بیشتر شود.

برای آشنایی با پروتکل RS232 و نحوه پیاده‌سازی آن، این مقاله را بخوانید…

ارسال و دریافت داده‌ها در پروتکل SPI

از آنجاییکه SPI یک ارتباط سنکرون است، هر بیت داده در master و slave همزمان با کلاک ارسال یا دریافت می‌شود. به عبارت دیگر، همزمان با هر کلاک، یک بیت از داده‌ها از master به slave و یک بیت از slave به master می‌تواند منتقل شود. طول این داده‌ها بستگی به قراردادی دارد که در یک وسیله خاص وجود دارد و ممکن است ۸ بیت، ۱۰ بیت، ۱۶ بیت، ۳۲ بیت یا هر مقدار دیگری باشد.

مثلا در یک ارتباط SPI برای انتقال داده‌های هشت بیتی، گیرنده SPI طوری طراحی شده است که بعد از فعال شدن ارتباط به وسیله سیگنال select slave، بعد از هر هشت کلاک، یک دیتای کامل دریافت شده است و در کلاک بعدی باید اولین بیت دیتای جدید را دریافت کند.

توجه کنید که در پروتکل SPI، وسیله‌ای که در حال دریافت داده‌ها است، باید از قبل بداند که داده دریافتی چند بیتی است. مثلا اگر master داده‌ای را به slave ارسال کند و در پاسخ به آن داده، انتظار داشته باشد که slave هم داده‌ای را به master ارسال کند، master باید کلاک را به تعداد لازم ادامه دهد تا slave بتواند به کمک آن، داده خود را به master ارسال کند.

ارسال هر کدام از این داده‌ها می‌تواند از بیت سنگین (MSB) یا از بیت سبک (LSB) آغاز شود. این موضوع بستگی به قرادادی دارد که در سیستم مورد استفاده شما وجود دارد. در بسیاری از سیستم‌ها، اینکه ارسال داده‌ها از بیت سنگین شروع شود یا از بیت سبک، قابل تنظیم است.

مثلا ممکن است شما از قبل، ماجول یک ارتباط SPI را در FPGA به کمک زبان VHDL آماده کرده باشید و این ماجول را طوری طراحی کرده باشید که داده‌ها را از بیت سبک آنها ارسال و دریافت می‌کند. برای ارتباط ماجولی که طراحی کرده‌اید با یک ماجول خارجی، می‌توانید برای اینکه مجبور نباشید تغییری در کدی که نوشتید بدهید، ماجول خارجی را طوری تنظیم کنید که ارسال و دریافت داده‌ها را از بیت سبک انجام دهد تا با ماجول شما سازگار شود.

شکل زیر، یک نمونه از زمان‌بندی سیگنال‌ها را در ارتباط SPI نشان می‌دهد. در این شکل، سیگنال SS ابتدا صفر شده است که این باعث انتخاب و فعال شدن ماجول slave می‌شود. در ابتدا، یک دیتای هشت بیتی از سمت master به slave ارسال شده است. سپس دو بایت پشت سر هم از سمت slave به master ارسال شده است. توجه داشته باشید که حتی وقتی ارسال دیتا از slave به master است، کلاک ماجول‌ها توسط master تولید می‌شود. بنابراین، بلوک master باید از قبل، از طول دیتای دریافتی از slave مطلع باشد تا بتواند به تعداد لازم کلاک ارسال کند.

 

نمودار زمان‌بندی SPI

 

 کاربردهای پروتکل SPI

با توجه به سادگی و سرعت مناسب پروتکل SPI، در بسیاری از ماجول‌ها و قطعات جانبی از این استاندارد ارتباطی استفاده می‌شود. برای مثال، قطعات جانبی مثل انواع سنسورها، مبدل‌های آنالوگ به دیجیتال، ماجول USB، ماجول Ethernet، حافظه‌های Flash و EEPROM برای ارتباط با دیگر قطعات از جمله FPGAها از پروتکل SPI استفاده می‌کنند. اجازه دهید برای مثال، به چند نمونه از مواردی که پروتکل SPI را در پروژه‌های مختلف به کار برده‌ام اشاره کنم.

یکی از موارد کاربرد پروتکل SPI که تقریبا روی هر بردی که شامل FPGA است وجود دارد، ارتباط FPGA با حافظه Flash پیکره‌بندی است. همانطور که می‌دانید، وقتی منبع تغذیه یک FPGA را که پروگرام کرده‌اید قطع می‌کنید، محتوای FPGA پاک شده و مجبور هستید بعد از روشن کردن برد، مجددا آن را پروگرام کنید. برای رفع این مشکل، فایلی که باید در FPGA پروگرام شود را درون یک حافظه Flash که به FPGA متصل است پروگرام می‌کنند. یک گروه از این حافظه‌های Flash از طریق پروتکل SPI با FPGA در ارتباط هستند. هر بار که برد به منبع تغذیه وصل می‌شود، به طور خودکار اطلاعات مربوط به پروگرام از حافظه Flash به FPGA منتقل می‌شود.

یکی دیگر از مواردی که به کمک ارتباط SPI پیاده‌سازی کرده‌ام، ماجول توزیع کننده کلاک یا clock distributer است. از این ماجول برای تولید چند کلاک با کیفیت و همفاز می‌توان استفاده کرد. معمولا در بردهایی که شامل تعدادی مبدل آنالوگ به دیجیتال هستند، برای نمونه‌برداری دقیق و همزمان از این ماجول استفاده می‌شود. این ماجول، یک کلاک با فرکانس مشخص را به عنوان مرجع دریافت می‌کند و این قابلیت را دارد که در خروجی‌های خود، چندین کلاک با فرکانس‌ها و فاز دلخواه تولید کند.

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

آخرین موردی که می‌خواهم به عنوان نمونه‌ای از کاربردهای پروتکل SPI نام ببرم، ارتباط با ماجول DDS است. ماجول DDS که مخفف Direct digital synthesizer است، ماجول بسیار پرکاربردی خصوصا در طراحی مدارات RF است. از این ماجول برای تولید انواع سیگنال‌ها با فرکانس و دامنه دلخواه و همچنین تولید انواع مدلاسیون‌ها استفاده می‌شود. نکته جالب در مورد این ماجول این است که تمام قابلیت‎های آن، فقط از طریق پروگرام کردن رجیسترهای مخصوصی که در این ماجول وجود دارند قابل دسترسی است. بنابراین، این ماجول یک سازنده سیگنال‌های آنالوگ است که به صورت دیجیتالی کنترل می‌شود. در این ماجول هم، پروتکل ارتباطی برای پروگرام کردن رجیسترها، پروتکل SPI است.

 

ایده‌هایی برای پیاده‌سازی

شروع طراحی یک ماجول، مهمترین و شاید سخت‌ترین بخش طراحی است. پیشنهاد می‌کنم برای شروع، به جای اینکه فورا نرم‌افزار ISE را اجرا کنید و شروع به کدنویسی کنید، ابتدا روی یک کاغذ، طرحی از آنچه در ذهن دارید را ترسیم کنید.

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

برای آشنایی با زبان VHDL این برنامه ویدئویی را ببینید…

اجازه دهید مرحله مشخص کردن پورت‌ها را با هم پیش ببریم. از این به بعد، به ماجولی که در حال طراحی آن هستیم، ماجول SPI می‌گوییم. شخصی که می‌خواهد ماجول SPI را به کار ببرد، نیاز به چه قابلیت‌هایی دارد؟

قاعدتا او باید بتواند یک دیتای چندبیتی را برای ارسال از طریق این پروتکل به ماجول منتقل کند. بنابراین حتما یک پورت ورودی برای این کار لازم است. من اسم این پورت را Send_Data می‌گذارم. این که این پورت چند بیتی باشد، بستگی به این دارد که ماجولی که به FPGA متصل کرده‌اید و از طریق پروتکل SPI با آن ارتباط برقرار می‌کنید، از چه طول دیتایی استفاده می‌کند. برای اطلاع از این موضوع باید به برگه مشخصات آن ماجول مراجعه کنید. مثلا ماجول توزیع کننده کلاکی که اخیرا از آن استفاده کردم، داده‌ها را در قالب‌های هشت بیتی دریافت و ارسال می‌کند.

البته می‌توانید پورت Send_Data  را به صورت generic تعریف کنید. یعنی طوری کدتان را بنویسید که قابلیت تغییر عرض بیت داده به راحتی در آن امکان‌پذیر باشد. قابلیت generic یکی از امکاناتی است که زبان VHDL در اختیار شما قرار می‌دهد و به کمک آن می‌توانید برای بعضی از پارامترها در کدتان یک متغیر تعریف کنید تا بعدا بتوانید فقط با تغییر آن متغیر، کدتان را به راحتی برای کاربردهای مختلف تغییر دهید.

پس تا این مرحله از طراحی، پورتی را برای ورود دیتای ماجول SPI طراحی کردیم. اما وقتی دیتایی که می‌خواهیم ارسال شود را در مقابل پورت دیتا قرار دادیم، باید به نحوی به ماجول SPI اطلاع دهیم که یک دیتای سالم در ورودی وجود دارد که باید ارسال شود. برای این کار نیاز به یک پورت تک‌بیتی داریم. می‌توانیم نام این پورت را Send بگذاریم. باید ماجول SPI را به گونه‌ای طراحی می‌کنیم که هر زمان که پورت Send فعال شد، دیتایی که در پورت Send_Data قرار دارد از طریق پروتکل SPI ارسال شود. بد نیست که این پورت را حساس به لبه بالارونده کنید.

اما یک مشکل ممکن است برای فردی که از ماجول SPI استفاده می‌کند به وجود آید. اگر در حالی که ماجول در حال ارسال یک دیتا است، مجددا درخواست جدیدی از طریق پورت Send به ماجول اعمال شود، چه اتفاقی باید بیفتد؟ یک انتخاب خوب این است که چنین درخواستی نادیده گرفته شود. اما اگر فرمان Send نادیده گرفته شد، چگونه به صادر کننده این فرمان اطلاع دهیم که فرمانش نادیده گرفته شده است؟

یک راه مناسب برای این کار، ایجاد یک پورت خروجی تک‌بیتی است که در زمان ارسال دیتا مقدارش یک باشد. اسم این پورت را Busy می‌گذارم و ماجول را طوری طراحی می‌کنیم که از لحظه دریافت فرمان Send تا ارسال آخرین بیت از طریق پروتکل SPI، این خروجی برابر با یک باشد. در این حالت، برای فردی که از ماجول SPI استفاده می‌کند معلوم است که در چه زمانی اجازه دارد فرمان Send را ارسال کند و اگر در زمان‌های غیر مجاز این کار را انجام دهد، فرمانش نادیده گرفته می‌شود.

برای دریافت دیتا توسط ماجول SPI هم همین داستان برقرار است. بنابراین نیاز به یک پورت خروجی دیتا وجود دارد که دیتای دریافتی از طریق پروتکل SPI را به صورت یک دیتای چندبیتی به خروجی ماجول SPI بفرستد. اسم این پورت را Receive_Data می‌گذارم. عرض بیت این پورت هم بستگی به نوع پکتی دارد که از سمت ماجول جانبی ارسال می‌شود و برای اطلاع از آن باید به برگه مشخصات آن مراجعه کنید.

اما فردی که از ماجول SPI استفاده می‌کند، چگونه مطلع شود که یک دیتای جدید دریافت شده است و می‌تواند آن را از پورت Receive_Data بخواند؟ برای این کار هم نیاز به یک پورت خروجی تک‌بیتی است که بهتر است وقتی دیتای جدید در پورت Receive_Data قرار می‌گیرد، به مدت یک کلاک یک شود تا حضور دیتا را به این طریق به فردی که از ماجول SPI استفاده می‌کند اطلاع دهد. اسم این پورت را هم Data_Ready می‌گذارم.

قاعدتا ماجول SPI باید دارای چهار پورت هم برای برقرار ارتباط SPI باشد. این چهار پورت به چهار پورت SPI ماجول جانبی که به FPGA وصل کرده‌ایم متصل خواهد شد. البته برای طراحی این مدار حتما به یک کلاک هم نیاز داریم که به عنوان آخرین پورت ماجول SPI معرفی می‌کنیم.

با این توضیحات، ماجول SPI به شکل زیر خواهد بود.

 

ماجول SPI

 

قدم بعدی برای طراحی

برای ادامه طراحی نیاز به اطلاعات جزئی‌تری در مورد ارتباط SPI دارید. این اطلاعات شامل طول داده‌هایی که باید منتقل شوند، حداکثر سرعت کلاک، و زمان‌بندی سیگنال‌ها است. برای اطلاع از این جزئیات، پیشنهاد می‌کنم بخش ارتباط SPI را در برگه مشخصات یکی از قطعات جانبی که از این پروتکل استفاده می‌کنند مطالعه کنید.

در اینجا لینک برگه مشخصات یک توزیع کننده کلاک و یک ماجول DDS را که از پروتکل SPI استفاده می‌کنند قرار می‌دهم. می‌توانید یکی از آنها را انتخاب کنید و ماجول SPI را با توجه به مشخصات ذکر شده در برگه مشخصات طراحی کنید.

صفحه مشخصات توریع کننده کلاک

دانلود مستقیم فایل مشخصات توزیع کننده کلاک

صفحه مشخصات ماجول DDS

دانلود مستقیم فایل مشخصات ماجول DDS

 

چطور از صحت پیاده‌سازی خودمان مطمئن شویم؟

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

برای آشنایی با نحوه شبیه‌سازی در نرم‌افزار ISE این برنامه ویدئویی را ببینید…

 

برای این منظور، یک فایل تست‌بنچ بسازید و ورودی Send_Data را در آن مشخص کنید. سپس به مدت یک کلاک، سیگنال Send را یک کنید تا فرمان ارسال صادر شود. اگر در این حالت، کدتان را شبیه سازی کنید، باید بتوانید سیگنال‌های Busy و چهارسیگنال مربوط به ارتباط SPI را در شبیه‌ساز ببنید. سپس این چهار سیگنال و زمان‌بندی آنها را با آنچه در برگه مشخصات مطالعه کرده‌اید مقایسه کنید و در صورت وجود تفاوت بین آنها، مجددا کدتان را بررسی کنید.

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

خوشحال خواهم شد اگر من را هم از نتیجه این پیاده‌سازی و تجربیاتی که از طریق آن کسب می‌کنید مطلع کنید. بنابراین، لطفا همین جا و در پایین همین مقاله، این موضوعات را با من و دیگر علاقمندان به اشتراک بگذارید.

کانال آموزش FPGA از صفر

12 پاسخ
  1. sarbaz13
    sarbaz13 گفته:

    سلام
    ممنون از آموزش های که راه انداختین که خیلی خوبه و خدا خیرتون بده
    ولی من یک پیشنهاد دارم برای آموزشهاتون که این هست
    موارد مورد نیاز جهت طراحی PCB برای برد
    مثلا برای mmc که از رابطه spi استفاده میکنه طبق دیتا شیت
    چون سنکرون هست طول ترک کلاک باید زیادتر باشه که اخر برسدو………..

    پاسخ دادن
  2. Reza
    Reza گفته:

    سلام استاد
    ممنون میشم اون فایل هایی که در باره نحوه پیاده سازی ddsو دومی قرار دادین رو به صورت pdfقرار بدین من هر چی تلاش نمی تونم اون سایت رو باز کنم ؟؟؟
    ممنون میشم به صورت pdfقرار بدید

    پاسخ دادن
  3. محمد
    محمد گفته:

    با سلام وقت بخیر
    ببخشید در این ماجول که تعریف کردید چهارتا سیگنال sclk,mosi,miso,ss از fpga به ماجول هایی که ارتباطشون با spi هست وصل میوشد ؟
    و سیگنال های بعدی که بصورت ورودی و خروجی دیگر تعریف شده اند اینها هم به پایه های fpga وصل میوشدند یا اینکه در داخل fpga بکار میروند؟

    پاسخ دادن
    • احمد ثقفی
      احمد ثقفی گفته:

      سلام،

      بله، چهار سیگنالی که مربوط به پروتکل SPI هستند از طریق پایه‌های FPGA به ماجولی که قرار است با آن ارتباط SPI برقرار شود متصل می‌شود و سیگنال‌های دیگر، داخل FPGA استفاده می‌شوند.

      پاسخ دادن
      • محمد
        محمد گفته:

        مهندس ببخشید اگر ماجول مورد نظر DDS باشد که با پروتکل spi ارتباط برقرار میکند در این صورت هم باید برای پروتکل spi نوشت هم برای ماجول DDS ؟

        پاسخ دادن
        • احمد ثقفی
          احمد ثقفی گفته:

          شما باید به کمک توضحاتی که در این مقاله دادم، پروتکل SPI را در FPGA به صورت master پیاده‌سازی کنید و سپس به کمک این پروتکل، رجیسترهای درون ماجول SPI را بر مبنای نیازتون پروگرام کنید.

          پاسخ دادن
  4. akrajaei
    akrajaei گفته:

    شما که همه رو گفتین، خب این i2c رو هم میگفتین.

    ۱ ماه و نیم ه هنوز دارم رو نوشتن ش این پروتکل کار می کنم.
    یه مرجع فارسی خوب هم پیدا نمیشه. البته انگلیسی ش هم گم بود.

    پاسخ دادن

تعقیب

  1. […] که در مقاله مربوط به پروژه پیاده‌سازی پروتکل SPI هم اشاره کردم، بهتر است قبل از شروع به پیاده‌سازی در […]

دیدگاه خود را ثبت کنید

خوشحال خواهم شد نظر شما را در مورد این پست بدانم.
ایمیل شما برای دیگران قابل مشاهده نخواهد بود.

پاسخ دهید

You have to agree to the comment policy.