برنامهنویسی حرفهای میکروکنترلر تلاشی است برای بیان نکات خاص و سودمند جهت نوشتن برنامهای بهینهتر مخصوصا برای پلتفرمهایی که بهلحاظ حافظه با محدودیتهای جدی روبرو هستند نظیر انواع میکروکنترلر! شاید فکرکنید صرفهجویی چندبایت یا چند سیکل حافظه چهمقدار میتواند ارزش داشتهباشد، درصورت بروز محدودیت با تعویض میکروکنترلر؛ بهسادگی با آن مقابله خواهیمکرد، البته اینهم راهکاری صحیحاست ولی اگر شما طراحی را برای یک تولید انبوه انجامدادهباشید، یک ریال هم یک ریال است! چراکه یک ریال به تعداد دستگاههای تولیدشده تکرار میشود. پس توصیه میکنیم حتما ایندست مقالات( برنامه نویسی حرفه ای میکروکنترلر )را دنبالکنید و البته نظر و پیشنهادات خود را درخصوص بهترشدن آن حتما مطرح نمایید. در ادامه با ما همراه باشید.
عملیات بیتی موضوع برنامهنویسی حرفهای میکروکنترلر
انجام عملیات بیتی برروی متغییرها و رجیسترها یکیاز پرکاربردترین نوع عملیاتی است که در برنامهنویسی با میکروکنترلر مورداستفاده قرارمیگیرد. اما واقعا بااستفادهاز چه روشهایی میتوان این عملیات را انجامداد. این عملیات چنان مهم و کاربردی است که دربرخی پردازندهها حتی دستور اسمبلی برای آن وجود دارد و دربرخی پردازندههای ARM حتی سختافزاری برای آن تعبیهشدهاست. قبلا در قسمت دوم مقاله برنامهنویسی حرفهای از این قابلیت گفتیم(Bit-Banding) و نحوهی استفادهاز آن را بررسی کردیم. اما اگر بخواهیم فارغاز سختافزار به آن نگاهکنیم همچنان از اهمیت بسیاربالایی برخوردار است. در آموزش برنامهنویسی حرفهای میکروکنترلر از AVR استفادهخواهیمکرد و البته تمام کدهای پیادهشده درتمام دیگر پردازندهها بهسادگی قابلاستفاده خواهندبود!
دقیقا منظور از عملیات بیتی چیست ؟
همانطورکه میدانید؛ هربیت حاوی داده یک یا صفر است، و جز این مقداری دیگری نمیتواند بپذیرد (البته بهجز در کامپیوترهای کوانتومی) ، منظوراز عملیات بیتی دقیقا مقداردهی آنها و خواندن مقدار آنها خواهدبود، البته عملیاتهای And و Or و Xor و Not و… هم عملیات بیتی است، اما منظورما در این مقاله مقداردهی و خواندن مقدار یک بیت است. چراکه انجام عملیات منطقی به سادگی بر روی بایت ها قابل اجراست و مشکلی از بابت وجود ندارد. اما چرا داریم به مقوله مقداردهی بیتها میپردازیم؛ همانطورکه میدانید حافظه بهصورت بایت، بایت دردسترس قرارداد و برای دسترسیبه مقدار یک بیت از یک بایت باید تعدادی عملیات منطقی انجامداد، اما اینکه اینکار را به چهصورت انجامدهیم تاثیر بسزایی در سرعت اجرایبرنامه خواهدداشت.
کدویژن چکار میکند؟
قبلا طی مقالهای تحت عنوان “چرا کدویژن نه” به نقد این نرمافزار پرداختیم و باتکیهبر شواهد و دلایل منطقی توضیح دادیم که چرا نباید از این نرمافزار استفادهکرد. اما از آنجاییکه هر نرمافزار و سرویسی طرفدارهای دو آتیشه ای هم دارد، مکررا با این استدلال مواجهشدم که کدام نرم افزاری قابلیت دسترسیبه بیتهای یک پورت را دارد. البته این استدلال صحیح است، نرمافزار کدویژن برای دسترسیبه بیتهای یک پورت امکانات ویژهای دارد. بهعنوانمثال برای مقداردهی بیت دوم از پورت B کافیاست خط زیر را در برنامه واردکنید.
PORTB.2 = 1;
برای خواندن کافیاست خط زیر را وارد کنید:
bit = PORTB.2;
البته خود این نحوه نوشتار بهخوبی نشان میدهد که تا چه اندازه کدویژن از یک کامپایلر مطلوب فاصله دارد. حتی اگر PORTB را یک Struct یا union بدانیم باز هیچ اسم متغییری نمیتواند با اعداد شروعشود! و همیشه به این موضوع میبالند که بله کدویژن چنین کار را ساده کرده! اگر مقاله را تاانتها دنبالکنید، درخواهیدیافت که GCC و روش اصولی برنامهنویسی هیچتفاوتی با این نوع برنامهنویسی بیقائده نخواهد داشت.
در GCC چطور این کار را خواهیم کرد ؟
اینروش دقیقا مثل روشی است که در کدویژن مورداستفاده قرار میگیرد اما به سبک استانداردشده. برای اینکار بهسادگی یک Struct با ۸عضو میسازیم که هرعضو ۱ بیت طول داشتهباشد. اما چطور چنینکاری ممکناست؟ به تعریفزیر دقتکنید:
struct { type [member_name] : width ; };
همانطورکه تعریف Struct مشاهده میکنید بهسادگی میتوان طول هرعضو را باقراردادن دو نقطه ” : ” مشخصکنید. مطمئنا اکثر افراد از چنین مسالهای بیاطلاع هستند، تنها به ایندلیل که تسلط کافی به زبان و شکل نوشتاری زبان ندارد. برای همین مساله است که همیشه تاکید میکنم حتما بهاندازهی کافی به زبان مورداستفاده تسلط پیداکنید. اما متاسفانه همیشه با این تفکر پیش میرویم که برنامهنویسی چیز بیشتری برای آموختن ندارد! برای اطلاعبیشتر درخصوص تعریف بیتی ساختار میتوانید به این آموزش مراجعهکنید. اما باتوجهبه نحوهی تعریف ساختار بیتی، ساختار موردنظر را به شکلزیر تعریف میکنیم:
typedef struct { unsigned bit0:1; unsigned bit1:1; unsigned bit2:1; unsigned bit3:1; unsigned bit4:1; unsigned bit5:1; unsigned bit6:1; unsigned bit7:1; } PORT_REG;
هرعضو از Struct بالا ۱ بیت طول دارد که تعریف ۸عضو یعنی ۸بیت و طول کل هم ۱ بایت خواهد بود، اگر رجیستها یا پورتهای میکروکنترلر ۱۶ یا ۳۲ بیتی است میتوان بههمانتعداد عضو تعریفکرد. برای استفاده تنها کافیاست که آدرس (اشارهگر) پورت را رجیستر موردبحث را به این ساختار ارجاعدهیم:
PORT_REG *PortB = (PORT_REG*)&PORTB;
درحالحاضر متغیری به اسم PortB داریم که به بیتهای آن دسترسی مستقیم خواهیمداشت، برای مقداردهی میتوان بهصورتزیر عملکنیم:
PortB->bit2 = 1; PortB->bit2 = 0; PortB->bit2 = ~PortB->bit0;
دقیقا تمام عملیاتی که برروی یک متغیر امکانپذیر است برروی این بیتها هم امکانپذیر است. چراکه اعضای یک Struct هستند. مجموعه مقالات برنامه نویسی حرفه ای میکروکنترلر را در با ما دنبال کنید.
منبع: سیسوگ