برنامه نویسی رجیستری STM32 : مبانی

برای اعمال تنظیمات میکروکنترلر STM32 ، رجیستر ها باید تغییر کنند. رجیستر یک محتوای 8 ، 16 یا 32 بیتی بدون علامت هست با آدرسی مشخص. مقدار بیت های رجیستر عملکرد بخشی از میکروکنترلر رو مشخص میکنه. در این مقاله قدم به قدم در سه مرحله آموزش میبینید، در زبان سی چطور به محتوای حافظه و رجیسترها دسترسی پیدا میکنیم.

 

پیشنیاز:

مقاله کاربرد عملگرهای بیتی برای تغییر بیتها

 

فهرست

ساخت پوینتر برای هر رجیستر

دسترسی به رجیستر در قالب اعضای استراکچر

دسترسی به بیت رجیسترها با بیت فیلد

CMSIS و بیت فیلد

 

ویدئوی آموزش مبانی برنامه نویسی رجیستری STM32 در کانال یوتوب pointer-x

ساخت پوینتر برای هر رجیستر

فرض کنید یک رجیستر 16 بیتی در آدرس 0x40000000 وجود داره. چجوری میشه مقدار رجیستر رو خوند یا تغییر داد؟

رجیستر در حافظه

به پوینتری با مقدار 0x40000000 و نوع *uint16_t نیاز داریم. مثلا اسم پوینتر هست  p، با قرار دادن علامت استریسک قبل از پوینتر، به محتوای آدرس دسترسی داریم.استریسک پوینتر

 پوینتر متغیر
برای تعریف پوینتر، باید استریسک – پوینتر ( p* ) تعریف بشه. نوع p* ، نوع اون محتوای حافظه است که برای دسترسی بهش پوینتر میسازیم. مثلا اینجا میخواهیم به رجیستر 16 بیتی دسترسی داشته باشیم پس نوع p*  هست uint16_t . همونطور که در تعریف متغیر، قبل از نام اون، نوعش نوشته میشه. نوع p* هم قبلش نوشته شده که uint16_t هست. 
 
 

تعریف p* ، تعریف خود p هم هست ( یک عبارت همزمان تعریف دو چیزه). نوع پوینتر هم در تعریف پوینتر قبل از اسمش نوشته شده:

 

پوینتر ثابت

برای ساخت پوینتر ثابت باید نوع پوینتر رو قبل از مقدار پوینتر در پرانتز نوشت. به نوشتن نوع عدد در پرانتز قبل مقدار عدد، میگن کست کردن.
 
 

جمع بندی روش اول

برای دسترسی به رجیستر 16 بیتی در آدرس 0x40000000 کافیه یک پوینتر ثابت بسازیم و قبلش علامت استریسک بذاریم. 
 
 
 
میتونیم استریسک-پوینتر  رو در ابتدای کد define کنیم که برنامه خوانا تر باشه. فرض کنید اسم این رجیستر 16 بیتی هست CR1 از پریفرال TIM2.
 
 
میشه از پوینتر متغیر هم استفاده کرد فقط اول باید تعریف و مقدار دهی بشه. 
 

رجیستر اعضای استراکچر فرضی

پریفرال GPIOC هفت رجیستر 32 بیتی داره که پشت سرهم در حافظه قرار دارند. رجیستر CRL اولین رجیستره که در آدرس 0x40011000 هست. برای دسترسی به GPIOC_CRL پوینتر زیر رو باید بسازیم.
 



روش بهتری هم وجود داره. بجای اینکه هر رجیستر رو یک 32 بیتی جدا در نظر بگیریم. همه ی رجیسترهای یک پریفرال رو، عضو یک استراکچر فرضی در نظر میگیریم. مثلا پریفرال GPIOC هفت عدد رجیستر 32 بیتی داره که از آدرس 0x40011000 شروع شدن. فرض میکنیم یک استراکچر که 7 عضو 32 بیتی داره در آدرس 0x40011000 قرار داره.
 
استراکچر قالب رجیستر های پریفرال GPIO در میکروکنترلر stm32f103c8


نوع متغیر استراکچر GPIO_Type رو مطابق رجیسترهای پریفرال های GPIO طراحی میکنیم و با استفاده از این نوع متغیر یک پوینتر میسازیم برای دسترسی به استراکچر فرضی از نوع GPIO_Type که در آدرس 0x40011000 قرار داره. 


ساخت پوینتر به استراکچر با کست کردن آدرس

با قراردادن عملگر پیکان بعد از پوینتر به استراکچر، میتونیم به اعضای استراکچر که رجیسترهای پریفرال GPIOC هستنید دسترسی پیدا کنیم. 

 

 

برای خواناتر شدن کد میتونیم، پوینتر به استراکچر رو define کنیم.


این روش CMSIS استاندارد هست برای دسترسی به رجیسترها ، در فایل دیوایس CMSIS این چیزها وجود داره که بتونیم به رجیسترها دسترسی داشته باشیم و برنامه نویسی رجیستری انجام بدیم.

1. تعریف آدرس اولین رجیستر پریفرال ها ( base address ) 

2. تعریف نوع متغیر استراکچر قالب رجیسترهای هر پریفرال

3. تعریف پوینتر برای دسترسی به رجیسترهای هر پریفرال

دسترسی به بیت رجیسترها با بیت فیلد

در دو روش قبلی برای دسترسی به رجیسترها، نوع خود رجیستر همیشه اینتیجر 32 بیتی بوده و برای تغییر بیت ها چند نیازمندی وجود داره:

  • فرایند صفر کردن و یک کردن بیت ها متفاوت هست.
  • به ماسک بیت نیاز هست.


فرض کنید با روش قبلی قراره بیت های MODE1 در رجیستر CRL از پریفرال GPIOC رو 0b01 کنیم. یعنی قراره بیت 5 صفر و بیت 4 یک بشه. در قدم اول هر دو بیت صفر میشن و به ماسک بیت های MODE1 نیاز هست. در قدم دوم بیت 4 باید یک بشه که ماسک بیت 4 نیاز هست. 

در روش سوم به عملگرهای بیتی و ماسک بیت نیازی نیست و مستقیما با عملگر = میتونیم بیت فیلد هارو تغییر بدیم. رجیستر CRL، تعداد 16 بیت فیلد 2 بیتی داره که اولی MODE0 و آخری CNF7 هست. مطابق بیت های این رجیستر یک نوع متغیر استراکچر تعریف میشه که اعضاش بیت فیلد هستند.



حالا فرض میکنیم در آدرس رجیستر CRL، بجای اینتیچر 32 بیتی، یک استراکچر از نوع CRL_Type وجود داره که البته 32 بیتی هست. در استراکچری که در مرحله قبل قالب رجیستر های پریفرال GPIO طراحی شده بود، نوع رجیستر CRL رو از uint32_t  به CRL_type تغییر میدم .

با دسترسی به اعضای این استراکچر به بیت فیلد های رجیستر دسترسی مستقیم پیدا میکنیم. قرار بود بیت 4 یک و بیت 5 صفر بشه، یعنی در بیت های MODE1 عدد یک نوشته بشه. در یک مرحله و با عملگر = میشه عدد یک رو در این دو بیت نوشت و به ماسک بیت و عملگر های بیتی نیازی نیست.  

به مقدار 32 بیتی بدون علامتی که در آدرس 0x4001000 هست، یک بار بصورت اینتیجر و یک بار استراکچر دسترسی پیدا کردیم. اگر بخواهیم همزمان قابلیت هر دو دسترسی رو داشته باشیم به یونیون نیاز هست. توضیحات مربوط به این قسمت رو در ویدئو ببینید.

CMSIS و بیت فیلد

لایه ی نرم افزاری CMSIS استاندارد که کتابخونه hal از اون استفاده میکنه بیت فیلد نداره و دسترسی به رجیسترها 32 بیتی هست. ولی شرکت آرم که CMSIS رو ارائه میده فایل هایی هم ارائه میده با دسترسی به بیت فیلد. دلیل اینکه از این فایل ها کمتر استفاده میشه به تفاوت کد اسمبلی نوشته شده توسط کامپایلر های مختلف برای دسترسی به بیت فیلد در حافظه است. 

دیدگاه‌ خود را بنویسید

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

پیمایش به بالا