برد STM ترفند

پروژه ساخت ماوس به کمک USB میکروکنترلر STM32 در کلاس HID

نوشته شده توسط علی زاهدی

شاید تا به حال برای شما این سوال پیش آمده باشد که پورت USB موجود بر روی میکروکنترلر های STM32 چه کاربردی دارد. پورت USB موجود در برخی از میکروکنترلر های STM32 قابلیت های مختلفی دارد. پیش از این در آموزش راه اندازی پورت USB بردها و میکروکنترلرهای STM32 در مد CDC نحوه ارسال داده به سمت کامپیوتر بدون استفاده از هیچ مبدلی توضیح داده شد. یکی دیگر از کلاس های USB Device کلاس HID است. در آموزش ساخت موس با STM32 قصد داریم با استفاده از پورت USB موجود بر روی برد BulePill در مد HID یک ماوس بسازیم. در ادامه با مرجع تخصصی بردهای امبدد به زبان فارسی، دیجی اسپارک همراه باشید.

 


انواع پورت USB


USB مخفف کلمه Universal Serial Bus و به معنای درگاه همه گذر می باشد. USB یک استاندارد صنعتی است که در سال ۱۹۹۰ به ثبت رسیده است. از این درگاه برای ارسال و دریافت داده بین سیستم های الکترونیکی مانند کامپیوتر ، موبایل و … استفاده می شود. همچنین درگاه USB به عنوان منبع تغذیه نیز در سیستم های الکترونیکی شناخته می شود. در USB ورژن ۲ حداکثر جریان قابل انتقال تقریبا برابر ۵۰۰ میلی آمپر بود. در حالی که در USB ورژن ۳٫۱ حداکثر جریان قابل تحمل به ۵۰۰۰ میلی آمپر افزایش یافت. در سری C این درگاه ها قابلیت انتقال ولتاژ به ۲۰ ولت و انتقال داده همزمان با شارژ وجود دارد. درگاه USB ممکن است شکل های مختلفی داشته باشد که در تصویر زیر میتوانید انواع شکل های درگاه USB را مشاهده کنید.

USB Typesپورت USB برای انتقال اطلاعات از روش Differential یا همان دیفرانسیل استفاده می‌کنید. تا نسخه USB2 از یک جفت پایه D+ و D- که قرینه یکدیگر هستند استفاده می شود. USB یک پروتکل ارتباطی غیر همزمان (Half Duplex) است. عموما USB دارای ۴ پایه است. طبق جدول زیر، پایه های ۱ و ۴ خط ولتاژ مدار، که به ترتیب مثبت ۵ ولت و زمین هستند. پایه های ۲ و ۳ برای انتقال اطلاعات از طریق پورت USB است. که در جدول با نام های D+ و D- مشخص شده است.

USB Pinout

 


شناخت Host و Devise در USB


همانطور که می دانید ارتباط یو اس بی بین دو دستگاه است، که یکی از این دو دستگاه، هاست (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 در کلاس HID استفاده شده است.

BluePill USB Port

 


کلاس HID در USB


کلاس HID یا Human Interface Device Class یکی از کلاس های USB برای اتصال وسایل جانبی به رایانه است. این کلاس دستگاه برای دستگاه های است که رابط بین انسان و رایانه هستند. برای مثال میتوان به ماوس، کیبورد، کنترل کننده بازی، دستگاه های نمایش الفبای عددی و … اشاره نمود. کلاس USB HID دستگاههایی را که تقریباً با همه رایانه های مدرن استفاده می شوند ، توصیف می کند. بسیاری از توابع از پیش تعریف شده در کلاس USB HID وجود دارد. این توابع به تولیدکنندگان سخت افزار اجازه می دهد تا محصولی را با مشخصات کلاس USB HID طراحی کنند و انتظار دارند که با هر نرم افزاری که این مشخصات را داشته باشد نیز کار کند.

HID

 


اتصالات پروژه


ذر این پروژه تغذیه میکروکنترلر از پورت USB موجود بر روی برد BulePill تامین می‌شود. برای کنترل حالت های مختلف ماوس نیاز است که ۶ عدد کلید به میکروکنترلر متصل کنیم. این کلید ها به پایه های PB4 تا PB9 برای اتصال کلید ها به میکروکنترلر تعریف شده اند. ورودی های میکروکنترلر به صورت نرم افزاری PULL-UP تعریف شده اند. بنابر این بایستی یک سمت از تمامی کلید ها را به پایه GND برد BluePill متصل کنید. و سمت دیگر کلید ها به ترتیب به پایه هیا PB4 تا PB9 متصل شود.

Schematic

 


پیکربندی میکروکنترلر STM32


پس از ساخت پروژه جدید در نرم افزار STM32CubeMX مطابق بخش اول آموزش میکروکنترلر های STM32 بخش های RCC و SYS را تنظیم کنید. برای استفاده از نوار سمت چپ گزینه USB را انتخاب کنید. سپس تیک مربوط به گزینه Device (FS) را بزنید. پس از آن از همان نوار سمت چپ وارد بخش USB_DEVICE شده و گزینه Class For FS IP را بر روی Human Interface Device Class (HID) تنظیم کنید.

HID Set

و پس از آن ۶ پین از میکروکنترلر را به عنوان ورودی برای کنترل ماوس با استفاده از میکروکنترلر تعریف کنید. در این آموزش پایه های PB4 تا PB9 برای اتصال کلید ها به میکروکنترلر به صورت ورودی تعریف شده است. برای تعریف پایه ها به عنوان ورودی بایستی بر روی پایه مورد نظر کلیک کنید و گزینه GPIO_Input را انتخاب کنید. سپس از نوار سمت چپ وارد بخش GPIO شوید. سپس بر روی هر یک از پایه های ورودی کلیک کرده و آن ها را بصورت PULL-UP تنظیم کرده و مثل تصویر زیر لیبل های مربوطه را برای آن ها تعریف کنید.

STM32 Pinout

سپس از صفحه Clock Configuration فرکانس کاری میکروکنترلر را بر روی ۷۲ مگاهرتز تنظیم کنید. یا در صورتی که نیاز به فرکانس کمتری دارید، بایستی توجه داشته باشید که فرکانس بخش USB بایستی بر روی ۴۸ مگاهرتز تنظیم شود. سپس وارد صفحه ی Project Manager شوید. پس از انتخاب نام ، آدرس بایستی در قسمت Toolchainبرای انتخاب KEIL گزینه MDK-ARM را انتخاب کرده و سپس گزینه Min Version را بر روی V5 قرار دهید. سپس مقدار گزینه های Minimum Heap Size و Maximum Stack Size را بر روی ۰x600 تنظیم کنید. پس از آن وارد بخش Code Generator شده و بخش STM32Cube MCU Package را بر روی گزینه دوم یعنی Copy only the necessary library files تنظیم کنید. و سپس بر روی گزینه GENERATE CODE کلیک کرده و وارد نرم افزار KEIL شوید.

 


کد نویسی پروژه در نرم افزار KEIL


برای این که کامپیوتر بتواند USB میکروکنترلر STM32 را شناسایی کند بایستی در فایل main.c در ابتدای تابع main قبل از فراخوانی تابع MX_USB_DEVICE_Init()  یک تاخیر ۱۰۰ میلی ثانیه‌ای قرار دهید. این نکته ای است که بایستی خیلی به آن دقت داشته باشد.

HAL_Delay(100); 
MX_USB_DEVICE_Init();

نحوه عملکر HID در میکروکنترلر STM32 بر اساس descriptor است. این descriptor تعیین می‌کند که اطلاعات ارسالی از STM32 به کامپیوتر چه مفهومی دارد. خوشبختانه descriptor ساخته شده توسط نرم افزار STM32CubeMX مربوط به ماوس است. این descriptor در فایل usbd_desc.c به صورت زیر قرار دارد.

__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
{
  ۰x12,                       /*bLength */
  USB_DESC_TYPE_DEVICE,       /*bDescriptorType*/
  ۰x00,                       /*bcdUSB */
  ۰x02,
  ۰x00,                       /*bDeviceClass*/
  ۰x00,                       /*bDeviceSubClass*/
  ۰x00,                       /*bDeviceProtocol*/
  USB_MAX_EP0_SIZE,           /*bMaxPacketSize*/
  LOBYTE(USBD_VID),           /*idVendor*/
  HIBYTE(USBD_VID),           /*idVendor*/
  LOBYTE(USBD_PID_FS),        /*idProduct*/
  HIBYTE(USBD_PID_FS),        /*idProduct*/
  ۰x00,                       /*bcdDevice rel. 2.00*/
  ۰x02,
  USBD_IDX_MFC_STR,           /*Index of manufacturer  string*/
  USBD_IDX_PRODUCT_STR,       /*Index of product string*/
  USBD_IDX_SERIAL_STR,        /*Index of serial number string*/
  USBD_MAX_NUM_CONFIGURATION  /*bNumConfigurations*/
};

برای اجرای این پروژه و استفاده از این descriptor بایستی ابتدا یک ارایه که دارای ۴ عضو است تعریف کنید. هر عضو ارایه تعریف شده برای انجام عملیات خاصی خواهد بود. عملکرد عضو های این ارایه به صورت زیر است.

  • عضو اول report[0] : این عضو ارایه برای کنترل کلید های ماوس است که با قرار گیری عدد ۱ در آن چپ کلیک و با قرار گیری عدد ۱- داخل آن عملیت راست کلیک انجام می‌شود. توجه داشته باشید که بایستی بعد از هر بار مقدار دهی به این آرایه بایستی بعد از مدت زمان کوتاهی آن را مجددا صفر کنید.
  • عضو دوم report[1] : با قرار گیری عدد مثبت در این عضو آرایه نشانگر ماوس به سمت راست و با قرار گیری عدد منفی نشانگر به سمت چپ حرکت می‌کند. در این آموزش با فرشدن کلید چپ یا راست عدد ۵ و ۵- در این عضو آرایه قرار می‌گیرد. و با رها شدن کلید توسط کاربر مقدار این عضو صفر می شود.
  • عضو سوم report[2] : با قرار گیری عدد مثبت در این عضو آرایه نشانگر ماوس به سمت بالا و با قرار گیری عدد منفی نشانگر به سمت پایین حرکت می‌کند. در این آموزش با فرشدن کلید چپ یا راست عدد ۵ و ۵- در این عضو آرایه قرار می‌گیرد. و با رها شدن کلید توسط کاربر مقدار این عضو صفر می شود.
  • عضو چهارم report[3] : این عضو برای کنترل scroll ماوس است. با قرار دادن عدد مثبت و منفی در این عضو آرایه میتوانید اسکرول ماوس را نیز کنترل کنید. در این آموزش با این بخش کاری نداریم.

با معرفی این آرایه به تابع  USBD_HID_SendReport به صورت زیر، متوانید تمامی کار هایی که یک ماوس انجام می‌دهد را انجام دهید.

USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*) report,4);

حالا برای اجرای این پروژه کافیست که کد زیر را به پروژه خود اضافه کنید. توجه داشته باشید که نرم افزار STM32CubeMX قسمت هایی از فایل main.c را برای کد نویسی کاربر تعین کرده است. بهتر است که کد زیر را در این بخش ها قرار دهید.

#include "usbd_hid.h"
#include "usb_device.h"

int main(void)
{
	int8_t report[4]={0,0,0,0};
        HAL_Delay(100);
        // MX_USB_DEVICE_Init();
	while(1)
	{
		if(HAL_GPIO_ReadPin(RIGHT_GPIO_Port,RIGHT_Pin) == GPIO_PIN_RESET)
		{
			report[2] = 5;
			USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*) report,4);
			HAL_Delay(50);
		}
		else if(HAL_GPIO_ReadPin(LEFT_GPIO_Port,LEFT_Pin) == GPIO_PIN_RESET)
		{
			report[2] = -5;
			USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*) report,4);
		  HAL_Delay(50);
		}
		else if(HAL_GPIO_ReadPin(UP_GPIO_Port,UP_Pin) == GPIO_PIN_RESET)
		{
			report[1] = 5;
			USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*) report,4);
			HAL_Delay(50);
		}
		if(HAL_GPIO_ReadPin(DOWN_GPIO_Port,DOWN_Pin) == GPIO_PIN_RESET)
		{
			report[1] = -5;
			USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*) report,4);
			HAL_Delay(50);
		}
		else if(HAL_GPIO_ReadPin(Left_Click_GPIO_Port,Left_Click_Pin) == GPIO_PIN_RESET)
		{
			report[0] = 1;
			USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*) report,4);
			HAL_Delay(10);
			report[0] = 0;
			USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*) report,4);
			HAL_Delay(10);
			while(HAL_GPIO_ReadPin(Left_Click_GPIO_Port,Left_Click_Pin) == GPIO_PIN_RESET);
		}
			else if(HAL_GPIO_ReadPin(Right_Click_GPIO_Port,Right_Click_Pin) == GPIO_PIN_RESET)
		{
			report[0] = -1;
			USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*) report,4);
			HAL_Delay(10);
			report[0] = 0;
			USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*) report,4);
			HAL_Delay(10);
			while(HAL_GPIO_ReadPin(Right_Click_GPIO_Port,Right_Click_Pin) == GPIO_PIN_RESET);
		}
		else for(int i=0;i<4;i++)report[i]=0;
	}
}

در آخر بایستی برنامه را کامپایل کرده و بر روی برد Bluepill پروگرام کنید. در صورتی که با نحوه پروگرام کردن میکروکنترلر های Stm32 آشنا نیستید. لطفا بخش اول آموزش های میکروکنترلر Stm32 را مطالعه نمایید. پس از دانلود کد بر روی برد BluePill بایستی یک بار کلید reset را بر روی برد فشار دهید. در صورتی که تمامی مراحل را به طور صحیح طی کرده باشید. با فشردن کلید های ها مشاهده می‌کنید که نشانگر ماوس را به راحتی می‌توانید کنترل کنید.

 


جمع بندی


در ابتدای این آموزش با درگاه USB ، انواع ورژن های آن، توان قابل تحمل و همچنین پایه های USB آشنا شدیم. در ادامه با کلاس های حالت های Host و Device در USB آشنا شدیم. در ادامه انواع کلاس های USB معرفی شد. پس از آن کلاس HID که موضوع اصلی بحث این آموزش بود، مورد بررسی قرار گرفت. سپس در نرم افزار STM32CubeMX به پیکربندی USB پرداختیم. پس از انجام تنظیمات مربوط به USB، کلاک مورد نیاز برای راه اندازی USB گفته شد. در آخر در نرم فزار KEIL کد مورد نیاز برای ساخت ماوس با استفاده از میکروکنترلر STM32 قرار داده شده است.

 


لوازم مورد نیاز


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

 

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

 

در پایان نظرات و پیشنهادات خود را با ما درمیان بگذارید و با اشتراک گذاری این آموزش در شبکه های اجتماعی از وبسایت دیجی اسپارک حمایت کنید.

 

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

علی زاهدی

برنامه نویس و طراح سیستم های مبتنی بر میکروکنترلر

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

تبادل نظر و رفع عیب با ثبت دیدگاه

۹ دیدگاه

  • سلام
    خسته نباشید آموزش عالی بود، برای اسکرول کردن چطور باید اقدام کنیم؟

    • با سلام از توجه شما سپاسگزارم
      همانطور که در متن آموزش گفته شده است. عضو چهارم آرایه report برای کنترل Scroll ماوس هست و با قرار دادن عدد مثبت و منفی میتوانید این قابلیت ماوس را نیز کنترل کنید.

  • سلام . بسیار عالی بود . فقط یه سوال
    اگه بخایم که کامپیوتر ، stm رو به صورت کیبرد هم شناسایی کنه و دکمه های بیشتری در اختیار داشته باشیم باید چه کنیم؟ میخام مثلا یه پد درست کنم که هم کنترل موس داشته باشه و هم بتونه ۴ جهت اصلی رو داشته باشه و یه سری قابلیت دیگه

    • با سلام
      برای این که کامپیوتر میکروکنترلر را به عنوان کیبورد تشخیص دهد بایستی descriptor مربوط به کیبورد را در قسمت مربوطه وارد کنید. البته امکان معرفی کیبورد و ماوس به صورت هم زمان بر روی یک میکروکنترلر نیست. در فرصتی مناسب آموزش ساخت کیبورد با کمک میکروکنترلر STM32 را نیز منتشر می‌کنیم.

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

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

    • با سلام
      برای استفاده از USB میکروکنترلر STM32 نیاز به نصب درایوری نیست. آیا تاخیر ۱۰۰ میلی ثانیه در فایل main.c قبل از تابع MX_USB_DEVICE_Init را قرار داده اید؟ همانند کد زیر:

      HAL_Delay(100);
      MX_USB_DEVICE_Init();

  • باسلام
    من تمام مراحل رو انجام میدم اما موقع فراخوانی تابع USBD_HID_SendReport ایرادی که ازم میگیره اینه که hUsbDeviceFS رو نمیشناسه و هرکاری که میکنم درست نمیشه. البته وقتی فایل usb_device.c رو include میکنم شناساییش میکنه اما مشکلی که پیش میاد اینه که میگه hUsbDeviceFS چندین بار تعریف شده
    مشکل از کجاست؟

    • با سلام
      عبارت extern را به ابتدای خط مربوط به تعریف hUsbDeviceFS اضافه کنید. مجددا برنامه را تست کنید و نتیجه را از طریق بخش کامنت همین پست اعلام کنید.