شاید تا به حال USB موجود بر روی بر روی برخی از برد های STM32 مثل برد BluePill توجه شما را جلب کرده باشد. حتی ممکن است در نگاه اول فکر کنید که شاید میتوان با استفاده از این پورت USB میکروکنترلر را پروگرام کنید. اما این پورت بصورت پیشفرض قابلیت پروگرام کردن میکروکنترلر را ندارد. اما میتوانید از این پورت برای ارسال و دریافت داده از کامپیوتر و یا هر دستگاه دیگری که قابلیت کنترل از طریق USB را دارد استفاده کنید. در این پست قصد داریم تا نحوه را اندازی پورت USB میکروکنترلر های STM32 در مد CDC را آموزش دهیم. در ادامه با مرجع تخصصی بردهای امبدد به زبان فارسی، دیجی اسپارک همراه باشید.
انواع پورت USB
USB مخفف کلمه Universal Serial Bus و به معنای درگاه همه گذر می باشد. USB یک استاندارد صنعتی است که در سال ۱۹۹۰ به ثبت رسیده است. از این درگاه برای ارسال و دریافت داده بین سیستم های الکترونیکی مانند کامپیوتر ، موبایل و … استفاده می شود. همچنین درگاه USB به عنوان منبع تغذیه نیز در سیستم های الکترونیکی شناخته می شود. در USB ورژن ۲ حداکثر جریان قابل انتقال تقریبا برابر ۵۰۰ میلی آمپر بود. در حالی که در USB ورژن ۳٫۱ حداکثر جریان قابل تحمل به ۵۰۰۰ میلی آمپر افزایش یافت. در سری C این درگاه ها قابلیت انتقال ولتاژ به ۲۰ ولت و انتقال داده همزمان با شارژ وجود دارد. درگاه USB ممکن است شکل های مختلفی داشته باشد که در تصویر زیر میتوانید انواع شکل های درگاه USB را مشاهده کنید.
پورت USB برای انتقال اطلاعات از روش Differential یا همان دیفرانسیل استفاده میکنید. تا نسخه USB2 از یک جفت پایه D+ و D- که قرینه یکدیگر هستند استفاده می شود. USB یک پروتکل ارتباطی غیر همزمان (Half Duplex) است. عموما USB دارای ۴ پایه است. طبق جدول زیر، پایه های ۱ و ۴ خط ولتاژ مدار، که به ترتیب مثبت ۵ ولت و زمین هستند. پایه های ۲ و ۳ برای انتقال اطلاعات از طریق پورت USB است. که در جدول با نام های D+ و D- مشخص شده است.
Host یا Devise ؟
همانطور که می دانید ارتباط یو اس بی بین دو دستگاه می باشد که یکی از این دو دستگاه، هاست (Host) و دیگری به عنوان دیوایس (Device) معرفی می شوند.
هاست (USB Host) : به نوعی از یو اس بی گفته می شود که در آن Device دیوایس ها کنترل می شوند. در واقع هاست وظیفه مدیریت روی ارسال و دریافت اطلاعات را بر عهده دارد به عنوان مثال کامپیوتر دارای درگاه های یو اس بی هاست می باشد. یو اس بی هاست دارای کلاس های زیر است؛
- Human Interface Device (HID)
- Mass Storage Device (MSC)
دیوایس (USB Device) : به نوعی از یو اس بی گفته می شود که به یک دستگاه داری یو اس بی هاست متصل می شود و اطلاعات مورد نیاز را به هاست منتقل کرده یا از آن دریافت می کند. به عنوان مثال دستگاه پرینتر دارای یک درگاه یو اس بی دیوایس می باشد که به درگاه کامپیوتر که از نوع هاست می باشد متصل می شود و یا حافظه جانبی به عنوان یک یو اس بی دیوایس می باشد که می تواند به دستگاه های دارای پورت یو اس بی هاست مانند کامپیوتر، ضبط و یا تلویزیون متصل شود. یو اس بی دیوایس نیز دارای کلاس های زیر است؛
- Audio Device (ADC) – to exchange streaming audio data
- Communication Device (CDC) – to realize a virtual COM port
- Human Interface Device (HID) – to exchange control and configuration data
- Mass Storage Device (MSC) – to store and access data
هر یک از کلاس های نامبرده شده بالا دارای توضیحات مفصلی هستند که توضیح آنها در این مقاله نمیگنجد. در این آموزش از USB نوع Device در کلاس CDC استفاده شده است.
کلاس CDC
CDC یا Communications Device Class همانطور که از نامش مشخص است، یکی از کلاس های USB Device است. CDC برای دستگاه های شبکه رایانه ای مشابه کارت شبکه استفاده می شود ، واسطی برای انتقال فریم های اترنت یا خودپرداز به برخی از رسانه های فیزیکی فراهم می کند. از این کلاس می توان برای تجهیزات صنعتی مانند ماشین آلات CNC استفاده کرد تا امکان کنترل از راه دور کنترل کننده های سری RS-232 و رباتیک وجود داشته باشد ، زیرا آنها می توانند سازگاری نرم افزار را حفظ کنند. دستگاه به یک خط ارتباطی RS-232 متصل می شود و سیستم عامل در سمت USB باعث می شود دستگاه USB به عنوان یک پورت RS-232 سنتی ظاهر شود.
پیکربندی میکروکنترلر STM32
پس از ساخت پروژه جدید در نرم افزار STM32CubeMX مطابق بخش اول آموزش میکروکنترلر های STM32 بخش های RCC و SYS را تنظیم کنید. برای استفاده از نوار سمت چپ گزینه USB را انتخاب کنید. سپس تیک مربوط به گزینه Device (FS) را بزنید. پس از آن از همان نوار سمت چپ وارد بخش USB_DEVICE شده و گزینه Class For FS IP را بر روی Communications Device Class (Virtual Port Com) تنظیم کنید.مقادیر پیشفرض تنظیم شده در بخش Parameter Setting را تغییر نمیدهیم. اگر به میکروکنترلر توجه کنید، مشاهده خواهید کرد که پایه های PA11 و PA12 با نام های USB_DM و USB_DP مشخص شده است.
سپس از صفحه Clock Configuration فرکانس کاری میکروکنترلر را بر روی ۷۲ مگاهرتز تنظیم کنید. یا در صورتی که نیاز به فرکانس کمتری دارید، بایستی توجه داشته باشید که فرکانس بخش USB بایستی بر روی ۴۸ مگاهرتز تنظیم شود. سپس وارد صفحه ی Project Manager شوید. پس از انتخاب نام و IDE برای پروژه مقدار گزینه های Minimum Heap Size و Maximum Stack Size را بر روی ۰x600 تنظیم کنید. و سپس بر روی گزینه GENERATE CODE کلیک کرده و وارد نرم افزار KEIL شوید.
کدنویسی در نرم افزار KEIL
تنظیمات اولیه:
uint8_t Coding[7];
سپس در تابع CDC_Control_FS در کیس های CDC_SET_LINE_CODING و دستور های زیر را به تر تیب کپی کنید. با استفاده از دستور های زیر پس از دریافت Line Coding از رشته pbuf آن را بایت به بایت ذخیره کرده و سپس دوباره بایت به بایت ارسال میکنیم.
//case CDC_SET_LINE_CODING: for(int i=0;i<7;i++) { Coding[i]=pbuf[i]; } //case CDC_GET_LINE_CODING: for(int i=0;i<7;i++) { pbuf[i]=Coding[i]; }
برای تشخیص داده های دریافتی از سمت کامپیوتر و ذخیره آن بایستی یک رشته برای ذخیره داده و یک متغیر برای ذخیره طول داده دریافتی تعریف شود. برای تعریف این رشته و متغیر میتوانید کد زیر در فایل usbd_cdc_if.c در یکی از قسمت های مشخص شده برای کاربر کپی کنید (برای مثال همان خط ۹۸).
uint8_t CDC_Buffer[128],CDC_Count;
حدود خط ۲۷۰ از فایل usbd_cdc_if.c تابعی با نام CDC_Receive_FS وجود دارد. در صورتی که قصد خواندن از سمت کامپیوتر را داشته باشیم، داده های ارسالی از سمت کامپیوتر به همراه طول آن در این تابع قرار داده میشود. برای ذخیره این با نوشتن کد زیر در این تابع (قبل از دستور return)، داده های دریافتی در متغیر و رشته ای که قبل از این تعیرف کردیم ذخیره خواهد شد. در ادامه در فایل main.c از این رشته و متغیر استفاده میکنیم.
CDC_Count=*Len; for(int i=0;i<*Len;i++)CDC_Buffer[i]=Buf[i];
تا به اینجا، کار ما در فایل usbd_cdc_if.c تمام است. حال بایستی متغیر های تعریف شده برای ذخیره داده های دریافتی از سمت کامپیوتر که در فایل usbd_cdc_if.c تعریف شده است را در فایل main.c نیز تعریف کنیم تا بتوانیم در برنامه از آن استفاده کنیم. کد زیر را در فایل main.c کپی کنید.
extern uint8_t CDC_Buffer[128],CDC_Count;
کد اصلی:
در کد زیر، با ارسال دستور start از سمت کامپیوتر میکروکنترلر شروع به ارسال عبارت Digispark.ir هر ۵۰۰ میلی ثانیه یک بار میکند. و زمانی که دستور stop از سمت کامپیوتر ارسال شود، این روند متوقف میشود. تا زمانی که دوباره دستور start ارسال شود.
#include <string.h> extern uint8_t CDC_Buffer[128],CDC_Count; int Flag=0; int main(void) { HAL_Delay(100); // MX_USB_DEVICE_Init(); while (1) { if(CDC_Count > 0) { if(strstr((char*)CDC_Buffer,"start")) { Flag=1; CDC_Transmit_FS("OK\r\n",4); } else if(strstr((char*)CDC_Buffer,"stop")) { Flag=0; CDC_Transmit_FS("OK\r\n",4); } } if (Flag == 1) { CDC_Transmit_FS("Digispark.ir\r\n",14); HAL_Delay(1000); } } }
اگر کد را با دقت مشاهده کنید. یک تاخیر ۱۰۰ میلی ثانیه وجود دارد و بعد از آن دستور MX_USB_DEVICE_Init() به صورت کامنت قرار داده شده است. این نکته ای است که بایستی خیلی به آن دقت داشته باشد. برای این که کامپیوتر برد شما را به عنوان یک USB Device بشناسد، بایستی این تاخیر ۱۰۰ میلی ثانیه را در ابتدای فایل main خود قبل از دستور مربوط به USB قرار دهید. در آخر بایستی برنامه را کامپایل کرده و بر روی برد Bluepill پروگرام کنید. در صورتی که با نحوه پروگرام کردن میکروکنترلر های Stm32 آشنا نیستید. لطفا بخش اول آموزش های میکروکنترلر Stm32 را مطالعه نمایید.
جمع بندی
در ابتدای این آموزش با درگاه USB ، انواع ورژن های آن، توان قابل تحمل و همچنین پایه های USB آشنا شدیم. در ادامه با کلاس های حالت های Host و Device در USB آشنا شدیم. در ادامه انواع کلاس های USB معرفی شد. پس از آن کلاس CDC که موضوع اصلی بحث این آموزش بود، مورد بررسی قرار گرفت. سپس در نرم افزار STM32CubeMX به پیکربندی USB پرداختیم. پس از انجام تنظیمات مربوط به USB، کلاک مورد نیاز برای راه اندازی USB گفته شد. در آخر در نرم فزار KEIL تنظیمات مورد نیاز برای ارسال دریافت از طرق USB گفته شد. و نمونه کدی برای آشنایی با چگونگی کار با USB قرار داده شد.
لوازم مورد نیاز
چنانچه در مراحل راه اندازی و انجام این پروژه با مشکل مواجه شدید، بدون هیچ نگرانی در انتهای همین پست، به صورت ثبت نظر سوالتان را مطرح کنید. من در سریعترین زمان ممکن پاسخ رفع مشکل شما را خواهم داد. همچنین اگر ایرادی در کدها و یا مراحل اجرایی وجود دارند میتوانید از همین طریق اطلاع رسانی کنید.
در پایان نظرات و پیشنهادات خود را با ما درمیان بگذارید و با اشتراک گذاری این آموزش در شبکه های اجتماعی از وبسایت دیجی اسپارک حمایت کنید.
ایولا
عالی بود
با سلام
از توجه شما سپاسگزارم
سلام مهندس
هیچ روشی نیست که فقط با کابل usb بشه پروگرم کرد؟ یعنی مستقیم به pc وصل شه
با سلام
در صورتی که یک بار بوت لودر مربوط به پروگرام از طریق USB روی برد پروگرام شود، امکان پروگرام از طریق USB نیز اضافه خواهد شد.
سلام مهندس .
من هر وقت پورت USB رو با کابل به کامپیوتر میزنم ارور not recognized میده .
این لینک رو هم بررسی کردم ولی اشکالم برطرف نشد .
https://pcbartists.com/firmware/stm32-firmware/stm32-usb-device-not-recognized-solution/
درایور خاصی باید نصب کنیم؟
ممنون میشم یه بررسی ای بفرمایید
با سلام
ایا Delay گفته شده در کد را قبل از تابع USB قرار داده اید؟ ممکن است مشکل از این قسمت باشد!
سلام مهندس جان اول تشکر میکنم بابت آموزش بسیار روان و کاربردیتون. دوم یه مشکلی که من الان دارم اینه که اگر بیش از ۶۴ کاراکتر در یک مرحله برای میکرو از طریق کام مجازی بفرستم آورلپ پیش میاد یعنی ۶۵ امین کاراکتررا به جای اولین کاراکتر در آرایه CCD-Buffer میزاره. میشه لطفا راهنمایی کنید که چه طور میتوان طول کاراکترهای ارسالی را به ۱۲۸ عدد بدون آورلپ رساند؟
ممنونم از توجهتون.
با سلام
بایستی داده های دریافتی را در آرایه دیگری که دارای سایز بزرگتری است ذخیره کرده و ادامه داده های دریافتی را در ادامه آن قرار دهید.