سلام دوستان! در قسمت قبل ، تنظیمات GPIO را برای میکروکنترلر STM32 در محیط نرمافزار CubeMX انجام دادیم. در این قسمت از آموزش قصد داریم تا این تنظیمات را به محیط نرمافزاری Keil منتقل کنیم و برنامهنویسی برای میکروکنترلر STM32 را در این محیط را آغاز کنیم. پس با سیسوگ همراه باشید.
همانطور که در عکس بالا مشاهده میکنید، باید نام پروژه و محل ذخیره آن و همچنین نام کامپایلر موردنظرمان (keil) را انتخاب کنیم و سپس دکمه OK را بزنیم و بعد از این عمل از همان منو Project گزینه generate code را بزنیم تا کدهای مربوط میکروکنترلر تولید شود و سپس دیالوگ مشابه عکس دوم برای ما ظاهر شود:
حالا باید دکمه open project را بزنیم تا برنامه ما در محیط نرمافزار keil مطابق عکس زیر باز شود:
همین ابتدا کار یک نکته خیلی مهم را اعلام میکنیم: در ابتدا دکمه F7 یا دکمه Build را میزنیم تا برنامه یکبار در محیط Keil کامپایل شود. پس از اتمام کامپایل برنامه، اگر به سمت چپ برنامه Keil توجه کنید، در کادر Project و در شاخه Drivers میتوانید کتابخانههای HAL را که برای راهاندازی ادوات مختلف این میکروکنترلر قرار داده شدهاند، مشاهده کنید:
قرار است توابع کتابخانه های stm32f1xx_hal_gpio.c و stm32f1xx_hal.c را مورد بررسی قرار دهیم و از آنها استفاده کنیم. همانطور که در عکس زیر مشاهده میکنید اگر در پایین همین کادر روی تب Functions کلیک کنید میتوانید توابع بکار رفته در هر فایل را ببینید.
این تابع همانطور که از نامش بر میآید برای برگرداندن تنظیمات یک پین مشخص از یک پورت مشخص به حالت پیشفرض است. در کتابخانه stm32f1xx_it.c تابع زیر را داریم که در زمان رخ دادن وقفه خارجی به داخل آن میرویم.
منظور از آرگومان GPIO_Pin پین از پورت مورد نظر است که اینتراپت خارجی روی آن فعال شده و از داخل همین تابع هم هست که ابتدا وقفه اینتراپت پاک میشود و سپس تابع HAL_GPIO_EXTI_Callback فراخوانی میشود به عنوان مثال به عکسهای زیر توجه کنید:
این تابع هم همان روتین وقفه خارجی است و همانطور که پیش از این گفته شد از داخل تابع HAL_GPIO_EXTI_IRQHandler فراخوانی میشود که با توجه به اینکه کلمه “weak __” در ابتدا آن بکار رفته به این معنی است که شما میتوانید همین تابع را به فایل main خودتان انتقال دهید و در آنجا کدهای خودتان را داخل آن جاسازی کنید. توضیحات بیشتر در مورد وقفه خارجی را موکول میکنیم به بخش آموزش کار با وقفه خارجی که در قسمت های بعدی بیان خواهم کرد فقط توجه داشته باشید که همین قضیه کلمه “weak __” را در مورد وقفههای ادوات دیگر میکروکنترلر مثل رابطهای سریال و تایمرها و غیره نیز داریم.
این تابع هم برای پیکره بندی یک پین یا پین های خاص از یک پورت مشخص کاربرد دارد پیکره بندی اعم از ورودی و یا خروجی بودن پورت ،پوش پول یا کلکتورباز بودن آن ، حداکثر سرعت پورت،اینکه ورودی آنالوگ یا غیره باشد است. البته توجه داشته باشد کدهای مربوط به پیکره بندی پورت ها در تابع MX_GPIO_Init داخل main برنامه تولید میشود.
توسط این تابع میتوانیم تنظیمات پیکره بندی را روی پین یا پینهای مورد نظر از یک پورت قفل کنیم که دیگر با تغییر مقادیر رجیسترهای پیکره بندی تغییری حاصل نشود.
توسط این تابع میتوانیم اطلاعات ورودی یک پین از پورت مشخص را در حالتی که بصورت ورودی پیکره بندی شده به شکل صفر و یا یک بخوانیم.
این تابع همانطور که از نامش بر می آید وظیفه بالعکس کردن وضعیت یک یا چند پین از پورت مشخص که بصورت خروجی پیکره بندی شده اند را بر عهده دارد.
این تابع وظیفه تغییر وضعیت یک یا چند پین از پورت مشخص که بصورت خروجی پیکره بندی شده اند به صفر یا یک را بر عهده دارد. تا اینجا با توابع کتابخانه gpio آشنایی مختصری پیدا کردیم ولیکن قرار بر این شد که برای برنامه نویسی اصولی تا آنجا که میتوایم کمتر از توابع کتابخانه hal استفاده کنیم از اینرو در ادامه به بررسی رجیسترهای رابط gpio میپردازیم .
کادر قرمز رنگ برای یک کردن پین مورد نظر استفاده می شود و کادر بنفش رنگ برای صفر کردن پین مورد نظر استفاده میشود. نمونه مثال عملی برای کاربرد این رجیستر را میتوانیم در متن تابع HAL_GPIO_WritePin هم ببنیم برای فهم بیشتر به عکس زیر توجه کنید:
کاربرد این رجیستر خیلی ساده و جالب است در عکس بالا اگر توجه کنید از همان 16 بیت اول برای یک کردن استفاده کرده ولی برای صفر کردن با 16 بیت شیفت دادن به سمت چپ و بیتهای پر ارزشتر از 16 بیت دوم استفاده میکنیم .توجه داشته باشید در اینجا منظور از GPIO_Pin که پین مورد نظر را مشخص میکند عدد 0 و 1 و 2و … تا 15 نیست بلکه همان 1 و 2 و 4 و 8 و … تا 32768 است در شکل زیر قضیه قابل فهم میشود که چطور ماکرو پین های مختلف نوشته شدهاند:
در قسمت بعدی آموزش میکروکنترلر STM32 قصد داریم به صورت عملی با رجیسترهای STM32 کار کنیم. پس سیسوگ را همراهی کنید.
باز کردن پروژه در نرمافزار Keil
پروژه ذخیرهشدهی خود را باز میکنیم و از منو project گزینه setting را انتخاب میکنیم تا صفحهای مطابق عکس زیر باز شود:توجه داشته باشید موقع اضافه کردن کد حتما کدهای خودتان را بین USER CODE BEGIN و USER CODE ENDهای مشخصشده در برنامه قرار بدهید. در غیر این صورت اگر دوباره با CubeMX تغییراتی اعمال و سپس دوباره خروجی بگیرید خودبهخود کدهایی که خارج از این کادرها قرار دادهاید، پاک میشوند!!!
توابع موجود در کتابخانه HAL میکروکنترلر STM32 :
با توضیح کتابخانه stm32f1xx_hal_gpio.c آغاز میکنیم:1 | void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) |
1 | void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) |
1 | __weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) |
1 | HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) |
1 | HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) |
1 | HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) |
1 | HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) |
1 | HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) |
رجیسترهای رابط GPIO میکروکنترلر STM32:
رجیسترهای GPIOx->CRH و GPIOx->CRL
رجیستر GPIOx->IDR
رجیستر GPIOx->ODR
رجیستر GPIOx->BSRR
رجیستر GPIOx->BRR
رجیستر GPIOx->LCKR
سلام. متشکر از سایت خوبتون مختصر و مفید بود واقعا
سلام. میخواستم بدونم اطلاعات مربوط به رجیسترهای یه میکرو از این سری (مثلا STM32L052R8) رو از کجا میتونم ببینم؟ دیتاشیتش رو دارم ولی بر خلاف AVR و PIC خبری از رجیسترها نیست. اگه میشه زودتر پاسخ بدین یه مقدار عجله دارم. ممنون.
آها شما باید فایل رفرنس منوال این میکروکنترلر رو دانلود کنید از خود سایت st میشه این کار رو انجام داد.
به قول شاعر «آمدی جانم به قربانت ولی حالا چرا؟»
جواب شما حکم نوشدارو بعد از «درمان» سهراب رو داشت. چون اون موردی که براش عجله داشتم خودش رفع شد! 🙂
به هر حال، ممنون از جوابتون. این مورد رو پیدا کردم که به سری 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 و اینجور چیزاست. یه نفر یه چیزایی در مورد چنین بردی بهم گفته بود.
سلام
باید بگم خوشحالم که مشکلتون حل شده :)، برای دیر شدن پاسخ پوزش میخوام – این روزها درگیری ها خیلی زیاد شده
+ الان من نگاه کردم شرکت st این مدل میکرویی که میگید رو تولید نکرده !!! تو نرم افزار stmcube چک کردم سری ۵۱ رو داره ولی سری ۵۲ چیزی نیست :/
فکر کنم یه جای رو اشتباه میکنید
من الان توی 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 نه!
اها – ببخشید اشتباه از من بود به جای l میزدم f ، اینقدری که با سری جنرال کار کردم ،
البته هفته پیش سری ۵۱ رو داشتم روش کار میکردم هر کاری میکردم پروگرام نمیشد نگو اونجام اشتباهی stm32f051 رو انتخاب کرده بودم :دی کلی وقت از دست دادم
سری های l توان مصرفیش خیلی مناسبه
در مورد برد هم برای من همون یک سری ۵۳ میآد ولی فکر میکنم اینا همخوان باشن – مثلا الان فرق سری ۵۱ و ۵۲ چیه ؟ – برنماه ۵۱ احتمال خیلی زیاد روی سری ۵۲ جواب میده
سلام
در برنامه keil با تعریف کردن تابع delay هنگام debug کردن وقتی دیباگر به خط delay میرسه با ارور undefined line number مواجه میشم تو اموزشی که دارم کد رو اجرا میکنه ولی برد وصله و من برد رو ندارم و در محیط سیمولیشن اجرا میکنم.
ایا امکان داره که تابع delay به سخت افزار نیاز داشته باشه؟
این در صورتی که وقتی تابع delay رو کامنت یا حذف میکنم، برنامه راحت debug میشه و اون ارور رو نمیده.
اونطور که من متوجه شدم شما برنامه رو دیباگ نمی کنید – سیمولیت میکنید- یعنی از سخت افزار استفاده نمیکنید –
توی سیمولیت کردن بسته به شکل تاخیری که ایجاد شده (با حلقه بوده یا تایمر) میتونه جواب های غیر دقیقی دریافت کنید و اینو دقیقا نمیدونم راه حلی داره یا نه باید توی سایت keil ببینید.
با سلام
ببخشید در شبیه سازی کامپایلر keil قسمت لاجیک آنالایزر هر سیگنال و متغیری را که اضافه میکنم خطا میده و میگه سیگنال شناخته نمی شود.
می تونید راهنماییم کنید
با تشکر
من کیل کار نمیکنم ولی امیدارم لینک زیر بهتون کمک کنه
http://www.keil.com/support/man/docs/uv4/uv4_db_dbg_logicanalyzer.htm
چطوری میتونیم از تابع write pin برای مقدار دهی همزمان چند پایه استفاده کنیم؟
مثلا میخام عدد ۳ روی پایه های pa0 تا pa1 قرار بگیره
چجوری با write pin این کارو بکنیم؟!
تنها وقتی میتونید از این روش استفاده کنید که پین های مروبطه روی یک gpio باشه.
با سادگی or کردن بایه هایی که مد نظر دارید.
سلام و خسته نباشید . مهندس با stm 32 میشه مستقیم با keil کار کرد و نیازی به cube mx نباشه؟
بله میشه صد در صد چنین کاری انجام داد.
باید پروژه رو از صفر خودتون پیاده سازی کنید.
من همه مراحل رو انجام دیدم ولی
کد ها generate نمیشه
البته jtag ها قرمز میشود که شاید به منزله ارور هستش نمیدونم
که البته این قسمت در نرم افزار من ورژن 4.7.1 کمی با مال شما فرق داره
شاید کتابخونه های مورد نیاز رو نتونسته دانلود کنه – متاسفانه st ایران رو تحریم کرده و این مشکل از این جهته که نرم افزارش کار نمیکنه
با ف… وصل بشید و آپدیت کنید.
خدا خیرتون بده
همین
متشکریم 🙂
بسیار عالی
🙂
با سلام خدمت دوستان
من بعد از generate کد در cube mx و اجرای برنامه keil صفحه مربوط به pack installer ران می شه وقتی می بندمش ارور زیر ظاهر می شه
one or more device familly pack device are not peresent
بعدش چند تا ارور دیگه می اد
کسی می دونه مشکل از کجاست؟؟؟؟
سلام دوست عزیز ،
اگر از کیل 5 به بعد استفاده می کنید احتمالا با این خطا مواجه میشید ؛ دلیلش هم اینه که توی این نسخه های شرکت ARM بسته های نصبی برای هر پکیج قرار داده به این صورت حجم فایل نصبی کم میشه و بهینه تر خواهد بود ؛ برای رفع این خطا تنها لازمه پکیج مورد نیاز رو نصب کنید – روی پک منیجر که باز میشه پکیج هایی رو که لازم دارید مثل STM32Fxxx رو نصب کنید CmSIS و…