في هذه المقالة سأخبرك كيف:- إنشاء مشروع في STM32CubeMX وإعداد أجهزة ضبط الوقت لالتقاط الإشارات الخارجية.
- فك شفرة إشارة PPM من وحدة تحكم طراز الطائرة.
- اجعل جهاز الواجهة البشرية على STM32 واكتب واصف تقرير HID.
- تطير في محاكاة على سباقات quadrocopter. :)
مقدمة
في الآونة الأخيرة ، اكتسبت سباقات FPV على quadrocopters من الدرجة 250 (FPV - First Person View) شعبية متزايدة. الرقم 250 يعني المسافة بين محاور المحركات قطريًا ، وهي نموذجية للمروحيات الصغيرة القابلة للمناورة. هذه الأجهزة مبنية على إطارات كربون متينة تتحمل السقوط والتصادمات. يتم وضع المراوح التي يبلغ قطرها 5-6 بوصات مع خطوة كبيرة (زاوية ميل الشفرات) على محركات قوية للقيام بالرحلة الأكثر ديناميكية. يتم إرسال الصورة من كاميرا الفيديو التناظرية بتردد 5.8 جيجا هرتز إلى الشاشة أو نظارات الفيديو الخاصة بالطيار. نظرًا لأن الإرسال الرقمي عبر WiFi يخلق تأخيرًا طويلاً (200-300 مللي ثانية) ، يتم بث الفيديو دائمًا على قناة تناظرية. لتسجيل مقاطع مذهلة ، يتم وضع كاميرات الحركة على متن الطائرة (GoPro ، Mobius ، SJcam ، Xiaomi Yi ، إلخ).فيما يلي بعض مقاطع الفيديو المثيرة حول مروحيات FPV:
قبل بناء جهاز quadrocopter الصغير الخاص بي ، أردت أن أطير في جهاز محاكاة وأرى ما إذا كنت مهتمًا بسباقات FPV. للتدريب ، محاكي FPV FreeRider مناسب تمامًا . إنه غير مكلف ، ولديه نسخة تجريبية مجانية ، ووفقًا للطيارين ذوي الخبرة ، يقلد بدقة دقيقة آليات الطيران الحقيقية.يمكنك التحكم في الطائرة في جهاز المحاكاة من لوحة المفاتيح أو من عصا التحكم. لوحة المفاتيح غير مناسبة للتجريب ، حيث يمكن للأزرار فقط نقل قيمة منفصلة (يتم الضغط على الزر / عدم الضغط عليه) ومن المستحيل نقل القيم الوسيطة المتغيرة بسلاسة. عصا التحكم من وحدات تحكم الألعاب بالعصي التناظرية هي أفضل بكثير ، ولكنها تحتوي على عصا صغيرة جدًا ، والتي لا تسمح لك بالتحكم في الجهاز بدقة كافية. الخيار المثالي لمحاكاة هو وحدة تحكم طراز الطائرة المتصلة بجهاز كمبيوتر من خلال محول خاص ، وبفضله يرى نظام التشغيل أنه عصا التحكم.كان لدي بالفعل طائرة رباعية ، تم تجميعها للرحلات الترفيهية والتصوير الفوتوغرافي ، ولكنها كبيرة وثقيلة جدًا للسباق. وفقًا لذلك ، كان هناك جهاز تحكم عن بعد - Turnigy 9X (في الرسم التوضيحي الأول). على الجانب الخلفي ، يحتوي على موصل لتوصيل محول يتم إخراج إشارة PPM إليه. هذه الإشارة عبارة عن نبضة قصيرة بفواصل من 1 إلى 2 مللي ثانية ، تتوافق مدتها مع موضع عناصر التحكم (مزيد من المعلومات عنها في القسم الخاص بفك التشفير).يجب أن أقول إن المحولات لتوصيل جهاز التحكم عن بعد من PPM إلى USB تم إصدارها منذ فترة طويلة ويتم بيعها. يمكن شراء محول مماثل في عامل محرك الأقراص المحمول مقابل 5 دولارات في الصين أو أغلى قليلاً في المتاجر الروسية. هناك أيضًا مشاريع محولات مفتوحة المصدر على وحدات تحكم AVR.ولكن رغبتي بشدة بالطيران على الفور جاءت إلي في وقت متأخر من المساء ، عندما تم إغلاق جميع متاجر طرازات الطائرات في موسكو بالفعل. لم أكن أرغب في الانتظار في الصباح ، لم يكن هناك وقت لتسميم ولحام اللوحة باستخدام ATmega ، لذلك قررت عمل محول PPM-USB على لوحة STM32F3Discovery ، التي كانت لفترة طويلة خاملة وكانت في متناول اليد.ما هو المطلوب
لإنشاء محول ، ستحتاج إلى:لوحات التصحيح Discovery مكلفة للغاية. تكلف F3 الموصوفة حوالي 20 دولارًا وقدراتها زائدة عن الحاجة لمثل هذا المشروع البسيط. لقد استخدمته لأنه في وقت كتابة هذا كان اللوحة الوحيدة مع USB الأجهزة التي وجدتها في المنزل. بالنسبة لأولئك الذين لم يشتروها بعد ، يمكنني أن أنصحك بالاهتمام باللوحات المصغرة مع وحدة التحكم STM32F103C8T6 من AliExpress مقابل 3 دولارات ومبرمج ST-Link من هناك. لا تختلف العملية عن تلك الموضحة في المقالة. ما لم يكن من الضروري اختيار وحدة تحكم أخرى في البداية ، حدد وجود مرنان كوارتز واستخدم دبوسًا مختلفًا قليلاً.إنشاء مشروع في STM32CubeMX
STM32Cube عبارة عن حزمة تم تطويرها بواسطة STMicroelectronics لتسهيل الحياة على مطوري أجهزة STM32. وهو يتألف من أداة رسومات CubeMX وبرامج تشغيل HAL ومكونات البرامج الوسيطة.CubeMX هي أداة لإنشاء المشاريع وتهيئة الأجهزة الطرفية. للبدء ، ما عليك سوى تحديد وحدة التحكم ، وتحديد مربعات الوحدات المطلوبة ، وتحديد الأوضاع المطلوبة في القائمة وإدخال القيم المطلوبة في عدة حقول. سيقوم CubeMX بإنشاء المشروع وربط المكتبات اللازمة به. سيكتب مطور الجهاز فقط منطق التطبيق.السائقين هال(طبقة تجريد الأجهزة) هي واجهة برمجة تطبيقات للعمل مع الوحدات النمطية والأجهزة الطرفية لوحدة التحكم الدقيقة. يسمح لك HAL بفصل الطبقة العليا من التطبيق التي ينشئها المطور من العمل مع السجلات وجعل رمز البرنامج محمولاً قدر الإمكان بين عائلات وحدة التحكم STM32.تتضمن الوسيطة أو المكونات الوسيطة نظام تشغيل FreeRTOS ومكتبة للعمل مع نظام الملفات ومكتبات USB و TCP / IP وما إلى ذلك.يبدو أنه من الممكن الآن "البرمجة باستخدام الماوس" بدلاً من كتابة وحدات البت يدويًا إلى السجلات. لكن البساطة والراحة لا تلغي حقيقة أنك بحاجة إلى دراسة الوثائق ، خاصة في الحالات التي تحتاج فيها إلى الضغط على السرعة القصوى أو الحد الأدنى من استهلاك الطاقة أو استخدام الأجهزة الطرفية في الأوضاع غير القياسية. STM32Cube لا يغطي حتى الآن 100 ٪ من جميع إمكانات وحدة التحكم الدقيقة ، ولكنه يقترب من ذلك. تقوم شركة STMicroelectronics بتحديث المكعب من وقت لآخر ، وتمديد الوظائف ، وإصلاح الأخطاء. لذلك ، إذا كان لديك Cube مثبتًا بالفعل ، فتحقق من أنه أحدث إصدار.الإعدادات الأولية
يبدأ العمل مع المشروع باختيار وحدة التحكم. قم بتشغيل STM32CubeMX ، انقر فوق مشروع جديد . في علامة التبويب MCU Selector ، يمكنك تحديد وحدة التحكم المطلوبة من عوامل التصفية. نظرًا لأن لدينا لوحة تصحيح نهائية ، في علامة التبويب Board Selector ، نجد STM32F3Discovery . بعد اختيار لوحة ، ستظهر صورة وحدة التحكم مع دبابيس موقعة وموقعة.توجد أربع علامات تبويب كبيرة في الجزء العلوي من النافذة:Pinout - لتهيئة وظائف السن والضبط المسبق للوحدات. نحن على ذلك الآن.تكوين الساعة - إعداد الساعة ، PLL ، المقسمات.التكوين - تكوين أكثر تفصيلا للأجهزة الطرفية والبرامج الوسيطة.حاسبة استهلاك الطاقة - حساب الطاقة التي تستهلكها وحدة التحكم الدقيقة.
في القائمة اليسرى في علامة التبويب Pinout ، يمكنك استخدام الأجهزة الطرفية المطلوبة ، وعلى دائرة التحكم ، حدد وظيفة لأي من مخرجات وحدة التحكم الدقيقة. بعض العناصر على اليسار هي أيقونات تحذير. هذا يعني أن الوحدات (في هذه الحالة ADC ، DAC ، OPAMP2 ، RTC) يمكن استخدامها الآن بشكل غير كامل ، لأن بعض مخرجاتها مشغولة بالفعل بوظائف أخرى.يتم تمييز المسامير المكونة باللون الأخضر في دائرة التحكم. نظرًا لأننا لم نختار وحدة تحكم عارية بدون ربط ، ولكن لوحة تصحيح أخطاء F3-Discovery الجاهزة ، فقد تم تكوين بعض المخرجات بالفعل ، على سبيل المثال ، زر أزرق متصل بـ PA0 ، ومصابيح LED إلى PE8 ... 15. يتم تمييز تلك الدبابيس التي تتصل بها بعض الأجهزة الخارجية على Discovery باللون البرتقالي ، ولكن لم يتم تكوين الوحدات الطرفية الخاصة بها بعد. كما ترون ، هذه دبابيس لـ USB ، مرنانات كوارتز ، SPI و I2C للجيروسكوب والبوصلة ، DP و DM لـ USB. لا تُستخدم الاستنتاجات الرمادية حاليًا ، ويمكننا تطبيق أي منها لأغراضنا.اختيار الإدخال
سنقوم بالتقاط مدة النبضات ، لذلك يجب توصيل المدخلات بإحدى قنوات أي جهاز توقيت. بالإضافة إلى ذلك ، فإن مستوى الإشارة مع Turnigy 9X ليس 3.3V ، مثل جهد الإمداد لـ STM32 ، ولكن 5V. نحن كسالى للغاية في لحام مقسم الجهد ، لذلك تحتاج إلى اختيار إدخال يمكن أن يتحمل 5V (تسمى هذه المدخلات متسامحة 5V). يمكن العثور على الدبابيس المناسبة في ورقة البيانات على STM32F303VCT6 في قسم Pinouts ووصف الدبوس . هناك العديد من المؤقتات في STM32F3 ، وهي مبعثرة عبر جميع الدبابيس تقريبًا. الخيار المناسب هو PC6. يمكن أن يتحمل 5 فولت ويقع في الزاوية اليسرى السفلية من اللوحة ، بجوار GND. قم بتعيين القناة الأولى للعداد الثالث TIM3_CH1 لهذا الدبوس.إعداد الساعة
لكي يعمل USB ، يجب أن يتم تسجيل الميكروكونترولر بتردد ثابت للغاية ، وهذا هو السبب في أن جميع أجهزة USB تقريبًا تحتوي على رنانات كوارتز. استقرار التردد لمولد RC المدمج ليس كافيًا لـ USB. ولكن على لوحة STM32F3 Discovery ، كان المطورون لسبب ما جشعين ولم يضعوا الكوارتز. ومع ذلك ، إذا كنت تدرس بعناية الدائرة ، يمكنك أن ترى أن إشارة MCO متصلة بإدخال PF0-OSC_IN ، حيث يجب توصيل الكوارتز . يأتي من مبرمج ST-Link على نفس اللوح الذي يوجد فيه الكوارتز. يقول دليل المستخدم الخاص بـ F3 Discovery (UM1570) في قسم OSC Clock أنه يتم إرسال 8 ميجاهرتز إلى هذا الخط.
وبالتالي ، يتم التحكم في الميكروكونترولر من مصدر خارجي. يسمى هذا الوضع تجاوز. في قائمة الإعدادات الطرفية في قسم RCC ، لتسجيل ساعة عالية السرعة ، حدد مصدر ساعة BYPASS .
قبل المتابعة إلى إعداد ساعة أكثر تفصيلاً ، نلاحظ في القائمة الطرفية أن الميكروكونترولر سيكون بمثابة جهاز USB.
يمكنك الآن الانتقال إلى علامة التبويب الكبيرة التالية - تكوين الساعة . هنا سنرى رسمًا بيانيًا ضخمًا يوضح إشارات الساعة الموجودة في وحدة التحكم الدقيقة ، من أين تأتي ، وكيف تتفرع ، تتضاعف وتقسم. باللون الأصفر ، أبرزت تلك المعلمات التي يجب ملاحظتها.
تحقق من أن تردد الإدخالتردد الإدخال هو 8 ميجا هرتز.قمنا بتعيين مفتاح PLL Source Mux على HSE (عالي السرعة خارجي) على مدار الساعة من مصدر خارجي بدلاً من مصدر داخلي.PLL - حلقة قفل الطور ، أو PLL - حلقة قفل الطور ، تعمل على مضاعفة التردد الخارجي عدة مرات. اضبط مضاعف PLLMul على 9. ثم سنصل إلى أقصى تردد ممكن لـ STM32F303-72 MHz. يجب أن يكونSystem Clock Mux في وضع PLLCLK بحيث يتم ضرب تردد الساعة في PLL.بالنسبة لوحدة USB ، هناك حاجة إلى 48 ميجاهرتز ، لذا ضع فاصل 1.5 أمام USB.انتبه إلى الترددالساعات الموقت APB1 على الجانب الأيسر من الدائرة. يذهب إلى الموقتات ومفيد لنا في المستقبل.إذا تم تكوين أي تردد بشكل غير صحيح ، أو تجاوز الحد الأقصى للقيمة الممكنة أو كانت المفاتيح في وضع غير صالح ، فسيقوم CubeMX بتمييز هذا المكان باللون الأحمر.إعداد المؤقت
لقياس مدة النبض ، سنبدأ موقت TIM3 في وضع التقاط الإدخال. في الدليل المرجعي ، تحت قسم المؤقتات للأغراض العامة (TIM2 / TIM3 / TIM4) ، يوجد رسم تخطيطي يوضح تشغيل المؤقتات . باستخدام الألوان ، قمت بتمييز الإشارات والسجلات المستخدمة في وضع التقاط الإدخال.
تدخل إشارة الساعة المميزة باللون الأخضر باستمرار سجل عداد CNT وتزيد قيمته بمقدار 1 في كل دورة ساعة. في مقسم Prescaler PSC ، قد ينخفض تردد الساعة للحصول على عدد أبطأ. يتمإدخال إشارة خارجية إلى TIMx_CH1 . كاشف الحوافيتعرف على حواف إشارة الإدخال - التحولات من 0 إلى 1 أو من 1 إلى 0. عند تسجيل الحافة ، يرسل أمرين مميزين باللون الأصفر:- أمر لكتابة قيمة عداد CNT إلى تسجيل الالتقاط / المقارنة 1 (CCR1) ومكالمة المقاطعة CC1I .- أمر لوحدة التحكم في وضع Slave ، يتم من خلاله إعادة تعيين قيمة CNT إلى 0 ويبدأ العد التنازلي مرة أخرى.فيما يلي توضيح للعملية في مخطط زمني:
عند حدوث مقاطعة ، سنقوم بتنفيذ إجراءات بقيمة تم التقاطها. إذا كانت نبضات الإدخال تأتي كثيرًا ، وكانت الإجراءات التي تحدث في معالج المقاطعة طويلة جدًا ، فيمكن استبدال قيمة CCR1 قبل أن نقرأ الإجراء السابق. في هذه الحالة ، تحتاج إلى التحقق من علامة Overcapture أو تطبيق الوصول المباشر للذاكرة (DMA) عندما تملأ البيانات من CCR1 تلقائيًا الصفيف المحضر في الذاكرة. في حالتنا ، تستغرق أقصر نبضة مدة 1 مللي ثانية ، وسيكون معالج المقاطعة بسيطًا وقصيرًا ، لذلك لا تقلق بشأن الكتابة فوقها. الذهابإلى Pinout التبويب وتعيين TIM3 الموقت في ملحقات القائمة .
وضع الرقيق: وضع إعادة الضبط- يعني أنه في بعض الأحداث سيتم إعادة ضبط المؤقت إلى 0.مصدر التشغيل: TI1FP1 - الحدث المستخدم لإعادة ضبط المؤقت وبدء تشغيله هو حافة الإشارة الملتقطة من إدخال TI1.ClockSource: الساعة الداخلية - يتم تسجيل المؤقت من المولد الداخلي لوحدة التحكم الدقيقة.القناة 1: الوضع المباشر لالتقاط الإدخال - فترات التقاط من القناة الأولى في تسجيل CCR1.في علامة التبويب التكوين الكبيرة التالية ، سنقوم بإعداد إعدادات مؤقت إضافية.Prescaler هو مقسم مؤقت. إذا كان الرقم 0 ، يتم أخذ التردد مباشرة من ساعة ساعة حافلة APB - 72 ميجاهرتز. إذا كان ما قبل المكبر هو 1 ، يتم تقسيم التردد على 2 ويصبح 36 ميجاهرتز. اضبط المقسوم على 71 بحيث يتم تقسيم التردد على 72. ثم سيكون تردد المؤقت 1 ميجاهرتز وسيتم قياس الفواصل بدقة 1 ميكروثانية.فترة العداد - قم بتعيين الحد الأقصى الممكن لقيمة 16 بت 0xFFFF. الفترة مهمة لتوليد فترات زمنية ، على سبيل المثال ، ل PWM. لكن الفترة ليست مهمة لالتقاط الإشارات ؛ سنجعلها معروفة بأنها كبيرة لأي نبضات إدخال.اختيار القطبية: حافة السقوط - سيتم التقاط قيم المؤقت على حافة السقوط لإشارة الإدخال.في علامة التبويب إعدادات NVIC ، ضع داوالمقاطعة العالمية لـ TIM3 ، بحيث تولد الأحداث المتعلقة بالساعة الثالثة مقاطعة.إعداد جهاز USB
لقد لاحظنا بالفعل أن وحدة التحكم ستكون جهاز USB. نظرًا لأن ذراع التحكم ينتمي إلى فئة أجهزة HID ، في القائمة Middlewares -> USB_DEVICE ، حدد Class For FS IP: فئة جهاز واجهة بشرية (HID) . ثم سيقوم CubeMX بتوصيل المكتبات الخاصة بجهاز HID إلى المشروع.
دعنا نذهب إلى إعدادات USB_DEVICE في علامة التبويب التكوين في قسم Middlewares :بائع ID و معرف المنتج هما معرفات 16 بت التي تنفرد بها كل نموذج من جهاز USB. يتوافق VID مع الشركة المصنعة للجهاز ، ويقوم كل مصنع بتعيين PID ، مسترشداً باعتباراتهم الخاصة. لم أتمكن من العثور على القائمة الرسمية لـ VID و PID ، لقد وجدت فقط قاعدة المعرّف المدعومة من قبل المتحمسين. للحصول على معرف البائع الخاص بك ، تحتاج إلى الانتقال إلى منتدى منفذي USB على usb.org ودفع بضعة آلاف من الدولارات. يمكن للشركات الصغيرة أو مطوري البرامج مفتوحة المصدر الذين لا يمكنهم تحمل VID الخاص بهم طلب الشركة المصنعة لشريحة USB وتتلقى رسميًا زوج VID / PID لمشروعهم. يتم تقديم هذه الخدمة ، على سبيل المثال ، من قبل FTDI أو معامل السيليكون.إذا قمت بتوصيل جهازين بنفس VID / PID ، ولكن من نوع مختلف (على سبيل المثال ، أحدهما جهاز HID والآخر هو Mass Storage) ، سيحاول نظام التشغيل تثبيت نفس برنامج التشغيل لهم ، وواحد على الأقل لن يعمل. هذا هو السبب في أن أزواج VID / PID لنماذج الأجهزة المختلفة يجب أن تكون فريدة.نظرًا لأننا لا نصنع جهازًا لأنفسنا ، فلن نبيعه ونوزعه ، وسنترك VID 0x0483 ، المقابل لـ STMicroelectronics ، وسنتوصل إلى PID الخاص بنا. بشكل افتراضي ، يقدم CubeMX PID 0x5710 لجهاز HID. استبدلها ، على سبيل المثال ، بـ 0x57FF.استبدال سلسلة المنتج مع STM32 PPM-USB محول. سيظهر هذا الاسم في قائمة الأجهزة في لوحة تحكم Windows. لن نقوم بتغيير الرقم التسلسلي (S \ N) بعد.عندما يكتشف Windows أنه يكتشف جهازًا يحتوي على مجموعة من VID و PID و S \ N لم يراها من قبل ، يقوم النظام بتثبيت برنامج التشغيل المناسب له. إذا تم استخدام تركيبة VID و PID و S \ N بالفعل ، فإن Windows يقوم تلقائيًا باستبدال برنامج التشغيل المستخدم سابقًا. يمكنك رؤية ذلك ، على سبيل المثال ، عند توصيل محرك الأقراص المحمول بـ USB. يستغرق الاتصال والتثبيت في المرة الأولى بعض الوقت. في الاتصالات اللاحقة ، يبدأ محرك الأقراص في العمل على الفور تقريبًا. ومع ذلك ، إذا قمت بتوصيل مثيل آخر لمحرك أقراص فلاش من نفس الطراز ، ولكن برقم تسلسلي مختلف ، فسيقوم النظام بتثبيت برنامج تشغيل جديد له ، على الرغم من أنه يحتوي على نفس VID و PID.سأشرح لماذا هذا مهم. إذا قمت بإنشاء ماوس USB على جهاز STM32 باستخدام VID و PID و S \ N ، وقمت بتوصيله بالكمبيوتر ، ثم قمت بعمل ذراع تحكم USB دون تغيير VID و PID و S \ N ، فإن Windows سينظر إلى الجهاز الجديد باعتباره ماوسًا بالفعل المستخدمة في النظام ، ولن يتم تثبيت برنامج تشغيل عصا التحكم. وفقًا لذلك ، لن تعمل عصا التحكم. لذلك ، إذا كنت تريد تغيير نوع جهازك ، وترك VID / PID دون تغيير ، فتأكد من تغيير الرقم التسلسلي الخاص به.إنشاء مشروع IDE
آخر الإعدادات التي تحتاج إلى القيام بها هي إعدادات إنشاء المشروع. يتم ذلك من خلال Project -> Settings ... هناك سنقوم بتعيين الاسم ومجلد الوجهة و IDE المطلوب ، والذي بموجبه سيقوم CubeMX بإنشاء المشروع. لقد اخترت MDK-ARM V5 ، لأنني أستخدم Keil uVision 5. في علامة التبويب Code Generator ، يمكنك تحديد مربع الاختيار نسخ ملفات المكتبة الضرورية فقط حتى لا تزدحم المشروع بالملفات غير الضرورية.اضغط على زر المشروع -> إنشاء رمز . سيعمل CubeMX على إنشاء مشروع برمز يمكن فتحه في Keil uVision وتجميعه ووميضه بدون إعدادات إضافية. في ملف main.c في الوظيفة الرئيسية (باطلة)تم إدراج الوظائف بالفعل لتهيئة الساعة والمنافذ والمؤقت و USB. يتم تكوين وحدات التحكم الدقيقة فيها ، وفقًا للأوضاع التي قمنا بتعيينها في CubeMX.
في المدونة ، غالبًا ما يتم العثور على منشآت من هذا النوع:
(...)
من المفترض أن يقوم المستخدم بتضمين كودهم في هذه الأقسام. إذا تم تمكين خيار الاحتفاظ بكود المستخدم عند إعادة التوليد في إعدادات مشروع CubeMX ، فلن تتم الكتابة فوق الكود المرفق بين هذه السطور أثناء الجيل الثانوي لمشروع موجود. لسوء الحظ ، يتم حفظ الأقسام التي تم إنشاؤها بواسطة CubeMX فقط. سيتم فقد الأقسام / * رمز المستخدم * / الذي أنشأه المستخدم. لذلك ، إذا أردت بعد كتابة الرمز في IDE العودة إلى CubeMX وإنشاء المشروع مرة أخرى باستخدام الإعدادات الجديدة ، أوصي بعمل نسخة احتياطية من المشروع.في إعدادات البرامج الثابتة في uVision ( Flash -> Configure Flash Tools ) أنصحك بتمكين خيار إعادة الضبط بعد الفلاشبحيث يبدأ الميكروكونترولر مباشرة بعد الوميض. بشكل افتراضي ، يتم تعطيله ، وبعد كل وميض ، يجب عليك الضغط على زر إعادة الضبط على اللوحة.
فك تشفير PPM
PPM - تعديل موضع النبض - طريقة لتشفير الإشارات المرسلة ، واسعة الانتشار في إلكترونيات طراز الطائرات. هو سلسلة من النبضات ، والفترات الزمنية التي تتوافق مع القيم العددية المرسلة.وفقًا لهذا البروتوكول ، ترسل وحدة التحكم المعلومات إلى وحدة الإرسال اللاسلكية ، والتي يتم إدخالها في وحدة التحكم في الخلف. يمكن للعديد من أجهزة الاستقبال التي يتم وضعها على متن المروحية إرسال إشارات التحكم لوحدة التحكم في الطيران عبر PPM. بالإضافة إلى ذلك ، تحتوي أي وحدة تحكم تقريبًا على موصلات لتوصيل وحدة تحكم ثانية في وضع المدرب - الطالب ولتوصيل وحدة التحكم بمحاكي ، والذي يستخدم أيضًا PPM.نكتب إشارة من إخراج محاكاة Turnigy 9X مع محلل منطقي:يقوم كل تسلسل بترميز الحالة الحالية لعناصر التحكم على جهاز التحكم عن بعد. عادة ما تتوافق القيم الأربع الأولى (تسمى أيضًا القنوات) مع موضع العصي التناظرية ، والقيم اللاحقة لموضع مفاتيح التبديل أو مقاييس فرق الجهد.يتوافق الحد الأدنى لموضع التحكم مع الفاصل الزمني 1000 ،s ، والحد الأقصى - 2000 ،s ، والموضع المتوسط - 1500 μs. يتم فصل دفقات النبضات أو الإطارات بفواصل زمنية أطول ويتبعها بفترة تتراوح من 20-25 مللي ثانية.دعونا نلقي نظرة فاحصة على الإشارة:كما ترون ، هناك ثلاثة أصابع في الوضع المحايد (1 ، 3 ، 4) ، وواحدة في الوضع المتطرف (2). ثلاثة مفاتيح تبديل مغلقة (5 ، 6 ، 7) ، والأخير في وضع التشغيل (8). يجب أن يلتقط الميكروكونترولر ، الذي يعمل كمحول ، مثل هذا التسلسل ، ويضيف القيم إلى الصفيف ويرسله عبر USB كأمر من عصا التحكم. لنكتب مفكك تشفير تسلسل النبض.قطع الالتقاط
بعد التهيئة في main.c ، قبل الحلقة الرئيسية أثناء التكرار ، ابدأ مؤقت TIM3 في وضع التقاط Input Capture من القناة 1 ، مع إنشاء مقاطعات الالتقاط. للقيام بذلك ، استخدم الوظيفة المقابلة من HAL:HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1);
بنية htim3 المعلنة في main.c هي معالج مؤقت TIM3 ، الذي يحتوي على جميع الهياكل والمتغيرات المرتبطة بالمؤقت: معلمات التهيئة ، والمؤشرات إلى جميع سجلات المؤقت (قيمة العداد ، والمقسم ، وجميع الإعدادات ، وعلامات المقاطعة) ، المؤشر على معالج DMA يعمل مع هذا المؤقت ، إلخ. لا يحتاج المطور إلى البحث عن البتات التي يكون فيها التسجيل مسؤولاً عن ما يتم تعيينها يدويًا وإعادة تعيينها. يكفي لتمرير المعالج إلى دالة HAL. ستقوم مكتبات HAL بالباقي بنفسها.يتم وصف مبادئ بنية HAL بمزيد من التفاصيل في وصف مستند برامج تشغيل STM32F3xx HAL .(UM1786). وتجدر الإشارة إلى أن مكتبات HAL نفسها موثقة جيدًا. لفهم كيفية عمل HAL للمؤقت وكيفية استخدامه ، يمكنك قراءة التعليقات في ملفي stm32f3xx_hal_tim.h و stm32f3xx_hal_tim.c .يتم استدعاء معالج TIM3_IRQHandler لكل مقاطعة ينشئها جهاز ضبط الوقت TIM3 . وهو موجود في ملف stm32f3xx_it.c ، بدوره ، يتم استدعاء معالج HAL_TIM_IRQHandler ، القياسي لجميع أجهزة ضبط الوقت ، ويتم تمرير مؤشر إلى بنية htim3 إليه.void TIM3_IRQHandler(void)
{
HAL_TIM_IRQHandler(&htim3);
}
وإذا نظرنا داخل HAL_TIM_IRQHandler ملف stm32f3xx_hal_tim.c ، ونحن نرى معالج الكبير الذي يتحقق أعلام المقاطعة لأسباب توقيت إعادة النداء وظيفة ويزيل العلم بعد التنفيذ. إذا حدث حدث التقاط ، فإنه يستدعي وظيفة HAL_TIM_IC_CaptureCallback . تبدو هكذا:__weak void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
}
وهذا يعني أن نتمكن من تجاوز هذه الوظيفة في main.c . لذلك ، قم بإدراج رد الاتصال هذا قبل وظيفة int main (void) :void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
};
أود أن أرى كيف يتم تنفيذ المقاطعة. أضف إليه نظرة سريعة على أحد الاستنتاجات:void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_SET);
__nop();__nop();__nop();__nop();__nop();__nop();
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_RESET);
};
تمت تهيئة دبوس PE8 بالفعل كمخرج. بين التبديل وإيقاف التشغيل ، يتم إدراج تعليمات __nop () ، مما يشكل تأخيرًا لدورة ساعة واحدة. هذا لمنع محلل المنطق الصيني 8 دولارات الذي يعمل عند 24 ميجاهرتز من فقد نبض قصير جدًا من متحكم يعمل عند 72 ميجاهرتز. الآن قم بتجميع مشروع المشروع -> بناء الهدف واطلب وحدة تحكم الفلاش -> تنزيل . سنقوم بتوصيل PPM من جهاز التحكم عن بعد إلى PC6 ، ونرى ما يحدث على PC6 و PE8 مع المحلل.يتم استدعاء رد الاتصال حقًا في اللحظات المناسبة - مباشرة بعد انتقال إشارة الإدخال من 1 إلى 0. لذلك ، تم عمل كل شيء بشكل صحيح.التقاط ومعالجة البيانات الملتقطة
سنقوم بتعديل رد الاتصال بحيث يضيف كل قيمة تم التقاطها إلى المخزن المؤقت الذي تم التقاطه بدون تغيير. إذا كان جهاز ضبط الوقت يلتقط قيمة كبيرة جدًا (أكثر من 5000 ،s) ، فهذا يعني أنه تم تسجيل توقف مؤقت ، وتم استلام الحزمة بالكامل ويمكن معالجتها. تتم إضافة القيم التي تمت معالجتها إلى مصفوفة rc_data المكونة من 5 عناصر. في الأربعة الأولى ، يتم تخفيض مواضع العصا إلى النطاق [0 ؛ 1000] ، في الخامسة ، يتم تعيين البتات الفردية وفقًا لمفاتيح التبديل ، والتي سيتم تفسيرها على أنها أزرار ضغط على لوحة الألعاب.uint16_t captured_value[8] = {0};
uint16_t rc_data[5] = {0};
uint8_t pointer = 0;
uint8_t data_ready = 0;
...
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
uint8_t i;
uint16_t temp;
temp = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
if ((temp > 5000) && (!data_ready))
{
pointer = 0;
for (i = 0; i < 4; i++)
{
if (captured_value[i] < 1000)
captured_value[i] = 1000;
else if (captured_value[i] > 2000)
captured_value[i] = 2000;
rc_data[i] = captured_value[i]-1000;
};
rc_data[4] = 0;
if (captured_value[4] > 1500)
rc_data[4] |= (1<<4);
if (captured_value[5] > 1500)
rc_data[4] |= (1<<5);
if (captured_value[6] > 1500)
rc_data[4] |= (1<<6);
if (captured_value[7] > 1500)
rc_data[4] |= (1<<7);
data_ready = 1;
}
else
{
captured_value[pointer] = temp;
pointer++;
};
if (pointer == 8)
pointer = 0;
}
اسمحوا لي أن أشرح لماذا وضعت البتات المقابلة للأزرار ليس في البتات الأربعة السفلى ، ولكن في البتات الخامسة إلى الثامنة. في المحاكي ، من المفترض أن يتم توصيل لوحة ألعاب من Xbox ، حيث يتم استخدام أزرار LB و RB و Start و Back ، ولديهم أرقام من 5 إلى 8.في الحلقة الرئيسية ، سيتم تدوير علامة data_ready باستمرار ، والتي سيتم من خلالها إرسال البيانات إلى الكمبيوتر.while (1)
{
if (data_ready)
{
data_ready = 0;
}
}
للتحقق من كيفية عمل ذلك ، قم بتوصيل جهاز التحكم عن بعد ، وقم بتجميعه وفلاشه مرة أخرى ، ثم ابدأ تصحيح التصحيح -> بدء / إيقاف جلسة تصحيح الأخطاء .فتح نافذة لتتبع المتغيرات مشاهدة -> ووتش ويندوز -> رايتس ووتش 1 وإضافة captured_value و rc_data هناك .نبدأ التصحيح باستخدام الأمر Debug -> Run وفي الوقت الفعلي ، حتى بدون إضافة نقاط توقف ، سنرى كيف تتغير الأرقام بعد العصي.بعد ذلك ، تحتاج إلى إرسال البيانات إلى الكمبيوتر في شكل أمر عصا التحكم.تكوين جهاز HID وإنشاء واصف تقرير HID
USB HID (جهاز الواجهة البشرية) هو فئة من الأجهزة للتفاعل بين الإنسان والحاسوب. وتشمل هذه لوحات المفاتيح والفئران وعصا التحكم ولوحات الألعاب ولوحات اللمس. الميزة الرئيسية لأجهزة HID هي أنها لا تتطلب برامج تشغيل خاصة في أي نظام تشغيل: Windows و OS X و Android وحتى iOS (عبر محول USB-Lightning). يمكن العثور على وصف مفصل في المستند تعريف فئة الجهاز لـ HID . الشيء الرئيسي الذي نحتاج إلى معرفته لإنشاء محول PPM-USB هو ما HID تقرير و هي HID تقرير واصف .يرسل جهاز HID حزم بايت إلى الكمبيوتر بتنسيق محدد مسبقًا. كل حزمة مثل تقرير HID. يقوم الجهاز بإبلاغ الكمبيوتر عن تنسيق البيانات عند توصيله ، وإرسال واصف تقرير HID ، ووصف الحزمة الذي يشير إلى عدد البايتات التي تحتوي عليها الحزمة والغرض من كل بايت وبت في الحزمة. على سبيل المثال ، يتكون تقرير HID من ماوس بسيط من أربعة بايت: يحتوي البايت الأول على معلومات حول الأزرار المضغوطة ، ويحتوي البايتان الثاني والثالث على الحركة النسبية للمؤشر على طول X و Y ، ويحتوي البايت الرابع على دوران عجلة التمرير. يتم تخزين واصف التقرير في ذاكرة وحدة تحكم الجهاز كمجموعة من وحدات البايت.قبل إنشاء واصف ، أود أن أتناول بشكل منفصل المصطلحات. ولايتين شائعة في بيئة اللغة الانجليزية - عصا التحكم و غمبد . عادة ما تسمى كلمة جويستيك بمناور يتم حملها بيد واحدة ومائلة في اتجاهات مختلفة ، وجيمباد هو جهاز بأزرار وعصي يتم حملها بيدين. عادة ما يطلق المستخدمون الناطقون بالروسية على عصا التحكم ذلك ، وآخر. في وصف جهاز HID ، هناك فرق بين عصا التحكم ولوحة الألعاب. تتشابه وحدة التحكم في طراز الطائرة بشكل أكبر في غرضها الوظيفي مع لوحة الألعاب ، لذلك في المستقبل سأستخدم أحيانًا مصطلح "لوحة الألعاب".أنشأنا مشروعًا ، يشير إلى أن الجهاز سيكون بمثابة جهاز واجهة بشرية. هذا يعني أن مكتبة USB HID متصلة بالمشروع وقد تم بالفعل إنشاء واصف الجهاز. وهو موجود في ملف usbd_hid.c ، ويصف تقرير الماوس ويبدو كما يلي:HID_Mouse_Report_Descriptor__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
{
0x05, 0x01,
0x09, 0x02,
0xA1, 0x01,
0x09, 0x01,
0xA1, 0x00,
0x05, 0x09,
0x19, 0x01,
0x29, 0x03,
0x15, 0x00,
0x25, 0x01,
0x95, 0x03,
0x75, 0x01,
0x81, 0x02,
0x95, 0x01,
0x75, 0x05,
0x81, 0x01,
0x05, 0x01,
0x09, 0x30,
0x09, 0x31,
0x09, 0x38,
0x15, 0x81,
0x25, 0x7F,
0x75, 0x08,
0x95, 0x03,
0x81, 0x06,
0xC0, 0x09,
0x3c, 0x05,
0xff, 0x09,
0x01, 0x15,
0x00, 0x25,
0x01, 0x75,
0x01, 0x95,
0x02, 0xb1,
0x22, 0x75,
0x06, 0x95,
0x01, 0xb1,
0x01, 0xc0
};
يستغرق إنشاء واصف تقرير HID يدويًا وقتًا طويلاً للغاية. لتسهيل المهمة ، هناك أداة تسمى HID Descriptor Tool (DT). يمكن لهذا البرنامج إنشاء واصف لجهازك. في الأرشيف معه ، يمكنك العثور على العديد من الأمثلة على واصفات الأجهزة المختلفة.إليك مقالة جيدة جدًا حول إنشاء واصف HID الخاص بك للماوس ولوحة المفاتيح (باللغة الإنجليزية). سأخبرك بالروسية كيف تصنع مقبضًا للألعاب.يجب أن يحتوي تقرير HID الذي تم إرساله بواسطة وحدة التحكم على أربع قيم 16 بت لمحور من العصي التناظرية و 16 قيمة بت واحدة للأزرار. إجمالي 10 بايت. سيبدو المقبض الذي تم إنشاؤه في DT على النحو التالي: 0x05, 0x01,
0x09, 0x05,
0xa1, 0x01,
0x09, 0x01,
0xa1, 0x00,
0x09, 0x30,
0x09, 0x31,
0x15, 0x00,
0x26, 0xe8, 0x03,
0x75, 0x10,
0x95, 0x02,
0x81, 0x02,
0xc0,
0xa1, 0x00,
0x09, 0x33,
0x09, 0x34,
0x15, 0x00,
0x26, 0xe8, 0x03,
0x75, 0x10,
0x95, 0x02,
0x81, 0x02,
0xc0,
0x05, 0x09,
0x19, 0x01,
0x29, 0x10,
0x15, 0x00,
0x25, 0x01,
0x75, 0x01,
0x95, 0x10,
0x81, 0x02,
0xc0
لا يبدو أنه أقل تخويفًا من واصف الماوس. ولكن إذا فهمت ما يعنيه كل سطر ، فقد اتضح أن كل شيء مفهوم ومفهوم تمامًا.يوضح الاستخدام كيفية قيام النظام بتفسير البيانات التي تذهب إلى أبعد من ذلك.هناك الكثير من أنواع الاستخدام ، يتم تصنيفها إلى مجموعات - صفحات الاستخدام. لذلك ، لتحديد استخدام معين ، يجب عليك أولاً الرجوع إلى USAGE_PAGE المقابلة. حول الاستخدام الذي يمكن العثور عليه في مستند Hid Usage Tables . في بداية الواصف ، نشير إلى أن عصا التحكم سيتم وصفها:USAGE_PAGE (عام سطح المكتب)
USAGE (لوحة اللعبة)
يجمع COLLECTION العديد من مجموعات البيانات ذات الصلة.تستخدم المجموعة المادية للبيانات المتعلقة بنقطة هندسية معينة ، على سبيل المثال ، عصا تناظرية واحدة. تُستخدم مجموعة التطبيقات لدمج الوظائف المختلفة في جهاز واحد. على سبيل المثال ، قد تحتوي لوحة المفاتيح المزودة بلوحة تتبع مدمجة على مجموعتي تطبيقات. نحن نصف عصا التحكم فقط ، مما يعني أن المجموعة ستكون واحدة:جمع (التطبيق)
...
END_COLLECTION
بعد ذلك ، تحتاج إلى تحديد أنه سيتم وصف العناصر التي ترسل الإحداثيات. يُستخدم مؤشر الاستخدام لوصف الفئران وعصا التحكم ولوحات الألعاب وأجهزة التحويل الرقمي:الاستخدام (المؤشر)
فيما يلي أوصاف العصي التناظرية مجتمعة في مجموعة:مجموعة (المادية)
USAGE (X)
USAGE (Y)
LOGICAL_MINIMUM (0)
LOGICAL_MAXIMUM (1000)
REPORT_SIZE (16)
REPORT_COUNT (2)
INPUT (Data,Var,Abs)
END_COLLECTION
يشيرالاستخدام هنا إلى استخدام قيم الانحراف على طول المحورين ، X و Y. يحدد LOGICAL_MINIMUM و LOGICAL_MAXIMUM المدى الذي يمكن أن تختلف فيه القيمة المرسلة.تم تعيين REPORT_COUNT و REPORT_SIZE ، على التوالي ، عدد الأرقام والحجم الذي سننقله ، أي رقمين 16 بت.INPUT (Data، Var، Abs) يعني أن البيانات تأتي من الجهاز إلى الكمبيوتر ، ويمكن أن تتغير هذه البيانات. القيم في حالتنا مطلقة. على سبيل المثال ، تأتي القيم النسبية من الماوس لتحريك المؤشر. أحيانًا يتم وصف البيانات على أنها Const ، وليس Var. يعد ذلك ضروريًا لإرسال بتات غير مهمة. على سبيل المثال ، في تقرير الماوس مع ثلاثة أزرار ، يتم نقل 3 بت من Var للأزرار و 5 بت من Const لتكملة حجم النقل إلى بايت واحد.كما ترى ، يتم تجميع أوصاف المحاور X و Y معًا. لديهم نفس الحجم ونفس الحدود. يمكن وصف العصا التناظرية نفسها على النحو التالي ، مع وصف كل محور على حدة. سيعمل مثل هذا الوصف على النحو السابق:مجموعة (المادية)
الاستخدام (X) LOGICAL_MINIMUM (0)
LOGICAL_MAXIMUM (1000)
REPORT_SIZE (16)
REPORT_COUNT (1)
INPUT (البيانات ، المتغير ، القيمة المطلقة)
الاستخدام (Y) LOGICAL_MINIMUM (0)
LOGICAL_MAXIMUM (1000)
REPORT_SIZE (16)
REPORT_COUNT (1)
INPUT (البيانات ، المتغير ، القيمة المطلقة)
END_COLLECTION
بعد العصا الأولى ، يتم وصف العصا التناظرية الثانية. محاورها لها استخدام مختلف بحيث يمكنك تمييزها عن العصا الأولى - Rx و Ry:مجموعة (المادية)
الاستخدام (Rx) الاستخدام
(Ry)
LOGICAL_MINIMUM (0)
LOGICAL_MAXIMUM (1000)
REPORT_SIZE (16)
REPORT_COUNT (2)
INPUT (البيانات ، المتغير ، القيمة المطلقة)
END_COLLECTION
تحتاج الآن إلى وصف بعض أزرار لوحة الألعاب. ويمكن القيام بذلك على النحو التالي:USAGE_PAGE (زر) الاستخدام (الزر
1)
الاستخدام (الزر 2)
الاستخدام (الزر 3)
...
الاستخدام (الزر 16)
يمكن تقليل التسجيل المرهق للأزرار من نفس النوع باستخدام نطاق الاستخدام:USAGE_PAGE (زر)
USAGE_MINIMUM (زر 1)
USAGE_MAXIMUM (زر 16)
البيانات المرسلة بواسطة الأزرار هي 16 قيمة بتة واحدة ، تتراوح من 0 إلى 1:LOGICAL_MINIMUM (0)
LOGICAL_MAXIMUM (1)
REPORT_SIZE (1)
REPORT_COUNT (16)
INPUT (Data,Var,Abs)
ترتيب الأسطر في الواصف غير صارم. على سبيل المثال ، يمكن كتابة Logical_Minimum و Logical_Maximum قبل الاستخدام (Button) ، أو يمكن تبديل السطور Report_Size و Report_Count.من المهم أن يحتوي أمر الإدخال على جميع المعلمات الضرورية لنقل البيانات (الاستخدام ، الحد الأدنى ، الحد الأقصى ، الحجم ، العدد).عندما يتم تكوين الواصف ، يمكن التحقق منه باستخدام الأمر Parse Descriptor للأخطاء.إذا كان كل شيء على ما يرام ، فقم بتصديره بالامتداد h. في ملف usbd_hid.c ، استبدل الواصف بواحد جديد واضبط في usbd_hid.h حجم واصف HID_MOUSE_REPORT_DESC_SIZE من 74 إلى 61.يتم إرسال التقارير باستخدام علامة data_ready . لهذاmain.c سوف نقوم بتضمين ملف رأس usbd_hid.h وفي الحلقة الرئيسية سوف نستدعي وظيفة إرسال التقرير. صفيف rc_data من نوع uint16 ، لذا يجب تحويل المؤشر إليه إلى نوع 8 بت وحجم تمرير 10 بدلاً من 5.#include "usbd_hid.h"
...
while (1)
{
if (data_ready)
{
USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t*)rc_data, 10);
data_ready = 0;
};
};
نقوم بتجميع المشروع ونومره مرة أخرى.الاتصال والاستخدام
أعد توصيل كبل USB من موصل USB ST-LINK بموصل USB الخاص بالمستخدم. سيكتشف Windows الجهاز الجديد ويقوم بتثبيت برنامج التشغيل تلقائيًا. دعنا نذهب إلى لوحة التحكم -> الأجهزة والطابعات ونرى جهاز محول STM32 USB-PPM مع رمز لوحة الألعاب.في معلمات الجهاز ، يمكنك أن ترى كيف يتحرك الصليب حول الحقل وتتحرك الأعمدة بعد تحريك العصي ، وتضيء رموز الزر من مفتاح التبديل. المعايرة ليست ضرورية لأنه تم بالفعل تعيين القيم الدنيا والقصوى في الواصف.بدءًا من FRV FreeRider ، سنرى كيف تتحرك العصي على الشاشة الرئيسية على لوحة الألعاب الافتراضية المرسومة وفقًا لجهاز التحكم عن بُعد. إذا لم يتم تعيين المحاور بشكل صحيح لسبب ما ، فيمكنك إعادة تكوينها في قسم معايرة وحدة التحكم .يتم استخدام مفاتيح التبديل المقابلة للأزرار الموجودة على جهاز التحكم عن بعد لتبديل أوضاع الطيران (بهلوانية / مثبتة) ، أو تبديل عرض الكاميرا (من اللوحة / من الأرض) ، أو بدء رحلة من البداية أو تشغيل السباق لفترة من الوقت.طار!
على الفيديو - نتيجة عدة أيام من تدريبي. أثناء الطيران بالطائرة الآلية ، وليس في الوضع البهلواني ، كما يفعل جميع سادة سباقات FPV. في وضع acro ، إذا قمت بتحرير العصي ، فإن المروحية لا تعود تلقائيًا إلى الوضع الأفقي ، ولكنها تستمر في الطيران بنفس الزاوية التي طارت بها. تعد الإدارة في وضع acro أكثر صعوبة ، ولكن يمكنك تحقيق سرعة أكبر ، وقدرة على المناورة ، وإجراء اضطرابات في الهواء وحتى الطيران رأساً على عقب.إلى Charpu Mastersما زلت بعيدًا جدًا ، لكنني أستمر في التدريب ويمكنني أن أقول على وجه اليقين أن فكرة المروحية الصغيرة التي تسابقني أثارت اهتمامي أكثر. وسرعان ما سأشارك بالتأكيد في بنائه ورحلاته لم تعد في جهاز المحاكاة ، ولكن في الواقع القاسي ، مع حوادث حقيقية ، مراوح مكسورة ، محركات مكسورة وبطاريات محترقة. ولكن هذا موضوع لمقالات أخرى :)
مشروع Keil uVision 5 و STM32CubeMX موجود على GitHub .