در این مقاله پریفرال RCC میکروکنترلر STM32F103C8 و رجیستر هاش رو بررسی میکنیم و اینکه برای تنظیم کلاک میکروکنترلر به 72MHz چه کدی باید بنویسیم و کدوم بیت ها رو در کدوم رجیستر پریفرال RCC باید تغییر بدیم.
– معرفی پریفرال NVIC در CPU Cortex-m3 در میکروکنترلر STM32F1
– حالت های pending و active برای اینتراپت های میکروکنترلر STM32
– رجیسترهای پریفرال NVIC در میکروکنترلر STM32F1
– توابع CMSIS برای تغییر رجیسترهای پریفرال NVIC در میکروکنترلر STM32F1
– مراحل فعالسازی اینتراپت در پریفرال NVIC در میکروکنترلر STM32
مشاهده ویدئوی تنظیمات کلاک میکروکنترلر STM32F103C8 بصورت رجیستری در یوتیوب
کد تنظیم کلاک با CMSIS استاندارد برای STM32F103C8:
کد تنظیم کلاک با CMSIS با دسترسی به بیت فیلد برای STM32F103C8:
معرفی پریفرال NVIC در CPU cortex-m3 در میکروکنترلر STM32F103
پریفرال NVIC یکی از پریفرال های سی پی یو cortex-m3 هست ، یعنی هر میکروکنترلری که از این CPU استفاده میکنه حالا چه ساخت شرکت st باشه چه TI این پریفرال رو داره ، طراحی این پریفرال رو مثل طراحی سی پی یو و سایر پریفرال های سی پی یو شرکت آرم انجام داده. وظیفه ی این پریفرال مدیریت اینتراپت ها هست. فعال کردن و مشخص کردن اولیت اینتراپت ها رو در رجیستر های این پریفرال انجام میدیم.
هر اینتراپتی قرار باشه اتفاق بیافته ابتدا پریفرال منبع اینتراپت یک درخواست به پریفرال NVIC ارسال میکنه ، این پریفرال NVIC هست که عملکرد سی پی یو رو متوقف میکنه و سی پی رو میفرسته که تابع IRQHandler رو اجرا کنه.
حالت های pending و اکتیو برای اینتراپت های میکروکنترلرهای STM32
حالت pending اینتراپت در میکروکنترلرهای STM32
از وقتی که درخواست اینتراپت به پریفرال NVIC ارسال میشه تا وقتی که تابع IRQHandler فراخوانی بشه، اینتراپت در حالت pending قرار داره، یعنی در صف اجرا هست.
حالت active اینتراپت در میکروکنترلرهای STM32
از وقتی تابع IRQHandler مربوط به یک اینتراپت فراخوانی میشه تا وقتی اجرای اون تابع تموم میشه ، اینتراپت در حالت اکتیو هست. ممکنه اینتراپت در حالت اکتیو باشه ولی CPU در حال اجرای تابع IRQHandler مربوط به اون اینتراپت نباشه.
رجیسترهای پریفرال NVIC در سی پی یو cortex-m3 در میکروکنترلر STM32F1
رجیسترهای ISER برای فعال کردن اینتراپت ها در میکروکنترلر STM32
برای فعال کردن هر اینتراپت دو جا باید اون رو فعال کرد ، یکی در پریفرالی که منبع اینتراپت هست و دیگری در پریفرال NVIC . برای هر اینتراپت یک بیت در رجیسترهای ISER وجود داره. یک کردن بیت به معنی فعال کردن اینتراپت هست. صفر نوشتن در این بیت ها تاثیری نداره. یک خوندن به معنای فعال بودن و صفر خوندن به معنای غیر فعال بودن اینتراپت هست. زیر بیت های این رجیستر نوشته rs یعنی میتونیم بخونیم و میتونیم یک کنیم.
رجیسترهای ICER برای غیر فعال کردن اینتراپت ها در میکروکنترلر STM32
برای هر اینتراپت یک بیت در رجیسترهای ICER وجود داره. یک نوشتن در بیت ، بیت رو صفر میکنه و به معنای غیر فعال کردن اینتراپت هست. صفر نوشتن در بیت تاثیری نداره. یک خوندن به معنی فعال بودن و صفر خوندن به معنای غیر فعال بودن اینتراپت هست. در زیر بیت ها نوشته rc_w1 ، یعنی میتونیم این بیت ها رو بخونیم و میتونیم صفرش کنیم با نوشتن یک .
رجیسترهای ISPR برای قرار دادن اینتراپت در حالت pending در میکروکنترلر STM32
وقتی که درخواست اینتراپت از طرف یک پریفرال میکروکنترلر برای پریفرال NVIC ارسال بشه ، اون اینتراپت در حالت pending قرار میگیره، یعنی میره تو صف اجرا. با استفاده از رجیسترهای ISPR میتونیم بصورت نرم افزاری اینتراپت رو به حالت pending ببریم. برای هر اینتراپت یک بیت در رجیسترهای ISPR داریم. یک نوشتن در این بیت میتونیم یکش کنیم و اینتراپت رو به حالت pending ببریم. صفر نوشتن در بیت های این رجیسترها مفهومی نداره. یک خوندن به معنای این هست که اینتراپت در حالت pending هست و صفر خوندن به معنای اینکه اینتراپت در حالت pending نیست. در زیر بیت های این رجیستر نوشته rs ، یعنی میتونیم بیت ها رو بخونیم یا یکش کنیم.
رجیسترهای ICPR برای خارج کردن اینتراپت از حالت pending در میکروکنترلر STM32
بعد از فراخوانی تابع interrupt request handler اینتراپت از حالت pending بیرون میاد. خودمون هم میتونیم اینتراپت رو از صف اجرا خارج کنیم با استفاده از رجیسترهای ICPR. برای هر اینتراپت یک بیت اینجا داریم. یک نوشتن در بیت ، مقدار بیت رو صفر میکنه و اینتراپت رو از حالت pending خارج میکنه. صفر کردن بیت تاثیری نداره. خوندن بیتها هم مشابه رجیستر ISPR هست. در زیر بیت ها نوشته rc_w1 ، یعنی میتونیم این بیت ها رو بخونیم و میتونیم صفرش کنیم با نوشتن یک .
رجیسترهای IABR برای چک کردن حالت اکتیو اینتراپت در میکروکنترلر STM32
برای هر اینتراپت یک بیت در این رجیستر داریم که فقط قابلیت خوندن داره. یک خوندن از این بیت به معنای این هست که تابع IRQHandler فراخوانی شده ولی هنوز اجراش تموم نشده. به این حالت میگن اکتیو . اگر صفر بخونیم یعنی اینتراپت در حالت اکتیو نیست. دقت کنید که اکتیو با فعال فرق داره. در زیر بیت ها در این رجیستر نوشته r ، یعنی فقط میتونیم این بیت ها رو بخونیم.
رجیسترهای IPR0 تا IPR20 برای اولویت بندی اینتراپت ها
برای هر اینتراپت 8 بیت در این رجیسترها داریم که البته در میکروکنترلر های STM32F1 فقط چهار بیت پیاده سازی شده، پس برای هر اینتراپت 4 بیت برای مشخص کردن اولیت داریم. هر چه عددی که در این چهار بیت نوشته میشه کمتر باشه. اینتراپت ارجهیت بالاتری برای اجرا داره. این چهار بیت به دو گروه preemption priority یا group priority (بیتهای پرارزش) و sub priority (بیتهای کم ارزش) تقسیم میشن. اگر دو اینتراپت هم زمان اتفاق بیافتن اول اونی که عدد preemption کمتری داره اجرا میشه، اگر برابر بودن اونی که عدد sub priority کمتری داره اول اجرا میشه و اگر sub priority هم برابر بود اون اینتراپتی اول اجرا میشه که شماره اینتراپت کمتری داره.
بیت های PRIGROUP در رجیستر IARCR در پریفرال SCB برای مشخص کردن گروه بندی اولیت
برای اینکه مشخص کنیم از چهار بیت اولویت چند بیت برای preemption priority داریم و چند بیت برای sub priority باید مقدار سه بیت PRIGROUP رو تنظیم کنیم. توجه داشته باشید رجیستر IARCR کلید داره. قبل از نوشتن در این رجیستر باید در بیت های کلید عدد 0x5FA رو نوشت.
توابع CMSIS برای تغییر رجیسترهای پریفرال NVIC در STM32
لایه ی نرم افزاری CMSIS برای تنظیم رجیسترهای پریفرال های CPU توابعی داره که در فایل core_cm3.h هستند. پریفرال NVIC هم یکی از پریفرال های CPU هست و میتونیم از توابعی که فایل core_cm3.h فراهم میکنه برای فعال سازی اینتراپت یا مشخص کردن اولیت یا … استفاده کنیم.
مراحل فعالسازی اینتراپت در پریفرال NVIC در میکروکنترلر STM32
در ادامه یک کد نمونه رو بررسی میکنیم تا ببینید چطور از توابع CMSIS برای فعالسازی یک اینتراپت در پریفرال NVIC استفاده میکنیم.
مشخص کردن گروه بندی اولویت اینتراپت ها در میکروکنترلر STM32
اولین تابعی که باید فراخوانی بشه تابع NVIC_SetPriorityGrouping هست ، این تابع یک ورودی از نوی 32 بیتی بدون علامت داره و مقداری که ورودی به این تابع میدیم در بیت های PRIGROUP در رجیستر SCB_AIRCR ثبت میشه و با اینجوری مشخص میکنیم از چهار بیت اولویت ، چند بیت برای preemption priority میخواهیم و چند بیت برای sub priority میخواهیم. دقت کنید که این تابع رو یک بار در کدمون فراخوانی میکنیم.
مشخص کردن اولیت یک اینتراپت در میکروکنترلر STM32
برای هر اینتراپت قبل از اینکه فعالش کنیم باید اولیت رو مشخص کنیم. برای مشخص کردن اولویت من از سه تا از توابع CMSIS استفاده کردم.
1- تابع NVIC_SetPriority : با این تابع میشه اولیت هر اینتراپت رو مشخص کرد. ورودی اولش شماره ی اینتراپت هست ، با شماره اینتراپت این تابع میفهمه کدوم بیت IP رو در کدوم رجیستر IPR باید تغییر بده. همونطور که در بالا گفتم، برای مشخص کردن اولویت چهار تا بیت به نامه IPx وجود داره. ورودی دوم این تابع عدد چهار بیتی هست که باید در بیت های IPx ثبت کنیم. برای ساخت این عدد چهار بیتی میتونیم از تابع NVIC_EncodePriority استفاده کنیم.
2- تابع NVIC_EncodePriority : این تابع سه تا ورودی داره ، ورودی اولش گروه بندی اینتراپت هاست ، دقیقا همون عددی که ورودی به تابع NVIC_SetPriorityGrouping دادیم و در بیت های PRIGROUP در رجیستر SCB_AIRCR ثبت کردیم تا مشخص کنیم چند تا بیت برای preemption و جند تا بیت برای sub priority داریم. ورودی دوم و سومش هم به ترتیب عددی هست که برای اولویت های preemption و sub priority در نظر گرفتیم. این تابع رجیستر های پریفرال NVIC رو تغییر نمیده فقط با استفاده از ورودی هاش عدد چهار بیتی که برای مشخص کردن اولیت نیاز داریم رو میسازه.
3- تابع NVIC_GetPriorityGrouping : ورودی اول تابع قبلی عددی بود که در بیت های PRIGROUP ثبت کردیم. تابع NVIC_GetPriorityGrouping این عدد رو برمیگردونه.
فعال کردن اینتراپت در پریفرال NVIC میکروکنترلر STM32
بعد از مشخص کردن اولویت نوبت فعال کردن اینتراپت هست، که با استفاده از تابع NVIC_EnableIRQ این کار رو انجام میدیم . این تابع یک ورودی داره که شماره اینتراپت هست. این تابع بیت مربوط به اینتراپت رو در رجیستر های ISER یک میکنه و اینطوری اینتراپت فعال میشه.