DIY افعل ذلك بنفسك لوحة التحكم المركبة الفضائية


مرحبا أيها القراء الأعزاء!

جاءت إحدى الأفكار إلي هنا ، ولكن ليس لتجميع لوحة تحكم لسفينة فضائية. إلى USB. مع دعم السائق الأصلي. اختفى مخصص. لعصا وكل شيء يعمل ، دون أي رقصات الدف. نتيجة لذلك ، حصلنا على نوع من "لوحة اللعبة" الوحشية لمحاكاة الفضاء. بشكل عام ، نحكم على نفسك.

في البداية ، لم يكن لدي أي فكرة عما سيحدث في النهاية. أردت اثنين من عصا التحكم الرئيسية ، كما هو الحال في Soyuz-MS ، وبعض المفاتيح ، والأزرار وعدة شاشات العرض.

بعد تقدير سطح العمل في طاولتي ، اخترت أبعاد وحدة التحكم في العرض والعمق 500 * 300 مم. وبعد تفتيشه في مستودعات ومحلات البناء بحثًا عن مواد البناء ، اختار ارتفاعًا يصل إلى 125 ملم. نتيجة لذلك ، حصلت على ورقة من الخشب الرقائقي 4 مم ، شرائح 20 * 12 مم ولوحة 120 * 20 مم.

في cad ، تم رسم رسم وحدة التحكم عن بعد بسرعة. وفعلت ذلك في شجرة لفترة طويلة جدا. ثلاثة اشهر في عطلة نهاية الأسبوع. وليس لأنه كان يعمل بفرض منشار ، ولكن بسبب ضيق الوقت. كانت اللوحة ممدودة ، غطى بالرمل ورسمت بطلاء المينا ، تشبه الألوان إلى الألواح الحقيقية لسفن الفضاء أو الطائرات.



لكن الآن ، اترك أعمال الرسم جانباً وسأتحدث عن الحشو الإلكتروني.

تم شراء أجزاء الراديو على علي. كما المقود ، لقد وجدت هذه. بشكل عام ، فإن الموقف مع مثل هذه المقود هو التماس الكامل. الحلول الصناعية باهظة الثمن ، ولكنها رخيصة الثمن ، تأتي كألعاب وبالتالي فهي سيئة. هذه هي ذات جودة عالية جدا ، لكنها لن تكون على علم كم من الوقت سوف تكون.


ما تبقى من الشيء القليل لم يسبب مشاكل. وحدة تحكم مختارة STM32. باعتبارها ADC لعصا التحكم ، ADS1118 16 بت. تم أيضًا شراء مصدر طاقة 12 فولت ، في الواقع ، يرجع هذا الجهد إلى حقيقة أنني حصلت على مقياس للوقود من "الشاه" ، والذي أردت أيضًا أن أعلقه هنا.


في الصورة ، مزود الطاقة ، مثبتات 5 و 3.3 V ، STM32 ، MCP23017 ، ADS1118

وحدة تحكم 100 دبوس STM32F407VET6 ، متصلة به:

2 محددات إلى 4 وظائف
1 المقاوم المتغير
2 مفاتيح المحور
4 محاور رئيسية
2 محاور مساعدة
2 محاور التحكم
4 مفاتيح رئيسية ، 2 أزرار لكل منهما
20 أزرار مع المصابيح
4 مفاتيح رئيسية مع المصابيح
2 أزرار الفطر مع المصابيح
2 أزرار توقيت
3 مفاتيح مع المصابيح
13 مفاتيح
2 ADS1118 (ADC)
4 MAX7219 (شاشات LED ذات 8 أرقام)
2 TM1637 (ساعات العرض)
1 PCF8574 (موسع I / O ، موصول بشاشة عرض الأحرف)


الهيكل الناتج

قررت أنه سيكون أكثر من اللازم بالنسبة لمئات أرجل عضو الكنيست ، كما قررت ، وأضيفت هنا موسعات I / O: أربع قطع من MCP23017 ، لكل 16 مدخلات أو مخرجات. بالنظر إلى المستقبل ، سأقول إن التأخير في استطلاع مدخلات الموسع اتضح أن حوالي 0.13 مللي ثانية لكل شريحة ، بسرعة I2C بسرعة 400 كيلوهرتز. وهذا هو ، مع وجود هامش يغطي الحد الأدنى لوقت الاقتراع USB من 1 مللي ثانية.

لكي لا تقود ناقل I2C مع طلبات عديمة الفائدة ، يحتوي MCP23017 على مقاطعة المخرجات التي تم ضبطها عند تغير حالة المدخلات. أنا أيضا تطبيقها في مشروعي. كما اتضح أكثر ، بسبب قعقعة الاتصالات ، كانت هذه الانقطاعات عديمة الفائدة.

لا يواكب ADS1118 ADC سرعة USB إلى حد ما ، ويبلغ أداؤه المعلنة 820 عينة على الأكثر في الثانية ، أي 1.2 مللي ثانية ، بينما يحتوي على عدة مدخلات متصلة بالفعل بـ ADC من خلال المضاعف. لقد استخدمت 2 المدخلات على رقاقة واحدة ، وبالتالي فإن وقت التحديث للقيم هو 2.4 مللي ثانية. سيئة ، ولكن ماذا يمكنك أن تفعل؟ لسوء الحظ ، لا توجد إعلانات ADC سريعة أخرى 16 بت على علي.


في الداخل يبدو هذا ، لكن بعد تثبيت الأسلاك ، يصبح الوضع أسوأ بكثير

برنامج وحدة المعالجة المركزية مكتوب بأسلوب برنامج PLC. لا توجد طلبات حظر. النواة لا تنتظر المحيط ، ولم يتح لها الوقت وللجحيم معها ، في الدورة التالية سوف تستجوب. لا يوجد RTOS في المشروع أيضًا ، لقد جربته ، واجهت وقتًا انتظارًا للمهمة بحد أدنى قدره 1 مللي ثانية - فقد تبين أنه ببطء إذا أردنا إرسال البيانات عبر USB بتردد قدره 1 مللي ثانية. نتيجة لذلك ، أدركت أنني سوف أستخدم نظام التشغيل بدون osDelay () ، ثم لماذا RTOS؟ كما هو الحال في PLC ، يكفي وضع تعليمات البرنامج واحدًا تلو الآخر داخل حلقة لا نهائية.

تستخدم ، بالطبع ، CubeMX ومكتبات HAL. بالمناسبة ، لقد تحولت مؤخراً إلى HAL وتساءلت عن الراحة. لا أعرف لماذا لا تزال غير شائعة ، والشيء الرئيسي هو معرفة ذلك في البداية ، وبعد ذلك سوف يتم ذلك بكل بساطة. يبدو أنك تقوم ببرمجة اردوينو.

الجهاز سيكون لدينا USB مخصص HID. HID هو الماوس ولوحة المفاتيح ولوحة التحكم وعصا التحكم وبعضها الآخر. وهناك العرف. كل هذا لا يتطلب برامج تشغيل من نظام التشغيل. بتعبير أدق ، تم كتابتها بالفعل من قبل المطور. يعد الجهاز المخصص جيدًا لأننا نجمع بين إمكانات جميع الأجهزة المذكورة أعلاه وفقًا لتقديرنا.

بشكل عام ، يكون شيء USB معقدًا للغاية ، حيث يحتوي على كتيب يحتوي على ما يقرب من ألف صفحة ولا يمكنك التقاطه من لحظة. من لا يرغب في قراءة الأدلة الثقيلة ، فهناك مقالة USB رائعة في NutShell ، google. لديها أيضا ترجمة. سأحاول شرح بعض النقاط "على الأصابع".

USB - نقل حزم البيانات مع مجموعة من المستويات والتجريدات. الجهاز معنا - لا يمكنه طلب أي بيانات ، يبدأ المضيف عملية النقل بأكملها. يكتب المضيف ويطلب البيانات إلى نقاط النهاية المزعومة ، ماديًا هي بعض المخازن المؤقتة في ذاكرة MK. حتى يتمكن المضيف من فهم نقاط النهاية التي من الممكن كتابتها ، ونقاط النهاية التي يجب قراءتها والبيانات التي يمكن تفسيرها كأزرار وفؤوس في الجهاز الخاص بنا ، وبصفة عامة ، ما نوع الجهاز الموجود لدينا هنا ، في بداية الاتصال الذي يطلب واصفات الجهاز. هناك العديد من هذه الواصفات ومن الصعب تكوينها ويمكنك كما تشاء ، وكذلك ارتكاب الأخطاء في أي مكان. جسديا ، فهي مجموعة من بايت.

في الواقع ، ستنشئ CubeMX رمز تهيئة Custom HID أفضل منا.





يرجى الانتباه إلى الصورة الأخيرة تحت الرقم 3. هذا هو حجم الواصف بالبايت ، والذي يحدد المحاور والأزرار الموجودة على الجهاز لدينا. يتم إنشاء هذا الواصف في أداة واصف HID . هناك العديد من الأمثلة للدراسة الذاتية. عموما ، هنا هو بلدي واصف. لا توجد بيانات للشاشات حتى الآن ، لسهولة الفهم ، ولكن جميع أزرار وفؤوس عصا التحكم موجودة. يجب وضعها في ملف usbd_custom_hid_if.c. بشكل افتراضي ، يجعل هذا المقبض المكعب فارغًا.

واصف HID (حجم 104 بايت)
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END = { /* USER CODE BEGIN 0 */ 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x09, 0x04, // USAGE (Joystick) 0xa1, 0x01, // COLLECTION (Application) 0x05, 0x02, // USAGE_PAGE (Simulation Controls) 0x09, 0xbb, // USAGE (Throttle) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x27, 0xff, 0xff, 0x00, 0x00, // LOGICAL_MAXIMUM (65535) 0x75, 0x10, // REPORT_SIZE (16) 0x95, 0x01, // REPORT_COUNT (1) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x01, // USAGE (Pointer) 0xa1, 0x00, // COLLECTION (Physical) 0x09, 0x30, // USAGE (X) 0x09, 0x31, // USAGE (Y) 0x95, 0x02, // REPORT_COUNT (2) 0x81, 0x02, // INPUT (Data,Var,Abs) 0xc0, // END_COLLECTION 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x32, // USAGE (Z) 0x95, 0x01, // REPORT_COUNT (1) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 0x33, // USAGE (Rx) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 0x34, // USAGE (Ry) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 0x35, // USAGE (Rz) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 0x36, // USAGE (Slider) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 0x39, // USAGE (Hat switch) 0x15, 0x01, // LOGICAL_MINIMUM (1) 0x25, 0x08, // LOGICAL_MAXIMUM (8) 0x35, 0x00, // PHYSICAL_MINIMUM (0) 0x46, 0x0e, 0x01, // PHYSICAL_MAXIMUM (270) 0x65, 0x14, // UNIT (Eng Rot:Angular Pos) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x01, // REPORT_COUNT (1) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x05, 0x09, // USAGE_PAGE (Button) 0x19, 0x01, // USAGE_MINIMUM (Button 1) 0x29, 0x40, // USAGE_MAXIMUM (Button 64) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x40, // REPORT_COUNT (64) 0x55, 0x00, // UNIT_EXPONENT (0) 0x65, 0x00, // UNIT (None) 0x81, 0x02, // INPUT (Data,Var,Abs) /* USER CODE END 0 */ 0xC0 /* END_COLLECTION */ }; 


في الواقع ، يمكن تكوينها كما تريد ، أولاً ، تقوم بتعيين USAGE PAGE و USAGE المطلوبة ، على سبيل المثال ، محور USAGE (Throttle) ، وبعد كلمة INPUT (Data ، Var ، Abs) ، سوف يفترض النظام أن لدينا محور "Gas". يتم تعيين البعد للمحور المتغير ورقمهم بواسطة المعلمات LOGICAL_MAXIMUM ، MINIMUM ، REPORT_SIZE ، REPORT_COUNT ، والتي يجب أن تكون قبل INPUT.

يمكن العثور على مزيد من التفاصيل حول هذه المعلمات ، وكذلك (البيانات ، فار ، القيمة المطلقة) في تعريف فئة الأجهزة لأجهزة واجهة الإنسان (HID) الإصدار 1.11 .

فيما يلي مثال على تهيئة محور Throttle من الواصف الخاص بي. في هذا المثال ، يحتوي Throttle على نطاق قيم من 0-65535 ، والذي يتوافق مع متغير uint16_t واحد.

  0x05, 0x02, // USAGE_PAGE (Simulation Controls) 0x09, 0xbb, // USAGE (Throttle) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x27, 0xff, 0xff, 0x00, 0x00, // LOGICAL_MAXIMUM (65535) 0x75, 0x10, // REPORT_SIZE (16) 0x95, 0x01, // REPORT_COUNT (1) 0x81, 0x02, // INPUT (Data,Var,Abs) 

ونعم ، ومع ذلك ، لنفترض أنه لا يمكنك كتابة LOGICAL_MAXIMUM أو MINIMUM أو REPORT_SIZE أو REPORT_COUNT في كل مرة ، فسيحدد المضيف هذه القيمة بواسطة المعلمة السابقة. يتضح ذلك من خلال المحاور التي تذهب واحدة تلو الأخرى ، دون تحديد الحجم والرقم:

  0x09, 0x32, // USAGE (Z) 0x95, 0x01, // REPORT_COUNT (1) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 0x33, // USAGE (Rx) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 0x34, // USAGE (Ry) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 0x35, // USAGE (Rz) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 0x36, // USAGE (Slider) 

الهيكل التالي يتوافق مع كل هذا الواصف ، والذي هو أعلى تحت المفسد. في الواقع ، لم تعد إلزامية ، بل هي أكثر ملاءمة للتسجيل بناءً على المؤشرات.

 #pragma pack(push, 1) typedef struct _myReportStruct { uint16_t Throttle; uint16_t X; uint16_t Y; uint16_t Z; uint16_t Rx; uint16_t Ry; uint16_t Rz; uint16_t Slider; uint8_t Hat; // 0 - none, 1 - up, 2 - up-right, 3 - right, 4 - down-right... uint32_t Buttons1; // 32 buttons of 1 bit each uint32_t Buttons2; // 32 buttons of 1 bit each }myReportStruct; #pragma pack(pop) volatile myReportStruct Desk; 

يمكن إرسال هذه البنية إلى المضيف بواسطة الوظيفة

 USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, (uint8_t *) &Desk, sizeof(Desk)); 

المعلمة الأولى هي مقبض USB ؛ تم إنشاؤها بالفعل في المكعب لدينا. قد تحتاج إلى تضمين الملف الضروري مع التضمين حيث تتم تهيئة هذا المؤشر لأول مرة وكتابة خارجي USBD_HandleTypeDef hUsbDeviceFS؛ بحيث يمكنك العمل معه. المعلمة الثانية هي مؤشر إلى هيكلنا والثالث هو حجم الهيكل بالبايت.

بعد ملء وحدة التحكم وامضها ، ستلاحظ أن هناك شيئًا USB يتحرك ببطء. لا يتم تحديث البيانات من لوحة لدينا بسرعة. لكي تكون سريعًا ، في ملفات usbd_customhid.h ، تحتاج إلى تغيير #define CUSTOM_HID_EPIN_SIZE إلى الحد الأقصى للقيمة 0x40 ، #define CUSTOM_HID_EPOUT_SIZE أيضًا تعيين 0x40. في ملف usbd_customhid.c ، ابحث عن التعليقات في واصف نقطة النهاية "/ * bInterval: Polling Interval (20 ms) * /" وتغيير بايت واصف إلى 0x01 لكل نقطة نهاية ، مرتين فقط. والتي سوف تتوافق مع تبادل البيانات 1 مللي.


يجب أن يكون شيء مثل هذا. الجهاز القياسي دون تثبيت أي برامج تشغيل

بشكل عام ، وظيفة الإدارة مفهومة قليلاً. من السهل جدًا القيام به وجميع الأزرار والفؤوس تعمل بالفعل. يبقى أن تعمل العروض. لقد فعلت ذلك ، حوالي ستة أشهر ، ولمدة نصف عام ، كانت اللجنة تجمع الغبار في صندوق طويل. لا وقت لذلك ، قررت أن أضع المقال في هذا النموذج ، وإلا فإنه لا يخاطر حتى بالخروج.

مع الشاشات ، كل شيء هو نفسه كما هو الحال مع المحاور. بالنسبة لهم ، نحتاج إلى استكمال واصف HID الخاص بجهازنا ، ما عليك سوى الإشارة إلى أن هذه العروض معروضة وبدلاً من قبول بيانات الإدخال ، سيرسل المضيف بيانات المخرجات.

نما مقبض جهاز HID بشكل ملحوظ. لقد قمت بالفعل بتطبيق معلمات معرف التقرير حتى لا تسد المخزن المؤقت للإرسال / الاستلام ونقاط النهاية بالبيانات الكاملة ولتمييز نوع البرقية التي تلقيناها. معرف التقرير هو بايت uint8_t مع القيمة التي تأتي في بداية البرق. القيمة التي حددناها في واصف الجهاز HID.

CUSTOM_HID_ReportDesc_FS
 //AXIS 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x04, // USAGE (Joystick) 0xa1, 0x01, // COLLECTION (Application)28 0x05, 0x02, // USAGE_PAGE (Simulation Controls) 0x09, 0xbb, // USAGE (Throttle) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x27, 0xff, 0xff, 0x00, 0x00, // LOGICAL_MAXIMUM (65535) 0x75, 0x10, // REPORT_SIZE (16) 0x95, 0x01, // REPORT_COUNT (1) 0x85, 0x01, // REPORT_ID (1) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x01, // USAGE (Pointer) 0xa1, 0x00, // COLLECTION (Physical) 0x09, 0x30, // USAGE (X) 0x09, 0x31, // USAGE (Y) 0x95, 0x02, // REPORT_COUNT (2) 0x81, 0x02, // INPUT (Data,Var,Abs) 0xc0, // END_COLLECTION 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x32, // USAGE (Z) 0x95, 0x01, // REPORT_COUNT (1) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 0x33, // USAGE (Rx) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 0x34, // USAGE (Ry) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 0x35, // USAGE (Rz) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 0x36, // USAGE (Slider) 0x81, 0x02, // INPUT (Data,Var,Abs) //HAT 0x09, 0x39, // USAGE (Hat switch) 0x15, 0x01, // LOGICAL_MINIMUM (1) 0x25, 0x08, // LOGICAL_MAXIMUM (8) 0x35, 0x00, // PHYSICAL_MINIMUM (0) 0x46, 0x0e, 0x01, // PHYSICAL_MAXIMUM (270) 0x65, 0x14, // UNIT (Eng Rot:Angular Pos) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x01, // REPORT_COUNT (1) 0x81, 0x02, // INPUT (Data,Var,Abs) //Buttons 0x05, 0x09, // USAGE_PAGE (Button) 0x19, 0x01, // USAGE_MINIMUM (Button 1) 0x29, 0x40, // USAGE_MAXIMUM (Button 64) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x40, // REPORT_COUNT (64) 0x55, 0x00, // UNIT_EXPONENT (0) 0x65, 0x00, // UNIT (None) 0x81, 0x02, // INPUT (Data,Var,Abs) //LEDs 0x85, 0x02, // REPORT_ID (2) 0x05, 0x08, // USAGE_PAGE (LEDs) 0x09, 0x4B, // USAGE (Generic Indicator) 0x95, 0x40, // REPORT_COUNT (16) 0x91, 0x02, // OUTPUT (Data,Var,Abs) 0xc0, // END_COLLECTION //LCD Displays 0x05, 0x14, // USAGE_PAGE (Alphnumeric Display) 0x09, 0x01, // USAGE (Alphanumeric Display) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0xa1, 0x02, // COLLECTION (Logical) 0x09, 0x32, // USAGE (Cursor Position Report) 0xa1, 0x02, // COLLECTION (Logical) 0x85, 0x04, // REPORT_ID (4) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x01, // REPORT_COUNT (1) 0x25, 0x13, // LOGICAL_MAXIMUM (19) 0x09, 0x34, // USAGE (Column) 0xb1, 0x22, // FEATURE (Data,Var,Abs,NPrf) 0x25, 0x03, // LOGICAL_MAXIMUM (3) 0x09, 0x33, // USAGE (Row) 0x91, 0x22, // OUTPUT (Data,Var,Abs,NPrf) 0xc0, // END_COLLECTION 0x09, 0x2b, // USAGE (Character Report) 0xa1, 0x02, // COLLECTION (Logical) 0x85, 0x05, // REPORT_ID (5) 0x95, 0x14, // REPORT_COUNT (20) 0x26, 0xFF, 0x00, // LOGICAL_MAXIMUM (255) 0x09, 0x2c, // USAGE (Display Data) 0x92, 0x02, 0x01, // OUTPUT (Data,Var,Abs,Buf) 0xc0, // END_COLLECTION 0x09, 0x24, // USAGE (Display Control Report) 0x85, 0x06, // REPORT_ID (6) 0x95, 0x01, // REPORT_COUNT (1) 0x91, 0x22, // OUTPUT (Data,Var,Abs,NPrf) 0xc0, // END_COLLECTION //LED Displays 0x05, 0x14, // USAGE_PAGE (Alphnumeric Display) 0x09, 0x01, // USAGE (Alphanumeric Display) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0xa1, 0x02, // COLLECTION (Logical) 0x09, 0x2b, // USAGE (Character Report) 0xa1, 0x02, // COLLECTION (Logical) 0x85, 0x07, // REPORT_ID (7) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x28, // REPORT_COUNT (40) 0x26, 0xFF, 0x00, // LOGICAL_MAXIMUM (255) 0x09, 0x2c, // USAGE (Display Data) 0x92, 0x02, 0x01, // OUTPUT (Data,Var,Abs,Buf) 0xc0, // END_COLLECTION //Other DATA 0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop) 0x09, 0x01, // USAGE (Vendor Usage 1) 0xa1, 0x01, // COLLECTION (Application) 0x85, 0x08, // REPORT_ID (8) 0x09, 0x01, // USAGE (Vendor Usage 1) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x27, 0xff, 0xff, 0x00, 0x00, // LOGICAL_MAXIMUM (65535) 0x75, 0x10, // REPORT_SIZE (16) 0x95, 0x0A, // REPORT_COUNT (10) 0x91, 0x82, // OUTPUT (Data,Var,Abs,Vol) 

تتم معالجة الإخراج في دالة int8_t الثابتة CUSTOM_HID_OutEvent_FS (uint8_t event_idx ، uint8_t state) ، والتي ، بشكل افتراضي ، موجودة في usbd_custom_hid_if.c.

ثابت int8_t CUSTOM_HID_OutEvent_FS ()
 static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state) { /* USER CODE BEGIN 6 */ uint8_t dataReceiveArray[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE]; USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef*)hUsbDeviceFS.pClassData; for (uint8_t i = 0; i < USBD_CUSTOMHID_OUTREPORT_BUF_SIZE; i++) { dataReceiveArray[i] = hhid->Report_buf[i]; } if (dataReceiveArray[0] == 2) //report ID 2 leds { //  Report id == 2,   -     dataReceiveArray[1 + N], ,  LED } if (dataReceiveArray[0] == 4) //report ID 4 cursor position { //  Report id == 4,   -,     LCD } if (dataReceiveArray[0] == 5) //report ID 5 display data { //  Report id == 5,   -,     USB  LCD } //   ,   ID     return (USBD_OK); /* USER CODE END 6 */ } 


يبقى فقط لكتابة برنامج على جهاز كمبيوتر يرسل التقارير اللازمة لتوجيه العروض. ومع ذلك ، للتحقق من رمز MK ، يعد برنامج رائع من ST: USB HID Demonstrator مناسبًا. يسمح لك بإرسال تقارير من كمبيوتر شخصي مع أي محتوى.


اختبار عرض الصمام

في هذه المرحلة ، لقد انتهيت حتى الآن. وليس من المعروف ما إذا كنت سأبدأ من جديد.

لعبت في أجهزة المحاكاة أكثر إثارة للاهتمام من لوحة المفاتيح. ولكن ليس كثيرًا بحيث كان هناك تأثير واو مباشر. لوحة المفاتيح ، يبدو أيضا مثل لوحة التحكم. لكن السيطرة على محاور عصا التحكم ، على الأقل ، غير عادية. يشعر وكأنه رائد فضاء. صحيح ، هناك حاجة إلى بدلة فضاء لغمر كامل.

آمل أن تكونوا مهتمين. الأخطاء المطبعية والأخطاء والأوهام موجودة. يمكن لأولئك الذين يريدون حفر أعمق في رمز نرى هنا .

التحيات

Source: https://habr.com/ru/post/ar434854/


All Articles