پروتکل SPI یکی دیگر از رابط های سریال موجود در میکروکنترلر ها است. این پروتکل از دیگر پروتکل های سریال دارای سرعت بیشتری است. از این پروتکل باری راه اندازی سنسور ها و ماژول های مختلفی استفاده میشود. پیش از این درباره دیگر پروتکل های سریال از جمله USART و I2C در آموزش های جداگانه ای صحبت کردیم. در این پست قصد دارین درباره پروتکل SPI را مورد بررسی قرار داده و نحوه راه اندازی آن در میکروکنترلرهای STM32 با استفاده توابع HAL را آموزش دهیم. در ادامه با مرجع تخصصی بردهای امبدد به زبان فارسی، دیجی اسپارک همراه باشید.
معرفی پروتکل SPI
گذرگاه Serial Peripheral Interface یا به اختصار SPI یکی دیگر از رابط های سریال موجود بر روی میکروکنترلرها است. این پروتکل در دهه ۱۹۸۰ میلادی توسط شرکت موتورلا معرفی شد. SPI یک درگاه سریال ورودی و خروجی سنکرون (همزمان) با سرعت بالا است که اجازه میدهد داده ها به صورت سریال با طول قابل تنظیم (بین ۲ تا ۱۶ بیت) و همچنین سرعت انتقال قابل تنظیم به دستگاه وارد و یا از آن خارج شوند. در پروتکل SPI همانند پروتکل I2C، ارتباط بین دستگاه ها به صورت Master (ارباب) و Slave (برده) است. اما در SPI تنها یکی ار دستگاه ها میتوان به عنوان Master با Slave ها ارتباط برقرار کند. کاربر تا د این پروتکل در میکروکنترلر ها برای برقراری ارتباط با سنسور ها، ماژول هایی همانند SD Card، شیفت رجیسترها، درایور نمایشگرها، مبدل های آنالوگ به دبجبتال و … است.
سخت افزار پروتکل SPI
پروتکل SPI برای برقراری ارتباط بین Master و Slave از ۴ خط استفاده میکند. خطوط مورد نیاز برای برقراری ارتباط در پروتکل SPI عبارتند از؛
- SCLK: سیگنالی تحت عنوان کلاک باعث همزمانی انتقال داده بین Master و Slave میشود. به ازای هر کلاک یک بیت داده منتقل میشود. این سیگنال بر روی خط SCLK تولید میشود. پس سرعت انتقال داده در SPI به فرکانس سیگنال کلاک تولید شده بر روی این پایه بستگی دارد. سیگنال کلاک از سمت Master تولید میشود.
- MOSI: در پروتکل SPI برای نوشتن داده روی Slave و خواندن داده از آن دو خط مجزا تعریف شده است. کلمه MOSI مخفف Master Output Slave Input است. Master با استفاده از این خط داده مورد نظر را به Slave انتقال میدهد.
- MISO: کلمه MISO مخفف Master Input Slave Outrput است. این خط برای برای انتقال داده از سمت Slave یه سمت Master از خط MOSI استفاده میشود.
- SS/CS: در حالت عادی زمانی که تنها یک Slave موجود است این خط بایستی داراری سطح ولتاژ پایین باشد. اما زمانی که تعداد Slave ها از یک عدد بیشتر شود. این خط برای انتخاب Slave مورد نظر مورد استفاده قرار میگیرد. به تعداد Slave ها های موجود بایستی از هر کدام از Slave ها یک خط SS به Master متصل شود. برای انتخاب Slave مورد نظر بایستی سطح ولتاژ خط مربوط به Slave مورد نظر را پایین و سطح ولتاژ باقی خطوط SS بالا باشد.
انتقال داده در SPI
در پروتکل SPI برای انتقال داده از Master به Slave ابتدا سطح ولتاژ پایه SS مربوط به Slave مورد نظر صفر میشود. سپس ۸ بیت داده ارسال میشود. ۸ بیت ابتدای همیشه برای آدرس است. با ارزش ترین بیت این بایت برای Slave مشخص میکند که Master قصد انجام چه عملیاتی را دارد. اگر این بیت برابر صفر باشد Master قصد دریافت داده از Slave را دارد و در صورتی که این بیت برابر یک باشد Msater قصد ارسال داده به سمت Slave را دارد. سپس Slave هشت بیت داده را که توسط ۸ پالس ساعت همزمان شده است با استفاده از خط MOSI دریافت میکند.
در آخر Master برای اعلام اتمام ارسال داده سطح ولتاژ خط SS مربوط به Slave مورد نظر را برابر یک قرار میدهد. در صورتی که قصد ارسال چندبایت داده بصورت پشت سر هم را داشته باشید. پس از ارسال بایت آدرس مورد نظر، بایستی بایت های داده را بدون تغییری در سطح ولتاژ خط SS ارسال کند.
در ادامه برای خواندن داده از Slave نیز بخش زیادی از مراحل بالا تکرار میشود. ابتدا برای شروع برقراری ارتباط بین Master با یکی از Slave ها سطح ولتاژ خط SS مروبط به Slave مورد نظر برابر صفر خواهد شد. سپس Master بایت آدرس را ارسال کرده و بیت آخر که برای مشخص کردن خواندن و نشوتن است برابر صفر قرار میگیرد تا Slvae شروع به ارسال داده کند. پس از آن با هر ۸ پالس ساعت Slave هشت بیت داده با استفاده از خط MISO به سمت Master ارسال میکند. در آخر Master برای اعلام اتمام ارسال داده سطح ولتاژ خط SS مربوط به Slave مورد نظر را برابر یک قرار میدهد. همانند نحوه ارسال داده به Slave ها برای خواندن چند بایت داده بایستی پس از ارسال بایت آدرس مورد نظر بایستی بایت های داده را بدون تغییری در سطح ولتاژ خط SS دریافت کند.
پیکر بندی SPI در نرم افزار STM32CubeMX
برای پیکربندی SPI در نرم افزار STM32CubeMX پس از ساخت پروژه جدید در این نرم افزار از نوار ابزار سمت چپ یکی از SPI های میکروکنترلر را انتخاب کنید. زمانی که وارد تنظیمات SPI میشوید. گزینه Mode بر روی Disable قرار دارد. این بخش دارای حالت های مختلفی است. این حالت ها عبارتند از؛
- Full-Duplex Master : در این حالت میکروکنترلر به عنوان Master تنظیم میشود. همچنین ارسال و دریافت در این حالت بصورت همزمان انجام میشود.
- Full-Duplex Slave : در این حالت میکروکنترلر به عنوان Slave تنظیم میشود. در این حالت نیز ارسال و دریافت بصورت هم زمان خواهد بود.
- Half-Duplex Master : در این حالت میکروکنترلر به عنوان Master تنظیم میشود. اما تفاوت این حالت با حالت اول این است که ارسال و دریافت بصورت همزمان صورت نمیگیرد.
- Half-Duplex Slave : در این حالت میکروکنترلر به عنوان Slave تنظیم میشود. ارسال و دریافت در این حال نیز بصورت غیر هم زمان است.
- Receive Only Master : در این حالت میکروکنترلر به عنوان Master فقط عمل دریافت را انجام میدهد. و داده ای ارسال نمیکند.
- Receive Only Slave : در این حالت میکروکنترلر به عنوان Slave فقط عمل دریافت را انجام میدهد.
- Transmit Only Master : این حالت میکروکنترلر به عنوان Master فقط عمل ارسال داده را انجام میدهد.
در این آموزش قصد داریم تا میکروکنترلر را به عنوان Master تنظیم کنیم. همچنین ارسال و دریافت باید به صورت همزمان انجام شود. بنابراین قسمت Mode را روی Full-Duplex Master تظیم میکنیم. سپس مشاهده میکنید که پایه های SCK ،MISO ،MOSI روی میکرو کنترلر ظاهر میشود. نرم افزار STM3CubeMX به صورت پیشفرض پایه های SS را تعریف نمیکند. در صورتی که تعداد Slave های شما بیشتر از یک عدد است بایستی برای هر Slave روی میکروکنترلر خروجی در نظر بگیرید.
در ادامه در بخش Parameter Setting میتوانید پارامتر هایی از جمله سایز داده، باودریت، قطب و فاز کلاک را تنظیم کنید. در صورتی که قصد راه اندازی ماژول و یا سنسور خاصی را دارید این بخش را باید با توجه به دیتاشیت آن قطعه تنظیم کنید.
سپس از صفحه Clock Configuration فرکانس کاری میکروکنترلر را به دلخواه تنظیم کنید. سپس وارد صفحه ی Project Manager شوید. پس از انتخاب نام و IDE برای پروژه بر روی CODE GENERATE کلیک کرده و وارد نرم افزار KEIL شوید.
بررسی توابع HAL مبربوط به SPI
همانطور گفته شد در این آموزش میکروکنترلر STM32 به عنوان Master تعریف شده است. بنابراین توابع که در ادامه معرفی میشود. مربوط به بخش Master میباشد. که زمانی که از نرم افزار STM32CubeMX برای راه اندازی SPI استفاده کنید. این نرم افزار توابع HAL مربوط به بخش SPI را در اختیار شما میگذارد. در این آموزش توابع پر کاربرد این SPI را معرفی میکنیم. توابع پر کاربرد SPI عبارتند از؛
HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size,uint32_t Timeout); HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size);
-
HAL_SPI_Receive
با استفاده از این تابع داده ارسالی از سمت Slave دریافت و در متغیر یا رشته ای که در ورودی این تابع قرار داده شده است، ذخیره میکند. این تابع دارای ۴ ورودی است. ورودی اول استراکتی است که نرم افزار STM32CubeMX پس از فعال سازی SPI مورد نظر میسازد. در واقع با استفاده از این ورودی SPI مورد نظر به تابع معرفی میشود. ورودی دوم برای ذخیره سازی داده دریافتی است. با یستی متغیری از نوع uint8_t ساخته و در این ورودی قرار دهید. ورودی سوم برای دریافت سایز داده دریافتی از SPI است. پس از دریافت داده سایز داده دریافتی در این بخش قرار میگیرد. ورودی آخر Timeout است. برای مقدار زمانی است که CPU متنظر دریفات می شود. اگر قبل از اتمام این زمان عملیات دریافت انجام شود. بلا فاصله ادامه برنامه اجرا خواهد شد. برای درک بهتر این مطلب به مثال زیر توجه کنید.
HAL_SPI_Receive(&hspi1, (uint8_t *)spi_buf, 3, 100);
-
HAL_SPI_Receive_IT
اکثر تراشه های STM32 همچنین از SPI در مد اینتراپت نیز پشتیابنی میکنند. این قابلیت به شما اجازه میدهد تا کد بدون وقفه داشته باشید. این تابع کاملا مشابه تابع قبل است. با این تفاوت که این تابع در مد اینتراپت است. و زمانی که داده دریافت شود. این تابع به صورت خودکار اجرا خواهد شد. تمامی ورودی های این تابع مشابه تابع قبل است. اما این تابع ورودی آخر یعنی Timeout را ندارد. زمانی میتوانید از این دستور استفاده کنید که در نرم افزار STM32CubeMX در بخش NVIC گزینه SPI1 global interrupt را فعال کرده باشید.
HAL_SPI_Receive_IT(&hspi1, (uint8_t *)spi_buf, 3);
-
HAL_SPI_Transmit
این تابع برای ارسال داده استفاده میشود. این تابع نیز همانند تابع اول دارای ۴ ورودی است. ورودی استراکت مربوط به انتخاب SPI مورد نظر است. در ورودی دوم داده مورد نظر برای ارسال قرار میگیرد. ورودی سوم بایستی سایز داده ای که در ورودی دوم قرار داده اید را بنویسید. ورودی آخر Timeout است.
HAL_SPI_Transmit(&hspi1, (uint8_t *)&addr, 1, 100);
-
HAL_SPI_Transmit_IT
این تابع مشابه تابع قبل عمل میکند. با این تفاوت که این تابع در مد اینتراپت قرار دارد. مزیت استفاده از این تابع نسبت به تابع قبل بدون وقفه بودن کد است. همانطور که مشهاده میکنید ورودی های این تابع نیز مشابه تابع قبل است. با این تفاوت که ورودی Timeout در این تابع وجود ندارد.
HAL_SPI_Transmit_IT(&hspi1, (uint8_t *)spi_buf, 3);
-
HAL_SPI_TransmitReceive
توابع بالا هر کدام تنها قبلیت ارسال و یا دریافت را داشتند. این تابع قبلیت ارسال و دریافت داده را بصورت همزمان را دارد. ورودی های این تابع عبارتند از؛ ورودی اول استراکتی که مربوط به انتخاب SPI مورد نظر است. در ورودی دوم بایستی داده ای قصد ارسال آن را دارید را قرار دهید. ورودی سوم پوینتر مربوط به داده دریافتی است. در ورودی چهارم بایستی سایز داده های ارسالی و دریافتی را مشخص کنید. ورودی آخر همانند توابع قبلی مدت زمان Timeout است.
-
HAL_SPI_TransmitReceive_IT
این تابع نیز عملیات ارسال و دریافت همزمان را همانند تابع قبل انجام میدهد اما این کار را در مد اینتراپت انجام میدهد و ورودی Timeout را ندارد.
-
توابع بیشتر …
نرم افزار STM32CubeMX برای کنترل SPI توابع دیگری را نیز در اختیار شما میگذارد. برای مشاهده ی این توابع بایستی در نرم افزار KEIL وارد بخش Function شده و سپس بر روی فایل stm32f1xx_hal.h کلیک کنید. سپس میتوانید تمامی توابع HAL مربوط به SPI را مشاهده کنید.
جمع بندی
در آموزش های پیشین با دیگر پروتکل های سریال مانند USART و I2C آشنا شده ایم. در این آموزش درباره پروتکل SPI صحبت شد. در ابتدای آموزش این پروتکل معرفی شد. در ادامه با سخت افزار SPI اشنا شدیم. سپس به نحوه انتقال داده در این پروتکل پرداختیم. پس از آن نحوه پیکربندی SPI در نرم افزار STM32CubeMX برای قرار دادن میکروکنترلر در حالت Master توضیح داده شد. در آخر با توابع پر کاربرد SPI اشنا شدیم.
لوازم مورد نیاز
چنانچه در مراحل راه اندازی و انجام این پروژه با مشکل مواجه شدید، بدون هیچ نگرانی در انتهای همین پست، به صورت ثبت نظر سوالتان را مطرح کنید. من در سریعترین زمان ممکن پاسخ رفع مشکل شما را خواهم داد. همچنین اگر ایرادی در کدها و یا مراحل اجرایی وجود دارند میتوانید از همین طریق اطلاع رسانی کنید.
در پایان نظرات و پیشنهادات خود را با ما درمیان بگذارید و با اشتراک گذاری این آموزش در شبکه های اجتماعی از وبسایت دیجی اسپارک حمایت کنید.