راه اندازی USB و ایجاد پورت سریال مجازی در میکروکنترلر های STM32

راه اندازی USB و ایجاد پورت سریال مجازی در میکروکنترلر های STM32
نوشته شده توسط

در این مطلب قصد داریم با استفاده از پورت 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 را انتخاب می‌کنیم.

نرم افزار STM32CUBEMX
نرم افزار STM32CUBEMX

بر اساس شماتیک برد دیسکاوری F407، چهار عدد LED بر روی پایه‌های PD12 تا PD15 وجود دارد که آن‌ها را خروجی و یک کلید که بر روی PA0 قرار دارد را به صورت ورودی تعریف می‌کنیم (توجه شود که این کلید به صورت سخت افزاری، Pull-Down شده است).

شماتیک LED ها در برد دیسکاوری F407
شماتیک LED ها در برد دیسکاوری F407
راه اندازی پورت سریال مجازی برای STM32
کلید در برد دیسکاوری برای راه اندازی F407

در نرم افزار Cube، از بخش Categories به قسمت Connectivity رفته و USB_OTG_FS را انتخاب می‌کنیم. از آن‌جایی که قرار است برد ما به کامپیوتر متصل شود، کامپیوتر، میزبان (HOST) بوده و برد دیسکاوری باید در حالت DEVICE قرار گیرد. بنابراین Mode را بر روی Device_Only تنظیم می‌کنیم. در آخر برای راه اندازی بخش تغذیه USB در برد دیسکاوری، تیک Activate_VBUS را زده و آن را فعال می‌کنیم. با این کار PA9 به صورت اتوماتیک روی USB_OTG_FS_VBUS تنظیم می‌گردد.

راه اندازی پورت سریال مجازی برای STM32
تنظیمات بخش USB در CubeMX

در نرم افزار Cube از قسمت Categories، به بخش Middleware رفته و USB_DEVICE را انتخاب کنید. مانند تصویر زیر در قسمت Mode منوی Class For FS IP را باز کرده و آن را بر روی Communication Devices Class (Virtual Port Com) قرار دهید تا در هنگام تولید پروژه پیکربندیِ نرم افزاریِ مربوط به USB CDC انجام شده و کتابخانه‌های مورد نیاز جهت کار با پورت سریال مجازی ایجاد گردند.

تنظیمات Middleware در نرم افزار CubeMX

بر اساس شماتیک برد دیسکاوری F407، برای فعال سازی VBUS، نیاز است که پایه PC0 صفر شود تا پایه EN در آیسی پاور سوییچ روی برد فعال گردد. بنابراین مجدد به Pin Configuration رفته و PC0 را نیز به صورت خروجی قرار می‌دهیم.

راه اندازی پورت سریال مجازی برای STM32
شماتیک USB در برد دیسکاوری F407
راه اندازی پورست سریال مجازی در میکروکنترلر STM32
تعریف پایه PC0 به عنوان خروجی

همانطور که در تصویر قبل نیز مشاهده شد، بخش Clock configuration دارای یک ضربدر قرمز رنگ می‌باشد. این ضربدر بعد از فعال کردن بخش USB ایجاد شده که نشان می‌دهد، باید تغییراتی را در بخش فرکانس اعمال کنیم.

راه اندازی پورت سریال مجازی برای STM32
Clock configuration در CubeMX

ابتدا از قسمت Categories، به شاخه System Core رفته و RCC را انتخاب می‌کنیم. در قسمت Mode و HSE، گزینه Crystal/Ceramic Resonator را انتخاب کرده تا امکان استفاده از کریستال خارجی فراهم گردد.

راه اندازی پورت سریال مجازی برای STM32
تنظیمات RCC در CubeMX

حال به سر برگ Clock Configuration می‌رویم.

Clock configuration در CubeMX
Clock configuration در CubeMX

بعد از رفتن به سربرگ Clock Configuration، پیغام تنظیم مجدد کلاک نمایش داده می شود که در این جا No را انتخاب کنید.

Clock configuration در CubeMX
Clock configuration در CubeMX

از آن جایی که بر روی برد دیسکاوری، کریستال 8 مگاهرتز قرار دارد، Input frequency را بر روی 8 قرار می‌دهیم. PLL Source Mux را بر روی HSE قرار داده و سپس System Clock Mux را روی PLLCLK تنظیم می کنیم.

Clock configuration در CubeMX
Clock configuration در CubeMX

در نهایت HCLK(MHz) را بر روی فرکانس دلخواه مثلا 72Mhz تنظیم کرده و کلید Enter را بر روی کیبورد کامپیوتر زده تا تنظیمات مربوط به کلاک میکرو به صورت اتوماتیک توسط نرم افزار Cube محاسبه و اعمال گردد.

Clock configuration در CubeMX
Clock configuration در CubeMX

برای اطمینان از درست بودن تنظیماتِ مقادیرِ مربوط به کلاک، باید فرکانس بخش USB بر روی 48MHz تنظیم شده باشد.

Clock configuration در CubeMX
Clock configuration در CubeMX

برای راه‌اندازی بخش USB لازم است که در بخش Project Manager، سایز Heap و Stack را افزایش دهیم. مقدار Heap را به 0x2000 و Stack را به 0x4000 تغییر دهید. نام پروژه، محل ذخیره سازی و IDE توسعه نرم افزار، که در اینجا برای ما Keil است را انتخاب کرده و بر روی Generate Code کلیک کنید تا پروژه تولید گردد (در میکرو های سری F1 و F3 معمولا نیاز به تغییر سایز Heap و Stack نمی‌باشد).

تنظیم مقادیر Heap و Stack در Project manager
تنظیم مقادیر Heap و Stack در Project manager

کد نویسی – بخش اول

بعد از بالا آمدن محیط Keil، از قسمت Project، فایل main.c را از پوشه Application/User/Core و فایل usbd_cdc_if.c را از پوشه Application/User/USB_DEVICE/App باز کنید.

باز کردن فایل های c در محیط Keil راه اندازی پورت سریال در STM32
باز کردن فایل های c در محیط Keil

در فایل usbd_cdc_if.c، کتابخانه  usbd_cdc_if.h را کپی کرده و آن را در فایل main.c پیست کنید.

کپی کردن کتابخانه usbd
کپی کردن کتابخانه usbd
راه اندزای پورت سریال در STM32
کپی کردن کتابخانه usbd

بعد از پیست کردن فایل کتابخانه در main.c، حال نوبت به نوشتن برنامه می‌رسد. در قدم اول می‌خواهیم یک شمارنده ایجاد کنیم که با فشردن کلیدی که به صورت پیش فرض در برد دیسکاوری به پایه PA0 متصل است، مقدار افزایش یافته و در نهایت این مقدار از طریق پورت USB به کامپیوتر جهت نمایش منتقل شود.

ابتدا کتابخانه stdio.h را به فایل main.c اضافه کرده و متغیر cnt از نوع int و آرایه s از نوع uint8_t را تعریف می‌کنیم.

افزودن کتابخانه stdio.h در فایل main
افزودن کتابخانه stdio.h در فایل main
تعریف متغیر ها در فایل main
تعریف متغیر ها در فایل main

اضافه کردن کتابخانه:

#include "stdio.h"

تعریف متغییر ها:

int cnt=0;
 uint8_t s[10];

قبل از حلقه اصلی، پایه PC0 را صفر می‌کنیم تا بخش مربوط به تغذیه USB_FS در برد دیسکاوری F407 فعال شود. در داخل حلقه While، شرط مربوط به فشردن کلید و بالا رفتن شمارنده را نوشته و از طریق sprintf مقادیر را برای ارسال، به رشته تبدیل می‌کنیم. با استفاده از دستور CDC_Transmit_FS می‌توانیم رشته را از برد به USB و در نهایت به کامپیوتر ارسال کنیم.

کدنویسی بخش شمارنده در فایل main
کدنویسی بخش شمارنده در فایل main

در دستور 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 را در آن پیدا کنید.

دریافت داده در فایل usbd_cdc_if
دریافت داده در فایل usbd_cdc_if

با هر بار ارسال دیتا از کامپیوتر به برد، این تابع به صورت اتوماتیک فراخوانی شده و کاراکتر‌ های دریافتی درون آرایه Buf قرار خواهند گرفت. با خواندن مقدار Buf[0] می‌توانیم کاراکتر مورد نظر را خوانده و دستورات مربوط به آن را کد نویسی کنیم.

کنترل LED ها در فایل usbd_cdc_if با تابع CDC_Receive_FS
کنترل LED ها در فایل usbd_cdc_if با تابع CDC_Receive_FS
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 را از این لینک دانلود کرده و با توجه به نوع سیستم عامل خود، اقدام به نصب درایور کنید.

نصب درایور USB STM32 VCP
نصب درایور USB STM32 VCP
شناسایی پورت مجازی توسط ویندوز در Device Manager
شناسایی پورت مجازی توسط ویندوز در Device Manager

برای من پورت سریال مجازی به صورت پیش فرض بر روی COM7 تنظیم شده است. حال کافیست که با برنامه سریال ترمینال، برنامه‌ نوشته شده را تست کنیم. در این آموزش از ترمینالِ Hercules استفاده شده است. که می‌توانید آن را از اینجا دانلود کنید.

تنظیمات پورت را بر روی COM7 قرار داده و Baud rate را به صورت دلخواه تنظیم کرده و در آخر بر روی Open برای باز کردن پورت کلیک کنید.

ارسال و دریافت دیتا با برنامه Hercules
ارسال و دریافت دیتا با برنامه Hercules

با ارسال 1 و 2، LED ها روشن و خاموش شده و پیام مربوط به وضعیت آن‌ها در ترمینال نشان داده می‌شود. همچنین با زدن کلیدِ روی برد، مقادیر شمارنده افزایش پیدا کرده و بر روی ترمینال نمایش داده می‌شود.

برد دیسکاوری Discovery F407
برد Discovery F407

نتیجه آموزش


نتیجه گیری

در این مطلب توانستیم با راه اندازی USB در میکروکنترلر STM32F407، بین کامپیوتر و میکروکنترلر، بدون استفاده از آیسی‌های واسط مبدل USB به سریال، داده ها را ارسال و دریافت کنیم. در نرم افزار CubeMX تنظیمات مربوط به USB_OTG_FS را انجام داده و از طریق ترمینالِ سریال، LED ها و کلید روی برد دیسکاوری را کنترل کردیم. از این روند می توان در میکروکنترلرها و سری های دیگر STM32 نیز استفاده نمایید.

امیدوارم از این آموزش کمال بهره را برده باشید. در صورتی که هرگونه نظر یا سوال داشتید درباره این آموزش لطفا اون رو در انتهای همین صفحه در قسمت دیدگاه ها قرار بدید. در کوتاه ترین زمان ممکن به اون ها پاسخ خواهم داد. اگر این مطلب براتون مفید بود، اون رو حتما با دوستانتون به اشتراک بگذارید. همینطور میتونید اون رو پس از اجرای عملی توی اینستاگرام با هشتگ microelecom# به اشتراک بگذارید و پیج مایکروالکام (microelecom@) رو هم منشن کنید.

۹ دیدگاه برای “راه اندازی USB و ایجاد پورت سریال مجازی در میکروکنترلر های STM32

  1. باسلام میخوام درمیکرو armبااستفاده ازپورت usb باکابل نه باوای فای یابلوتوث
    باگوشی اندروید ارتباط برقراره کنم وبتونم تنظیمات برد روانجام بدم وبه جایی بااستفاده ازگوشی وصل بشم شدنی هست ؟

    1. ممنون از حسن نظر شما. از این که این مطلب برای شما مفید واقع شده است بسیار خوش حال هستیم.

  2. سلام. خیلی ممنونم از توضیحات خوبتون. ولی یک بخشی رو از تنظیمات cube فراموش کردید بنویسید و فعال کنید که موجب می شد کد مناسب هم تولید نشود. در بخش تنظمیات Middleware از لیست سمت چپ نرم افزار cube، گزینه USB_DEVICE را انتخاب کرده و ان را روی
    Communication Device class (Virtual Port Com)
    قرار می دهیم و سپس تولید کد می کنیم.

    1. با عرض سلام و تشکر بابت دقت نظر شما. ایراد پیش آمده اصلاح شد. از اطلاع رسانی دقیق شما سپاس گزاریم.

  3. سلام
    من ویندوز ۱۰ دارم و به Device manager رفتم که پورت USB میکرو در کامپیوتر من شناخته نشده بود. لینکی که شما فرستادید برای درایور های USB VCP رو داخل سایت ST دیدم ولی گفته بود برای ویندوز ۱۰ باید از درایور خود ویندوز استفاده بشه. درایور خود ویندوز هم مشکل داره. میشه راهنمایی کنید.

    1. با سلام و وقت بخیر. درایور‌های ارائه شده توسط شرکت ST بر روی ویندوز ۱۰ نیز قابل نصب می‌باشد و از این حیث نباید مشکل خاصی جهت نصب آن وجود داشته باشد. در صورت امکان بر روی یک کامپیوتر دیگر نیز آزمایش کنید.
      موفق باشید

    2. سلام. بنده هم ویندوز ۱۰ دارم و درایوری که برای ویندوز ۸ بود را نصب کردم. این نصب نیاز به restart دارد. بعد از restart کردن پورت مجازی را به درستی شناسایی می کند.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *