وميض LED في STM32 في المجمع

منذ بعض الوقت كنت أرغب في تعلم المجمّع ، وبعد قراءة الأدبيات ذات الصلة ، حان وقت الممارسة. في الواقع ، سيتم مناقشته بشكل أكبر. تدربت في البداية على Arduino Uno (Atmega328p) ، الآن قررت الانتقال وتناول STM32. سقطت STM32F103C8 في الواقع بين يدي وسيتم إجراء المزيد من التجارب.

الأدوات


استخدمت الأدوات التالية:

  • Notepad ++ - لكتابة التعليمات البرمجية
  • مجمع غنو المجمع
  • STM32 ST-LINK Utility + ST-LINK V2 - لوميض الكود الموجود على وحدة التحكم الدقيقة وتصحيح الأخطاء

ابدأ


الغرض الرئيسي من لغة التجميع بالنسبة لي هو التعلم. نظرًا لأنك لا تعرف أبدًا مكان مواجهة مشكلة أخرى مثيرة للاهتمام ، فقد تقرر كتابة كل شيء من البداية. كانت المهمة الأساسية لفهم كيفية عمل ناقلات المقاطعة. على عكس Atmega في STM32 ، لا يحتوي ناقل المقاطعة على تعليمات الانتقال:

jmp main 

تتم كتابة عناوين محددة فيه ، وأثناء المقاطعة ، يستبدل المعالج نفسه العنوان المحدد في الناقل في سجل الكمبيوتر. فيما يلي مثال لمتجه المقاطعة الخاص بي:

 .org 0x00000000 SP: .word STACKINIT RESET: .word main NMI_HANDLER: .word nmi_fault HARD_FAULT: .word hard_fault MEMORY_FAULT: .word memory_fault BUS_FAULT: .word bus_fault USAGE_FAULT: .word usage_fault .org 0x000000B0 TIMER2_INTERRUPT: .word timer2_interupt + 1 

أريد أن ألفت انتباه القارئ إلى حقيقة أن السطر الأول ليس متجه إعادة التعيين ، ولكن القيم التي سيتم من خلالها تهيئة المكدس. مباشرة بعد ذلك ، هناك متجه إعادة تعيين متبوعًا بـ 5 نواقل مقاطعة إلزامية (NMI_HANDLER - USAGE_FAULT).

التنمية


أول شيء أذهلني كان بناء جملة ARM. حتى أثناء دراسة ناقلات المقاطعة ، صادفت إشارات إلى حقيقة أن ARM لديه نوعان من التعليمات Thumb وليس Thumb. وأن Cortex-M3 (STM32F103C8 وهي Cortex-M3) يدعم فقط مجموعة من تعليمات الإبهام. لقد كتبت التعليمات بدقة وفقًا للتوثيق ، ولكن لسبب ما لعن المجمع عليها.
مطلوب سجل غير منقول
اتضح أنه في بداية البرنامج
.syntax موحد
هذا يخبر المجمّع أنه يمكنك استخدام تعليمات الإبهام وغير الإبهام في نفس الوقت.

والشيء التالي الذي صادفته هو منافذ GPOI الافتراضية المعطلة. لجعلها تعمل ، من بين أمور أخرى ، تحتاج إلى تعيين القيم المناسبة في سجلات RCC (إعادة الضبط والتحكم على مدار الساعة). لقد استخدمت PORT C ، ويمكن تشغيله عن طريق تعيين بت 4 (ترقيم البتات يبدأ من نقطة الصفر) في RCC_APB2ENR (الساعة الطرفية تمكين التسجيل 2).

مزيد من وميض LED. بادئ ذي بدء ، كما هو الحال في Arduino ، تحتاج إلى تعيين دبوس للتسجيل. يتم ذلك عن طريق GPIOx_CRL (سجل التحكم منخفض) أو GPIOx_CRH (ارتفاع سجل التحكم). هنا من الضروري إلغاء ذلك لكل بت 4 دبوس مسؤولة في أحد هذه السجلات (32 بت التسجيلات). 2 بت (MODEy) تحديد الحد الأقصى لمعدل البيانات وتكوين 2 بت (CNF) دبوس. لقد استخدمت PORT C pin 14 ، لذلك قمت بتعيين بتات [25:24] = 10 بتات [27:26] = 00 في سجل GPIOx_CRH.

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

لن أصف بالتفصيل إعدادات المؤقت ، المهتمين بالكود على Github . كانت الفكرة بسيطة ، في دورة أرسل المعالج إلى Idle ، اخرج من Idle بواسطة المؤقت لتشغيل / إيقاف تشغيل LED ومرة ​​أخرى إلى Idle. لكن المؤقت يعمل بشكل أسرع بكثير مما تمكنت من القيام بكل ما سبق ، بسبب ذلك اضطررت إلى إدخال عداد إضافي.

العداد هو متغير 32 بت يجب أن يكون في SRAM. ثم كانت أشعل النار تنتظرني. عندما قمت بالبرمجة في Atmega لوضع متغير في SRAM ، من خلال .org قمت بتعيين عنوان بداية الذاكرة حيث تم وضع كتلة البيانات بالفعل. الآن ، بعد أن قرأت قليلاً عن تهيئة الذاكرة ، لست متأكدًا مما إذا كان هذا صحيحًا ، لكنه نجح. وقررت تحريك الشيء نفسه مع STM32. عنوان بدء الذاكرة في STM32F103C8 هو 0x20000000. وعندما فعلت ذلك .org على هذا العنوان ، حصلت على 512 ميجابايت ثنائي. هذا أرسل لي بضع ليال لتدخين كتيبات. ما زلت لا أفهم 100٪ كيف يعمل هذا ، ولكن بقدر ما أفهم قسم البيانات. يضع القيم التي يجب تهيئة المتغيرات من خلالها إلى ملف قابل للتنفيذ ، ولكن في وقت التشغيل يجب على المبرمج تهيئة القيم المتغيرة في الذاكرة. صحح لي من فضلك إذا كنت مخطئا. انتهى بي الأمر بإنشاء متغير مثل هذا:

 .section .bss .offset 0x20000000 flash_counter: .word 

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

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


All Articles