برنامه نویسی حرفه ای میکروکنترلر (عملیات بیتی)

برنامه نویسی حرفه ای میکروکنترلر (عملیات بیتی)

برنامه نویسی حرفه ای میکروکنترلر (عملیات بیتی)
برنامه نویسی حرفه ای میکروکنترلر (عملیات بیتی)

برنامه نویسی حرفه ای میکروکنترلر تلاشی است برای بیان نکات خاص و سودمند جهت نوشتن برنامه ای بهینه تر مخصوصا برای پلتفرم هایی که به لحاظ حافظه با محدودیت های جدی روبرو هستند نظیر انواع میکروکنترلر ! شاید فکر کنید صرفه جویی چند بایت یا چند سیکل حافظه چه مقدار میتواند ارزش داشته باشد ، در صورت بروز محدودیت با تعویض میکروکنترلر ؛ به سادگی با آن مقابله خواهیم کرد ، البته این هم راهکاری صحیح است ولی اگر شما طراحی را برای یک تولید انبوه انجام داده باشید ، یک ریال هم یک ریال است ! چرا که یک ریال به تعداد دستگاه های تولید شده تکرار می شود. پس توصیه می‌کنیم حتما این دست مقالات ( برنامه نویسی حرفه ای میکروکنترلر ) را دنبال کنید و البته نظر و پیشنهادات خود را در خصوص بهتر شدن آن حتما مطرح نمایید. برای مطاله مطالب پیشین میتوانید ” برنامه‌نویسی حرفه ای” را جستجو کنید. در ادامه با سیسوگ همراه باشید.

عملیات بیتی موضوع برنامه نویسی حرفه ای میکروکنترلر

برنامه نویسی حرفه ای میکروکنترلر (عملیات بیتی)

انجام عملیات بیتی بر روی متغییر ها و رجیستر ها یکی از پرکاربرد ترین نوع عملیاتی است که در برنامه نویسی با میکروکنترلر مورد استفاده قرار می گیرد. اما واقعا با استفاده از چه روش هایی میتوان این عملیات را انجام داد. این عملیات چنان مهم و کاربردی است که در برخی پردازنده ها حتی دستور اسمبلی برای آن وجود دارد و در برخی پردازنده های ARM حتی سخت افزاری برای ان تعبیه شده است. قبلا در قسمت دوم مقاله برنامه نویسی حرفه ای از این قابلیت گفتیم (Bit-Banding) و نحوه استفاده از آن را بررسی کردیم. اما اگر بخواهیم فارغ از سخت افزار به آن نگاه کنیم همچنان از اهمیت بسیار بالایی برخوردار است. در آموزش برنامه نویسی حرفه ای میکروکنترلر از AVR استفاده خواهیم کرد و البته تمام کد های پیاده شده در تمام دیگر پردازنده ها به سادگی قابل استفاده خواهند بود !

دقیقا منظور از عملیات بیتی چیست ؟

همانطور که میدانید ؛ هر بیت حاوی داده یک یا صفر است ، و جز این مقداری دیگری نمیتواند بپذیرد (البته به جز در کامپیوتر های کوانتومی) ، منظور از عملیات بیتی دقیقا مقدار دهی آنها و خواندن مقدار آنها خواهد بود ، البته عملیات های And و Or و Xor و Not و .. هم عملیات بیتی است ، اما منظور ما در این مقاله مقدار دهی و خواندن مقدار یک بیت است. چرا که انجام عملیات منطقی به سادگی بر روی بایت ها قابل اجراست و مشکلی از بابت وجود ندارد.

اما چرا داریم به مقوله مقدار دهی بیت ها می پردازیم ؛ همانطور که میدانید حافظه به صورت بایت ، بایت در دسترس قرار داد و برای دسترسی به مقدار یک بیت از یک بایت باید تعدادی عملیات منطقی انجام داد ، اما این که این کار را به چه صورت انجام دهیم تاثیر بسزایی در سرعت اجرای برنامه خواهد داشت.

 

کدویژن چکار می کند ؟

کدویژن عملیات بیتی

قبلا طی مقاله ای تحت عنوان “چرا کدویژن نه” به نقد این نرم افزار پرداختیم و با تکیه بر شواهد و دلایل منطقی توصیح دادیم که چرا نباید از این نرم افزار استفاده کرد. اما از آنجایی که هر نرم افزار و سرویسی طرف دار های دو آتیشه ای هم دارد ، مکررا با این استدلال مواجه شدم که کدام نرم افزاری قابلیت دسترسی به بیت های یک پورت را دارد. البته این استدلال صحیح است ، نرم افزار کدویژن برای دسترسی به بیت های یک پورت امکانات ویژه ای دارد. به عنوان مثال برای مقدار دهی بیت دوم از پورت B کافی است خط زیر را در برنامه وارد کنید.

برای خواندن کافی است خط زیر را وارد کنید

البته خود این نحوه نوشتار به خوبی نشان میدهد که تا چه اندازه کدویژن از یک کامپایلر مطلوب فاصله دارد. حتی اگر PORTB را یک Struct یا union بدانیم باز هیچ اسم متغییری نمی تواند با اعداد شروع شود!

و همیشه به این موضوع می بالند که بله کدویژن چنین کار را ساده کرده ! اگر مقاله را تا انتها دنبال کنید ، در خواهید یافت که GCC و روش اصولی برنامه نویسی هیچ تفاوتی با این نوع برنامه نویسی بی قائده نخواهد داشت.

در GCC چطور این کار را خواهیم کرد ؟

GCC عملیات بیتی

این روش دقیقا مثل روشی است که در کدویژن مورد استفاده قرار می گیرد اما به سبک استاندارد شده. برای این کار به سادگی یک Struct با 8 عضو می سازیم که هر عضو یک بیت طول داشته باشد. اما چطور چنین کاری ممکن است ، یه تعریف زیر دقت کنید

همانطور که تعریف Struct مشاهده می کنید به سادگی میتوان طول هر عضو را با قرار دادن دو نقطه ” : ” مشخص کنید. مطمئنا اکثر افراد از چنین مساله ای بی اطلاع هستند ، تنها به این دلیل که تسلط کافی به زبان و شکل نوشتاری زبان ندارد. برای همین مساله است که همیشه تاکید می‌کنم حتما به اندازه کافی به زبان مورد استفاده تسلط پیدا بکنید. اما متاسفانه همیشه با این تفکر پیش میرویم که برنامه نویسی چیز بیشتری برای آموختن ندارد !

برای اطلاع بیشتر در خصوص تعریف بیتی ساختار می توانید به این آموزش مراجعه کنید. اما با توجه به نحوه تعریف ساختار بیتی ، ساختار مورد نظر را به شکل زیر تعریف می‌کنیم:

هر عضو از Struct بالا یک بیت طول دارد که تعریف 8 عضو یعنی 8 بیت و طول کل هم یک بایت خواهد بود ، اگر رجیستر ها یا پورت های میکروکنترلر 16 یا 32 بیتی است می توان به همان تعداد عضو تعریف کرد. برای استفاده تنها کافی است که آدرس (اشاره گر) پورت را رجیستر مورد بحث را به این ساختار ارجاع دهیم :

در حال حاظر متغیری به اسم PortB داریم که به بیت های آن دسترسی مستقیم خواهیم داشت ، برای مقدار دهی می توان به صورت زیر عمل کنیم

دقیقا تمام عملیاتی که بر روی یک متغیر امکان پذیر است بر روی این بیت ها هم امکان پذیر است. چرا که اعضای یک Struct هستند.

 

مجموعه مقالات برنامه نویسی حرفه ای میکروکنترلر را در سیسوگ دنبال کنید.

حمایت از Zeus ‌

خوشحال میشیم برای تداوم و کیفیت ما رو حمایت کنید.

1 نفر

پــــســنــدیـده انـد

توجه

Zeus ‌
Zeus ‌

زئوس هستم ساکن المپ

دیدگاه ها

9 دیدگاه

  • AmirAli
    ۱۳ اسفند ۱۳۹۸

    سلام
    عالی بود این اموزش
    ممنون از شما 🙂

    با این روش میشه چنتا پین از پورت های مختلف رو ترکیب کرد و یه پورت جدید ساخت؟
    تو یه پروژه ممکنه چند پایه از پورت های مختلف بمونه و بخوایم از اونا برای کار دیگه استفاده کنیم و کار یکم سخت میشه
    چطور میشه این پین های باقی مونده رو به یه پورت جدید تبدیل کرد و مثل بقیه پورت ها باهاش رفتار کرد،
    مثلا بنویسیم :
    NewPort = 0xff;

    • Zeus ‌
      زئوس Zeus
      ۲۱ اسفند ۱۳۹۸

      سلام خواهش میکنم 🙂
      ولی فکر کنم برای تعریف پورت جدید لازمه که آدرس های حافظه پشت هم قرار گرفته باشند که معمولا این گونه نیست

  • علی
    ۳۰ مرداد ۱۳۹۸

    سلام
    من قبلا تو کدویژن اگه بخواستم اسم یه پایه رو تغییر بدم خیلی ساده انجام می شد مثل
    define Led=PORTD.0#
    اما الان که میخوام با AtmelStudio برنامه بنویسم به مشکل بر خوردم!!!
    از چه روشی باید استفاده کنم که تو برنامه کدها خوانا تر باشه.
    ممنون

    • Zeus ‌
      زئوس Zeus
      ۱ شهریور ۱۳۹۸

      سلام دوست عزیز ؛ خوب برای این کار توی کامپایلر gcc میتونید به دو روش عمل کنید ؛ روش اول استفاده از دستور اسمبلی sbi و cbi است ؛ برای راحت شدن استفاده از به شکل ماکرو باز نویسیش کردم

      #define SBI(port,bit) asm("sbi %0, %1" : : "I" (_SFR_IO_ADDR(port)), "I" (bit))
      #define CBI(port,bit) asm("cbi %0, %1" : : "I" (_SFR_IO_ADDR(port)), "I" (bit))

      یا این که به شکل عملیات بیتی باز نویسیش کنید

      #define SBI(port,bit) port |= (1 << bit)


      #define CBI(port,bit) port &= ~(1 << bit)

      برای استفاده هم کافیه که به شکل زیر استفاده کنید

      SBI(PORTA,1);

      • علی
        ۱ شهریور ۱۳۹۸

        سلام
        ممنون
        ولی این جواب من نبود!!!
        مثلا من اگه بخوام led رو روشن کنم مینوشتم
        led=1;
        ولی با روش شما من تو دستورات باید اسم پین و پورت led ی که متصل شده رو وارد کنم.
        اگه این طور باشه خب می نویسم PORTA.0=1

        با تشکر

        • Zeus ‌
          زئوس Zeus
          ۱ شهریور ۱۳۹۸

          سلام
          خواهش میکنم
          من الان توجه دغدغه شما نشدم ؛ الان سه روش مجزا برای خاموش و روشن کردن یک پین گفتم ؛ روش اول که توی پست هست استفاده از استارکپر (همونطور که قبلا توی کدویژن استفاده می کردید.) روش اسمبلی و روش عملیات منطقی 😐
          اگر دغدغه شما اینه که برای روشن کردن یه led بنویسید led=1 خوب از روشی که توی همین پست توضیخ داده شده استفاده کنید. و led رو دیفاین کنید همونطوری که توی کدویژن دیفاین می کردید.

  • Hosein Mohammadi
    Hosein Mohammadi
    ۲۱ مهر ۱۳۹۷

    ممنون بابت زحماتنون

  • نوید
    ۱۵ مهر ۱۳۹۷

    سلام.باز هم ممنونم
    میشه لطفا در مورد اشاره گر ها و union و structer توضیح بدین
    من از چنتا منبع مختلف خوندم اما کاملا متوجه نشدم
    اگر امکان داره شما همراه با چنتا مثال عملی و واقعی توضیح بدین
    همچنین همراه با فوایدشون
    بسیار ممنونم

    • Zeus ‌
      زئوس Zeus
      ۱۶ مهر ۱۳۹۷

      سلام دوست عزیز
      ببینید اینا مواردی هست که توضیحشون توی کامنت مقداری سخت هست ؛ احتمالا یک سری آموزش در خصوص برنامه نویسی منتشر خواهیم کرد و به این موارد خواهیم پرداخت
      اما میتونید به این لینک مراجعه کنید ، توضیحات خوبی با مثال گذاشته

پر بحث ترین ها

مسابقه دوم : چالش برنامه نویسی به زبان C

مسابقه اول سیسوگ (مسابقه اول: درک سخت افزار) انتقادهای زیادی رو در پی داشت تا جایی که حتی خودمم به نتیجه مسابقه...

Zeus ‌ Zeus ‌
  • 2 سال پیش

راه اندازی LCD گرافیکی Nokia 1661 و دانلود کتابخانه آن

LCD گرافیکی یکی از مهم ترین پارامترهای موجود در طراحی انواع مدارات الکترونیکی پیچیده و حتی ساده است ، نمایش وضعیت و...

Zeus ‌ Zeus ‌
  • 4 سال پیش

ریموت کدلرن و چکونگی دکد کردن آن به همراه سورس برنامه

ریموت کنترل امروزه کاربرد زیادی پیدا کرده است؛ از ریموت‌های درب بازکن تا ریموت‌های دزدگیر و کنترل روشنایی همه از یک اصول اولیه پیروی می‌کنند و آن‌هم ارسال اطلاعات به‌صورت بی‌سیم است....

Zeus ‌ Zeus ‌
  • 5 سال پیش

همه چیز درباره ریموت کنترل‌های هاپینگ

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

Zeus ‌ Zeus ‌
  • 5 سال پیش

مسابقه سوم: استخراج داده از رشته ها در زبان C

نزدیک به 5 ماه از مسابقه دوم سیسوگ می‌گذره و فکر کردم که بد نیست یک چالش جدید داشته باشیم! البته چالش‌ها...

Zeus ‌ Zeus ‌
  • 2 سال پیش

مسابقه ششم: بزن میکروکنترلر را بسوزون!

بزنم میکروکنترلر را بسوزونم اونم تو  این شرایط!، طراحی مسابقه از اون چیزی که به نظر می‌رسه سخت‌تر است، باید حواست باشه...

Zeus ‌ Zeus ‌
  • 10 ماه پیش

آموزش قدم به قدم راه اندازی +NRF24L01

آموزش قدم به قدم راه اندازی +NRF24L01  با کتابخانه سازگار با انواع میکروکنترلرها و کامپایلرها قبل از اینکه قسمت بشه با ماژول...

رسول خواجوی بجستانی رسول خواجوی بجستانی
  • 3 سال پیش

ساخت ماینر با FPGA و ARM

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

Zeus ‌ Zeus ‌
  • 3 سال پیش

کار با ماژول تمام عیار mc60 – قسمت دوم – راه اندازی OpenCPU

در قسمت اول به یکسری اطلاعات کلی ماژول mc60 پرداختیم، با نرم افزار QNavigator کار کردیم و یک هدربرد هم برای کار...

Mahdi.h   Mahdi.h  
  • 3 سال پیش

مسابقه چهارم: کدام حلقه سریع‌تر است؟

حدود ۷ ماه پیش، مسابقه سوم سیسوگ رو برگزار کردیم و کلی نکته در مورد خواندن رشته‌های ورودی را بررسی کردیم. فکر...

Zeus ‌ Zeus ‌
  • 1 سال پیش
سیـــســـوگ

مرجع متن باز آموزش الکترونیک