ARM, STM, STM32, توصیه شده, مقاله

آموزش میکروکنترلر STM32 قسمت دوم: نرم‌افزار Keil

سلام دوستان! در قسمت قبل ، تنظیمات GPIO را برای میکروکنترلر STM32 در محیط نرم‌افزار CubeMX انجام دادیم. در این قسمت از آموزش قصد داریم تا این تنظیمات را به محیط نرم‌افزاری Keil منتقل کنیم و برنامه‌نویسی برای میکروکنترلر STM32 را در این محیط را آغاز کنیم. پس با سیسوگ همراه باشید.  

باز کردن پروژه در نرم‌افزار Keil

پروژه ذخیره‌شده‌ی خود را باز می‌کنیم و از منو project گزینه setting را انتخاب می‌کنیم تا صفحه‌ای مطابق عکس زیر باز شود: محیط نرم افزار cubeMx برای میکروکترلر STM32   همان‌طور که در عکس بالا مشاهده می‌کنید، باید نام پروژه و محل ذخیره آن و همچنین نام کامپایلر موردنظرمان (keil) را انتخاب کنیم و سپس دکمه OK را بزنیم و بعد از این عمل از همان منو Project گزینه generate code را بزنیم تا کدهای مربوط میکروکنترلر تولید شود و سپس دیالوگ مشابه عکس دوم برای ما ظاهر شود: خرویجی نرم افزار CubeMx برای نرم افزار Keil   باز کردن کد تولید شده در نرم افزار Keil   حالا باید دکمه open project را بزنیم تا برنامه ما در محیط نرم‌افزار keil مطابق عکس زیر باز شود:   محیط نرم افزار keil   همین ابتدا کار یک نکته خیلی مهم را اعلام می‌کنیم:
توجه داشته باشید موقع اضافه کردن کد حتما کدهای خودتان را بین USER CODE BEGIN و USER CODE ENDهای مشخص‌شده در برنامه قرار بدهید. در غیر این صورت اگر دوباره با CubeMX تغییراتی اعمال و سپس دوباره خروجی بگیرید خودبه‌خود کدهایی که خارج از این کادرها قرار داده‌اید، پاک می‌شوند!!!
  در ابتدا دکمه F7 یا دکمه Build را می‌زنیم تا برنامه یک‌بار در محیط Keil کامپایل شود. پس از اتمام کامپایل برنامه، اگر به سمت چپ برنامه Keil توجه کنید، در کادر Project و در شاخه Drivers می‌توانید کتابخانه‌های HAL را که برای راه‌اندازی ادوات مختلف این میکروکنترلر قرار داده شده‌اند، مشاهده کنید: کتابخانه HAL در محیط نرم افزار Keil   قرار است توابع کتابخانه های  stm32f1xx_hal_gpio.c و stm32f1xx_hal.c  را مورد بررسی قرار دهیم و از آنها استفاده کنیم. همانطور که در عکس زیر مشاهده می‌کنید اگر در پایین همین کادر روی تب Functions کلیک کنید می‌توانید توابع بکار رفته در هر فایل را ببینید. توابع GPIO میکروکنترلر STM32  

توابع موجود در کتابخانه HAL میکروکنترلر STM32 :

با توضیح کتابخانه stm32f1xx_hal_gpio.c آغاز می‌کنیم: این تابع همانطور که از نامش بر می‌آید برای برگرداندن تنظیمات یک پین مشخص از یک پورت مشخص به حالت پیشفرض است.   در کتابخانه  stm32f1xx_it.c تابع زیر را داریم که در زمان رخ دادن وقفه خارجی به داخل آن می‌رویم. منظور از آرگومان GPIO_Pin پین از پورت مورد نظر است که اینتراپت خارجی روی آن فعال شده و از داخل همین تابع هم هست که ابتدا وقفه اینتراپت پاک می‌شود و سپس تابع HAL_GPIO_EXTI_Callback فراخوانی می‌شود به عنوان مثال به عکسهای زیر توجه کنید:       این تابع هم همان روتین وقفه خارجی است و همانطور که پیش از این گفته شد از داخل تابع HAL_GPIO_EXTI_IRQHandler فراخوانی می‌شود که با توجه به اینکه کلمه  “weak __”   در ابتدا آن بکار رفته به این معنی است که شما میتوانید همین تابع را به فایل main خودتان انتقال دهید و در آنجا کدهای خودتان را داخل آن جاسازی کنید.  توضیحات بیشتر در مورد وقفه خارجی را موکول می‌کنیم به بخش آموزش کار با وقفه خارجی که در قسمت های بعدی بیان خواهم کرد فقط توجه داشته باشید که همین قضیه کلمه  “weak __”   را در مورد وقفه‌های ادوات دیگر میکروکنترلر مثل رابط‌های سریال و تایمرها و غیره نیز داریم.   این تابع هم برای پیکره بندی یک پین یا پین های خاص از یک پورت مشخص کاربرد دارد پیکره بندی  اعم از ورودی و یا خروجی بودن پورت ،پوش پول یا کلکتورباز بودن آن ، حداکثر سرعت پورت،اینکه ورودی آنالوگ یا غیره باشد است. البته توجه داشته باشد کدهای مربوط به پیکره بندی پورت ها در تابع MX_GPIO_Init داخل main برنامه تولید می‌شود.   توسط این تابع میتوانیم تنظیمات پیکره بندی را روی پین یا پینهای مورد نظر از یک پورت قفل کنیم که دیگر با تغییر مقادیر رجیسترهای پیکره بندی تغییری حاصل نشود.   توسط این تابع می‌توانیم اطلاعات ورودی یک پین از پورت مشخص را در حالتی که بصورت ورودی پیکره بندی شده  به شکل صفر و یا یک بخوانیم.   این تابع همانطور که از نامش بر می آید وظیفه  بالعکس کردن وضعیت یک یا چند پین از پورت مشخص که بصورت خروجی پیکره بندی شده اند را بر عهده دارد.   این تابع وظیفه تغییر وضعیت یک یا چند پین از پورت مشخص که بصورت خروجی پیکره بندی شده اند به صفر یا یک را بر عهده دارد.   تا اینجا با توابع کتابخانه gpio آشنایی مختصری پیدا کردیم ولیکن قرار بر این شد که برای برنامه نویسی اصولی تا آنجا که می‌توایم کمتر از توابع کتابخانه hal استفاده کنیم از اینرو در ادامه به بررسی رجیسترهای رابط gpio می‌پردازیم .  

رجیسترهای رابط GPIO میکروکنترلر STM32:

  • رجیسترهای GPIOx->CRH و GPIOx->CRL

دو رجیستر 32 بیتی خواندنی و نوشتنی به همین نامها برای هر پورت میکروکنترلر در نظر گرفته شده، که بدلیل اینکه هر پورت در میکروکنترلر STM32 حداکثر 16 بیتی است برای هر پین از پورت، 4 بیت تنظیمات خواهیم داشت که توسط رجیسترهای GPIOx->CRH و GPIOx->CRL  اعمال می‌گردد. در اسامی رجیسترها منظور از x همان نام پورت خاص است که از A شروع می‌شود تا B   و C  و … برای فهم بیشتر به عکسهای زیر در مورد مشخصات این رجیسترها در رفرنس منوال توجه نمائید:      
  • رجیستر GPIOx->IDR

این یک رجیستر خواندنی 32 بیتی هست که 16 بیت اول آن برای ما قابل استفاده است و از طریق این 16 بیت می‌توانیم مقدار لاجیک صفر و یک روی پین های پورت مورد نظرمان را بخوانیم. توجه داشته باشید اگر پورت مورد نظر بجای ورودی بصورت خروجی پیکره بندی شده باشد در هر لحظه مقدار این رجیستر مساوی مقدار رجیستر GPIOx->ODR خواهد بود. برای فهم بیشتر به عکس زیر در مورد مشخصات این رجیستر در رفرنس منوال میکروکنترلر توجه نمائید:    
  • رجیستر GPIOx->ODR

این یک رجیستر خواندنی و نوشتنی 32 بیتی هست که 16 بیت اول آن برای ما قابل استفاده است و از طریق این 16 بیت میتوانیم مقدار لاجیک صفر و یک روی پین های پورت مورد نظرمان را تنظیم کنیم. دقیقاً مشابه رجیستر PORT در میکرو کنترولر AVR که هر کدام از بیتها را که صفر کنیم پین متناظر آن صفر منطقی میشود و هر کدام از بیتها را که یک نمائیم پین متناظر آن یک منطقی خواهد شد. برای فهم بیشتر به عکس زیر در مورد مشخصات این رجیستر در رفرنس منوال توجه نمائید:    
  • رجیستر GPIOx->BSRR

این یک رجیستر خواندنی و نوشتنی 32 بیتی هست که هر 32 بیت آن برای ما قابل استفاده است و از طریق 16 بیت اول می‌توانیم پین یا پین های مشخص از پورتمان را یک منطقی و از طریق 16 بیت دوم می‌توانیم پین یا پین های مشخص از پورتمان را صفر منطقی کنیم. برای فهم بیشتر مسئله به عکس زیر توجه کنید:     کادر قرمز رنگ برای یک کردن پین مورد نظر استفاده می شود و کادر بنفش رنگ برای صفر کردن پین مورد نظر استفاده می‌شود. نمونه مثال عملی برای کاربرد این رجیستر را میتوانیم در متن تابع HAL_GPIO_WritePin هم ببنیم برای فهم بیشتر به عکس زیر توجه کنید:     کاربرد این رجیستر خیلی ساده و جالب است در عکس بالا اگر توجه کنید از همان 16 بیت اول برای یک کردن استفاده کرده ولی برای صفر کردن با 16 بیت شیفت دادن به سمت چپ و بیتهای پر ارزشتر از 16 بیت دوم استفاده می‌کنیم .توجه داشته باشید در اینجا منظور از GPIO_Pin که پین مورد نظر را مشخص می‌کند عدد 0 و 1 و 2و … تا 15 نیست بلکه همان 1 و 2 و 4 و 8 و … تا 32768 است در شکل زیر قضیه قابل فهم می‌شود که چطور ماکرو پین های مختلف نوشته شده‌اند:    
  • رجیستر GPIOx->BRR

این یک رجیستر خواندنی و نوشتنی 32 بیتی هست که 16 بیت اول آن برای ما قابل استفاده است و از طریق این 16 بیت میتوانیم مقدار لاجیک صفر و یک روی پین های پورت مورد نظرمان را صفر کنیم. ما اگر هر کدام از بیتها را که یک نمائیم پین متناظر آن صفر منطقی خواهد شد. برای فهم بیشتر به عکس زیر در مورد مشخصات این رجیستر در رفرنس منوال توجه نمائید:      
  • رجیستر GPIOx->LCKR

این یک رجیستر خواندنی و نوشتنی 32 بیتی است که 17 بیت اول آن برای ما قابل استفاده است و از طریق 16 بیت اول با یک کردن هر کدام از بیت های مورد نظر، می‌توانیم پیکره بندی پین های متناظر رجیستر شده را قفل کنیم. بعد از این عمل تا زمانی که بیت مورد نظر با آن پین را در رجیستر GPIOx->LCKR  صفر نکنیم، نمی‌توانیم پیکره بندی آن پین ها را عوض کنیم.  بیت هفدهم  برای این است که محتویات 16 بیت اول تا زمان ریست شدن میکروکنترلر STM32 قفل شود. برای فهم بیشتر به عکسهای زیر در مورد مشخصات این رجیستر در رفرنس منوال توجه نمائید:         در قسمت بعدی آموزش میکروکنترلر STM32 قصد داریم به صورت عملی با رجیسترهای STM32 کار کنیم. پس سیسوگ را همراهی کنید.

انتشار مطالب با ذکر نام و آدرس وب سایت سیسوگ، بلامانع است.

شما نیز میتوانید یکی از نویسندگان سیسوگ باشید.   همکاری با سیسوگ

نوشته های مشابه

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

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

22 دیدگاه در “آموزش میکروکنترلر STM32 قسمت دوم: نرم‌افزار Keil

  1. امیرسینا گفت:

    سلام. میخواستم بدونم اطلاعات مربوط به رجیسترهای یه میکرو از این سری (مثلا STM32L052R8) رو از کجا میتونم ببینم؟ دیتاشیتش رو دارم ولی بر خلاف AVR و PIC خبری از رجیسترها نیست. اگه میشه زودتر پاسخ بدین یه مقدار عجله دارم. ممنون.

    1. زئوس Zeus زئوس Zeus گفت:

      آها شما باید فایل رفرنس منوال این میکروکنترلر رو دانلود کنید از خود سایت st میشه این کار رو انجام داد.

      1. امیرسینا گفت:

        به قول شاعر «آمدی جانم به قربانت ولی حالا چرا؟»
        جواب شما حکم نوشدارو بعد از «درمان» سهراب رو داشت. چون اون موردی که براش عجله داشتم خودش رفع شد! 🙂
        به هر حال، ممنون از جوابتون. این مورد رو پیدا کردم که به سری STM32L0x1 مربوط میشه:
        https://www.st.com/resource/en/reference_manual/dm00108282-ultra-low-power-stm32l0x1-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf
        ولی برای STM32L052 یا در کل STM32L0x2 چیزی پیدا نکردم. همون pdf بالا برای L052 جواب میده یا باید دنبال چیز دیگه‌ای بگردم؟
        یه سوال دیگه: برد خاصی بر پایه STM32L052 وجود داره؟ منظورم مثلا برد آموزشی یا development board و اینجور چیزاست. یه نفر یه چیزایی در مورد چنین بردی بهم گفته بود.

        1. زئوس Zeus زئوس Zeus گفت:

          سلام
          باید بگم خوشحالم که مشکلتون حل شده :)، برای دیر شدن پاسخ پوزش میخوام – این روزها درگیری ها خیلی زیاد شده
          + الان من نگاه کردم شرکت st این مدل میکرویی که میگید رو تولید نکرده !!! تو نرم افزار stmcube چک کردم سری ۵۱ رو داره ولی سری ۵۲ چیزی نیست :/
          فکر کنم یه جای رو اشتباه میکنید

          1. امیرسینا گفت:

            من الان توی STM32CubeMX دارم ۸ تا میکرو از سری STM32L052 میبینم! مثلا STM32L052T8. از قسمت Line گزینه‌ی STM32L0x2 رو تیک بزنید.
            فایل‌های مربوطه رو توی Cube پیدا کردم. بعد انتخاب یکی از میکروهای این سری (همون 52T8) رفتم قسمت Docs & Resources این دو تا لینک به دردم خورد:
            https://www.st.com/resource/en/datasheet/stm32l052t8.pdf
            این همون دیتاشیته که قبلا دیدم و رجیسترها رو نداشت.

            https://www.st.com/resource/en/reference_manual/DM00108281-.pdf
            این یکی reference manual برای سری L0x2 هست.

            در مورد اون برد که گفتم چی؟ توی Cube دو تا برد بر پایه L053 دیدم ولی L052 نه!

          2. زئوس Zeus زئوس Zeus گفت:

            اها – ببخشید اشتباه از من بود به جای l میزدم f ، اینقدری که با سری جنرال کار کردم ،
            البته هفته پیش سری ۵۱ رو داشتم روش کار میکردم هر کاری میکردم پروگرام نمیشد نگو اونجام اشتباهی stm32f051 رو انتخاب کرده بودم :دی کلی وقت از دست دادم
            سری های l توان مصرفیش خیلی مناسبه
            در مورد برد هم برای من همون یک سری ۵۳ میآد ولی فکر میکنم اینا همخوان باشن – مثلا الان فرق سری ۵۱ و ۵۲ چیه ؟ – برنماه ۵۱ احتمال خیلی زیاد روی سری ۵۲ جواب میده

  2. احد گفت:

    سلام
    در برنامه keil با تعریف کردن تابع delay هنگام debug کردن وقتی دیباگر به خط delay میرسه با ارور undefined line number مواجه میشم تو اموزشی که دارم کد رو اجرا میکنه ولی برد وصله و من برد رو ندارم و در محیط سیمولیشن اجرا میکنم.
    ایا امکان داره که تابع delay به سخت افزار نیاز داشته باشه؟
    این در صورتی که وقتی تابع delay رو کامنت یا حذف میکنم، برنامه راحت debug میشه و اون ارور رو نمیده.

    1. زئوس Zeus زئوس Zeus گفت:

      اونطور که من متوجه شدم شما برنامه رو دیباگ نمی کنید – سیمولیت میکنید- یعنی از سخت افزار استفاده نمیکنید –
      توی سیمولیت کردن بسته به شکل تاخیری که ایجاد شده (با حلقه بوده یا تایمر) میتونه جواب های غیر دقیقی دریافت کنید و اینو دقیقا نمیدونم راه حلی داره یا نه باید توی سایت keil ببینید.

  3. حامد گفت:

    با سلام
    ببخشید در شبیه سازی کامپایلر keil قسمت لاجیک آنالایزر هر سیگنال و متغیری را که اضافه میکنم خطا میده و میگه سیگنال شناخته نمی شود.
    می تونید راهنماییم کنید
    با تشکر

    1. زئوس Zeus زئوس Zeus گفت:

      من کیل کار نمیکنم ولی امیدارم لینک زیر بهتون کمک کنه
      http://www.keil.com/support/man/docs/uv4/uv4_db_dbg_logicanalyzer.htm

  4. مهسا گفت:

    چطوری میتونیم از تابع write pin برای مقدار دهی همزمان چند پایه استفاده کنیم؟
    مثلا میخام عدد ۳ روی پایه های pa0 تا pa1 قرار بگیره
    چجوری با write pin این کارو بکنیم؟!

    1. زئوس Zeus زئوس Zeus گفت:

      تنها وقتی میتونید از این روش استفاده کنید که پین های مروبطه روی یک gpio باشه.
      با سادگی or کردن بایه هایی که مد نظر دارید.

  5. علی عطاران گفت:

    سلام و خسته نباشید . مهندس با stm 32 میشه مستقیم با keil کار کرد و نیازی به cube mx نباشه؟

    1. زئوس Zeus زئوس Zeus گفت:

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

  6. حسین گفت:

    من همه مراحل رو انجام دیدم ولی
    کد ها generate نمیشه
    البته jtag ها قرمز میشود که شاید به منزله ارور هستش نمیدونم
    که البته این قسمت در نرم افزار من ورژن 4.7.1 کمی با مال شما فرق داره

    1. زئوس Zeus زئوس Zeus گفت:

      شاید کتابخونه های مورد نیاز رو نتونسته دانلود کنه – متاسفانه st ایران رو تحریم کرده و این مشکل از این جهته که نرم افزارش کار نمیکنه
      با ف… وصل بشید و آپدیت کنید.

  7. Ebbex گفت:

    خدا خیرتون بده
    همین

  8. محمد امین گفت:

    با سلام خدمت دوستان
    من بعد از generate کد در cube mx و اجرای برنامه keil صفحه مربوط به pack installer ران می شه وقتی می بندمش ارور زیر ظاهر می شه
    one or more device familly pack device are not peresent
    بعدش چند تا ارور دیگه می اد
    کسی می دونه مشکل از کجاست؟؟؟؟

    1. زئوس Zeus زئوس Zeus گفت:

      سلام دوست عزیز ،
      اگر از کیل 5 به بعد استفاده می کنید احتمالا با این خطا مواجه میشید ؛ دلیلش هم اینه که توی این نسخه های شرکت ARM بسته های نصبی برای هر پکیج قرار داده به این صورت حجم فایل نصبی کم میشه و بهینه تر خواهد بود ؛ برای رفع این خطا تنها لازمه پکیج مورد نیاز رو نصب کنید – روی پک منیجر که باز میشه پکیج هایی رو که لازم دارید مثل STM32Fxxx رو نصب کنید CmSIS و…