در این مطلب قصد داریم با استفاده از پورت USB در میکروکنترلرهای STM32، یک پورت سریال مجازی بر روی این میکروکنترلرها ایجاد کنیم. اگر قبلا با بردهای آردیونو کار کرده باشید، احتمالا با تنظیمات مربوط به پورت COM در این نوع برد ها آشنایی دارید. در بردهای آردیونو یک آیسی مبدل USB به سریال وجود دارد که علاوه بر پروگرام کردن میکروی روی برد، امکان برقراری ارتباط بین کامپیوتر و میکروکنترلر را از طریق پروتکل UART و درگاه USB امکان پذیر میکند. سپس میتوان با اجرای یک ترمینالِ سریال مانند Serial monitor و یا Serial plotter، دادههای دریافتی را مشاهده کرده و یا دادههای مد نظر خود را به برد ارسال کنیم.
در اکثر میکروکنترلرهای STM32، پورت USB به صورت پیش فرض وجود داشته و میتوان با تبدیل آن به پورت سریال مجازی، اطلاعات را به صورت سریال و بدون نیاز به آیسی مبدل بین کامپیوتر و میکرو انتقال داد. همچنین شما میتوانید آموزش کامل نحوه اختصاص بخشی از حافظه FLASH به EEPROM در میکروکنترلر سری STM32 را نیز مطالعه کنید.
Host ،USB FS و Device
در برد دیسکاوری F407 که در این آزمایش استفاده شده است، کانکتور USB تعبیه شده بر روی برد، به پایههای مربوط به USB_FS متصل شده است. USB FS مخفف USB Fast Speed میباشد که سرعت انتقال داده در آن به 12 مگابیت بر ثانیه میرسد.
Host یا میزبان، یک دستگاه الکترونیکی است که ارتباط بین خود و دیوایسِ slave را کنترل میکند. میزبان معمولا یک رایانه شخصی یا لپ تاپ است.
دیوایس، یک دستگاه الکترونیکی است که توسط میزبان کنترل میشود. دیوایس میتواند صفحه کلید یا ماوس، PC ،Flash drive ،Disk drive یا تلفن هوشمند باشد.
وسایل الکترونیکی که قابلیت OTG دارند، میتوانند هم به صورت Host و هم به صورت Device عمل کنند. به عنوان مثال یک تلفن هوشمند هنگام اتصال به لپ تاپ Device بوده و هنگامی که یک حافظه فلش به آن گوشی متصل شود، برای آن حافظه Flash تبدیل به میزبان یا Host خواهد شد.
تعریف پروژه
در این جا قصد داریم بر روی برد دیسکاوری F407، پایه های مربوط به LED های روی برد را از طریق درگاه USB کنترل کنیم. بعد از ارسال کاراکتر ‘1’، تمام LED ها روشن شده و پیام وضعیت روشن بودن آنها به ترمینال جهت نمایش ارسال خواهد شد. همچنین با ارسال کاراکتر ‘0’ تمام LED ها خاموش شده و پیام خاموش شدن LED ها بر روی ترمینال نمایش داده خواهند شد. علاوه بر این، یک شمارنده بر روی میکرو ایجاد خواهیم کرد که با هر بار فشردن کلید User (کلید آبی)، مقدار آن افزایش یافته و بر روی ترمینالِ سریال نمایش داده شود.
وسایل مورد نیاز
برد دیسکاوری F407
یک عدد کابل USB mini
یک عدد کابل USB Micro
برنامه Serial terminal که در اینجا ما از Hercules استفاده میکنیم.
عزیزان توجه داشته باشند که می توانند از این مطلب، برای بردها و سری های دیگر میکروکنترلرهای STM32 نیز استفاده کنند.
مراحل انجام آزمایش
ابتدا نرم افزار STM32CUBEMX را اجرا کرده و بعد از انتخاب گزینه ACCESS TO MCU SELECTOR، میکروکنترلر STM32F407VG را انتخاب میکنیم.
بر اساس شماتیک برد دیسکاوری F407، چهار عدد LED بر روی پایههای PD12 تا PD15 وجود دارد که آنها را خروجی و یک کلید که بر روی PA0 قرار دارد را به صورت ورودی تعریف میکنیم (توجه شود که این کلید به صورت سخت افزاری، Pull-Down شده است).
در نرم افزار Cube، از بخش Categories به قسمت Connectivity رفته و USB_OTG_FS را انتخاب میکنیم. از آنجایی که قرار است برد ما به کامپیوتر متصل شود، کامپیوتر، میزبان (HOST) بوده و برد دیسکاوری باید در حالت DEVICE قرار گیرد. بنابراین Mode را بر روی Device_Only تنظیم میکنیم. در آخر برای راه اندازی بخش تغذیه USB در برد دیسکاوری، تیک Activate_VBUS را زده و آن را فعال میکنیم. با این کار PA9 به صورت اتوماتیک روی USB_OTG_FS_VBUS تنظیم میگردد.
در نرم افزار Cube از قسمت Categories، به بخش Middleware رفته و USB_DEVICE را انتخاب کنید. مانند تصویر زیر در قسمت Mode منوی Class For FS IP را باز کرده و آن را بر روی Communication Devices Class (Virtual Port Com) قرار دهید تا در هنگام تولید پروژه پیکربندیِ نرم افزاریِ مربوط به USB CDC انجام شده و کتابخانههای مورد نیاز جهت کار با پورت سریال مجازی ایجاد گردند.
بر اساس شماتیک برد دیسکاوری F407، برای فعال سازی VBUS، نیاز است که پایه PC0 صفر شود تا پایه EN در آیسی پاور سوییچ روی برد فعال گردد. بنابراین مجدد به Pin Configuration رفته و PC0 را نیز به صورت خروجی قرار میدهیم.
همانطور که در تصویر قبل نیز مشاهده شد، بخش Clock configuration دارای یک ضربدر قرمز رنگ میباشد. این ضربدر بعد از فعال کردن بخش USB ایجاد شده که نشان میدهد، باید تغییراتی را در بخش فرکانس اعمال کنیم.
ابتدا از قسمت Categories، به شاخه System Core رفته و RCC را انتخاب میکنیم. در قسمت Mode و HSE، گزینه Crystal/Ceramic Resonator را انتخاب کرده تا امکان استفاده از کریستال خارجی فراهم گردد.
حال به سر برگ Clock Configuration میرویم.
بعد از رفتن به سربرگ Clock Configuration، پیغام تنظیم مجدد کلاک نمایش داده می شود که در این جا No را انتخاب کنید.
از آن جایی که بر روی برد دیسکاوری، کریستال 8 مگاهرتز قرار دارد، Input frequency را بر روی 8 قرار میدهیم. PLL Source Mux را بر روی HSE قرار داده و سپس System Clock Mux را روی PLLCLK تنظیم می کنیم.
در نهایت HCLK(MHz) را بر روی فرکانس دلخواه مثلا 72Mhz تنظیم کرده و کلید Enter را بر روی کیبورد کامپیوتر زده تا تنظیمات مربوط به کلاک میکرو به صورت اتوماتیک توسط نرم افزار Cube محاسبه و اعمال گردد.
برای اطمینان از درست بودن تنظیماتِ مقادیرِ مربوط به کلاک، باید فرکانس بخش USB بر روی 48MHz تنظیم شده باشد.
برای راهاندازی بخش USB لازم است که در بخش Project Manager، سایز Heap و Stack را افزایش دهیم. مقدار Heap را به 0x2000 و Stack را به 0x4000 تغییر دهید. نام پروژه، محل ذخیره سازی و IDE توسعه نرم افزار، که در اینجا برای ما Keil است را انتخاب کرده و بر روی Generate Code کلیک کنید تا پروژه تولید گردد (در میکرو های سری F1 و F3 معمولا نیاز به تغییر سایز Heap و Stack نمیباشد).
کد نویسی – بخش اول
بعد از بالا آمدن محیط Keil، از قسمت Project، فایل main.c را از پوشه Application/User/Core و فایل usbd_cdc_if.c را از پوشه Application/User/USB_DEVICE/App باز کنید.
در فایل usbd_cdc_if.c، کتابخانه usbd_cdc_if.h را کپی کرده و آن را در فایل main.c پیست کنید.
بعد از پیست کردن فایل کتابخانه در main.c، حال نوبت به نوشتن برنامه میرسد. در قدم اول میخواهیم یک شمارنده ایجاد کنیم که با فشردن کلیدی که به صورت پیش فرض در برد دیسکاوری به پایه PA0 متصل است، مقدار افزایش یافته و در نهایت این مقدار از طریق پورت USB به کامپیوتر جهت نمایش منتقل شود.
ابتدا کتابخانه stdio.h را به فایل main.c اضافه کرده و متغیر cnt از نوع int و آرایه s از نوع uint8_t را تعریف میکنیم.
اضافه کردن کتابخانه:
#include "stdio.h"
تعریف متغییر ها:
int cnt=0; uint8_t s[10];
قبل از حلقه اصلی، پایه PC0 را صفر میکنیم تا بخش مربوط به تغذیه USB_FS در برد دیسکاوری F407 فعال شود. در داخل حلقه While، شرط مربوط به فشردن کلید و بالا رفتن شمارنده را نوشته و از طریق sprintf مقادیر را برای ارسال، به رشته تبدیل میکنیم. با استفاده از دستور CDC_Transmit_FS میتوانیم رشته را از برد به USB و در نهایت به کامپیوتر ارسال کنیم.
در دستور CDC_Transmit_FS عبارت STR، رشته و یا متغیر رشتهای و L طول رشته آن رشته میباشد.
CDC_Transmit_FS(STR,L);
به عنوان مثال برای آن که یک کلمه مانند microele که 8 کاراکتر دارد را ارسال کنیم، تابع به صورت زیر تکمیل میگردد:
CDC_Transmit_FS(microele,8)
همچنین برای ارسال آرایه رشتهای میتوانیم به شکل زیر عمل کنیم:
uint8_t str1[]=”microele”; CDC_Transmit_FS(str1,strlen(str1));
توجه شود که با استفاده از دستور strlen، تعداد کاراکترهای رشته مستقیما استخراج میشوند.
/* USER CODE BEGIN 2 */ HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_RESET); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == 1) { cnt++; sprintf(s,"%04d\r\n",cnt); CDC_Transmit_FS(s,strlen(s)); HAL_Delay(300); } } /* USER CODE END 3 */
تا این جای کار کدهای مربوط به شمارنده و ارسال آنها به USB جهت نمایش در کامپیوتر را انجام دادیم. حال میخواهیم LED های روی برد را از طریق کامپیوتر و پورت USB کنترل کنیم و بخش دریافت دادهها را تکمیل کنیم.
کد نویسی – بخش دوم
حال میخواهیم LED های روی برد را از طریق کامپیوتر و پورت USB کنترل کنیم و بخش دریافت دادهها را تکمیل کنیم. به فایل usbd_cdc_if.c رفته و تابع CDC_Receive_FS را در آن پیدا کنید.
با هر بار ارسال دیتا از کامپیوتر به برد، این تابع به صورت اتوماتیک فراخوانی شده و کاراکتر های دریافتی درون آرایه Buf قرار خواهند گرفت. با خواندن مقدار Buf[0] میتوانیم کاراکتر مورد نظر را خوانده و دستورات مربوط به آن را کد نویسی کنیم.
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ if(Buf[0] == '1') { HAL_GPIO_WritePin(GPIOD,0xf<<12,GPIO_PIN_SET); CDC_Transmit_FS("\r\nLEDS ON!\r\n",12); } if(Buf[0] == '0') { HAL_GPIO_WritePin(GPIOD,0xf<<12,GPIO_PIN_RESET); CDC_Transmit_FS("\r\nLEDS OFF!\r\n",13); } USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); USBD_CDC_ReceivePacket(&hUsbDeviceFS); return (USBD_OK); /* USER CODE END 6 */ }
اگر کاراکتر ‘1’ از کامپیوتر به برد ارسال شود، تمام LED ها روشن شده و پیام LEDS ON! از طرف برد به کامپیوتر جهت نمایش ارسال میگردد و اگر کاراکتر ‘0’ ارسال شود، تمام LED ها خاموش شده و پیام LEDS OFF! نمایش داده خواهد شد.
برنامه را Build و بر روی برد دیسکاوری LOAD میکنیم. برای اتصال برد دیسکاوری F407 به کامپیوتر و استفاده از USB_FS، لازم است که هر دو درگاهِ USB که بر روی برد دیسکاوری وجود د را به پورت USB کامپیوتر متصل کنیم. بر روی برد دیسکاوری یک درگاه USB-MINI برای ST-LINK وجود دارد که تغذیه برد نیز از همین درگاه تامین می شود. و دیگری یک درگاه USB-MICRO است که مربوط به USB-FS بوده که پورت سریال مجازی نیز بر روی همین درگاه ایجاد شده است.
اگر به Device manager در ویندوز بروید ممکن است که پورت USB میکرو در کامپیوتر شما شناخته نشده باشد. به همین منظور لازم است که درایور های USB VCP را از این لینک دانلود کرده و با توجه به نوع سیستم عامل خود، اقدام به نصب درایور کنید.
برای من پورت سریال مجازی به صورت پیش فرض بر روی COM7 تنظیم شده است. حال کافیست که با برنامه سریال ترمینال، برنامه نوشته شده را تست کنیم. در این آموزش از ترمینالِ Hercules استفاده شده است. که میتوانید آن را از اینجا دانلود کنید.
تنظیمات پورت را بر روی COM7 قرار داده و Baud rate را به صورت دلخواه تنظیم کرده و در آخر بر روی Open برای باز کردن پورت کلیک کنید.
با ارسال 1 و 2، LED ها روشن و خاموش شده و پیام مربوط به وضعیت آنها در ترمینال نشان داده میشود. همچنین با زدن کلیدِ روی برد، مقادیر شمارنده افزایش پیدا کرده و بر روی ترمینال نمایش داده میشود.
نتیجه آموزش
نتیجه گیری
در این مطلب توانستیم با راه اندازی USB در میکروکنترلر STM32F407، بین کامپیوتر و میکروکنترلر، بدون استفاده از آیسیهای واسط مبدل USB به سریال، داده ها را ارسال و دریافت کنیم. در نرم افزار CubeMX تنظیمات مربوط به USB_OTG_FS را انجام داده و از طریق ترمینالِ سریال، LED ها و کلید روی برد دیسکاوری را کنترل کردیم. از این روند می توان در میکروکنترلرها و سری های دیگر STM32 نیز استفاده نمایید.
امیدوارم از این آموزش کمال بهره را برده باشید. در صورتی که هرگونه نظر یا سوال داشتید درباره این آموزش لطفا اون رو در انتهای همین صفحه در قسمت دیدگاه ها قرار بدید. در کوتاه ترین زمان ممکن به اون ها پاسخ خواهم داد. اگر این مطلب براتون مفید بود، اون رو حتما با دوستانتون به اشتراک بگذارید. همینطور میتونید اون رو پس از اجرای عملی توی اینستاگرام با هشتگ microelecom# به اشتراک بگذارید و پیج مایکروالکام (microelecom@) رو هم منشن کنید.
سلام
فایل pdf قابل دانلود نیست
سلام، ممنون از توجهتون حتما بررسی میکنیم.
باسلام توضیحتون عالی بود ولی من یه پروژه دارم نیاز به کمک بیشتری دارم
باسلام میخوام درمیکرو armبااستفاده ازپورت usb باکابل نه باوای فای یابلوتوث
باگوشی اندروید ارتباط برقراره کنم وبتونم تنظیمات برد روانجام بدم وبه جایی بااستفاده ازگوشی وصل بشم شدنی هست ؟
خیلی ممنون .خدا خیرتون بده .کارم راه افتاد.خیلی ساده و روان توضیح داده بودین
ممنون از حسن نظر شما. از این که این مطلب برای شما مفید واقع شده است بسیار خوش حال هستیم.
سلام. خیلی ممنونم از توضیحات خوبتون. ولی یک بخشی رو از تنظیمات cube فراموش کردید بنویسید و فعال کنید که موجب می شد کد مناسب هم تولید نشود. در بخش تنظمیات Middleware از لیست سمت چپ نرم افزار cube، گزینه USB_DEVICE را انتخاب کرده و ان را روی
Communication Device class (Virtual Port Com)
قرار می دهیم و سپس تولید کد می کنیم.
با عرض سلام و تشکر بابت دقت نظر شما. ایراد پیش آمده اصلاح شد. از اطلاع رسانی دقیق شما سپاس گزاریم.
سلام
من ویندوز ۱۰ دارم و به Device manager رفتم که پورت USB میکرو در کامپیوتر من شناخته نشده بود. لینکی که شما فرستادید برای درایور های USB VCP رو داخل سایت ST دیدم ولی گفته بود برای ویندوز ۱۰ باید از درایور خود ویندوز استفاده بشه. درایور خود ویندوز هم مشکل داره. میشه راهنمایی کنید.
با سلام و وقت بخیر. درایورهای ارائه شده توسط شرکت ST بر روی ویندوز ۱۰ نیز قابل نصب میباشد و از این حیث نباید مشکل خاصی جهت نصب آن وجود داشته باشد. در صورت امکان بر روی یک کامپیوتر دیگر نیز آزمایش کنید.
موفق باشید
سلام. بنده هم ویندوز ۱۰ دارم و درایوری که برای ویندوز ۸ بود را نصب کردم. این نصب نیاز به restart دارد. بعد از restart کردن پورت مجازی را به درستی شناسایی می کند.