برنامه نویسی میکروکنترلر را به صورت حرفه ای بیاموزیم

برنامه نویسی میکروکنترلر را به صورت حرفه ای بیاموزیم

برنامه نویسی میکروکنترلر را به صورت حرفه ای بیاموزیم
برنامه نویسی میکروکنترلر را به صورت حرفه ای بیاموزیم

برنامه نویسی حرفه ای تاثیر خیلی زیادی در راندمان سخت افزار دارد،  قبلا در مقاله ای تحت عنوان “میکروکنترلر مقصر نیست مقصر برنامه نویسی است” بررسی کردیم که چقدر برنامه نویسی می تواند تاثیر بسزایی در راندامان و بازدهی سخت افزار داشته باشد، با روشن شدن این مساله مهم ، نکته ای که باید به آن توجه داشت ، بهبود سطح برنامه نویسی است. یکی از مسائلی که به شخصه فکر می کنم نقطه ضعف طراح های الکترونیک و البته برنامه نویس های سیستم های نهفته (embedded systems) است عدم تسلط کافی به مقوله برنامه نویسی است؛ برای بررسی بیشتر این مساله با سیسوگ همراه باشید.

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

امروزه بیشتر مدارات الکترونیکی از میکروکنترلرها و پردازنده ها استفاده می کنند که نیازمند برنامه نویسی برای عملکرد دلخواه هستند، مقوله ای که در دانشگاه ها به آن پرداخته نمی شود آموزش صحیح برنامه نویسی برای مهندسین الکترونیک است ، مهندسین الکترونیک دید خوبی نسبت به سخت افزار و عملگرد آن دارند اما آیا واقعا فکر می کنید گذراندن یک درس دو واحدی “برنامه نویسی” برای یاد گرفتن مهارت برنامه نویسی کافی است ؟

ممکن است فکر کنید، که کار برنامه نویسی سیستم های میکروکنترلر را می شود به مهندسین کامپیوتر واگذار است ،اما واقعا اینطور نیست؛ سیستم های میکروکنترلری دارای پیچیدگی هایی است که درک آن برای یک مهندس کامپیوتر سخت و دشوار است (البته استثنا همیشه وجود دارد) از طرفی مهندسین کامپیوتر با محدودیت های سخت افزاری آشنایی لازم را ندارد و این خود بزرگترین چالش برای آنها خواهد بود. فکر کنید یک مهندس کامپیوتر بخواهد برنامه ای بنویسد که کلا از 512 بایت RAM استفاده کند.

پس بهترین گزینه برای پر کردن خلاء برنامه نویسی سخت افزار یا همان میکروکنترلر، مهندسین الکترونیک هستند به شرط آنکه مهارت برنامه نویسی خود را بهبود ببخشند و از روش های حرفه ای برای برنامه نویسی استفاده کنند ، ما در سیسوگ سعی خواهیم کرد با مطرح کردن چالش هایی ، مهارت برنامه نویسی دوستان عزیز را محک بزنیم.

چالش برنامه نویسی این پست

امروزه که میکروکنترلر های ARM رواج پیدا کرده‌اند باعث تغییرات شگرفی در طراحی سخت افزار شده است ، پردازنده 32 بیتی که مقدار RAM و FLASH قابلی توجهی دارد و سرعت بالایی را کنار توان مصرفی کم ارائه می کند ، شما ممکن است به یاد نداشته باشید که طراحی میکروکنترلری با استفاده از Z80 یا 8086 چقدر دشوار و پیچیده بود از طرفی برنامه نویسی به زبان اسمبلی برای محاسبات ریاضی بر روی اعداد 32 بیتی یک کابوس تمام عیار بود و یا محاسبات اعشاری و ممیز شناور کار هر کسی نبود اما امروزه به لطف تکنولوژی تمام این کابوس های تلخ تبدیل به یک رویای شیرین شده است. با این همه، تکنولوژی نمی تواند برخی مسائل را حل کند ، برنامه نویسی نیز یکی از این مسائل است. برای چالش این پست فرض می کنیم که یک متغیر 32 بیتی داریم!(با توجه به وجود میکروکنترلرهای 32 بیتی ARM) و قصد داریم تعداد بیت های 1 را در این متغییر شمارش کنیم. برای روشن شدن مساله به جدول زیر توجه کنید

در واقع ما نیازی به برنامه ای داریم که اگر عدد 0xA0000500 را در ورودی دریافت کرد ، عدد 4 را در خروجی نمایش دهد. ممکن است نوشتن چنین برنامه ای کار ساده ای باشد ولی روش های مختلفی که می شود این برنامه را نوشت بررسی کنیم.

برنامه ای که همه می نویسند

قطعا ساده ترین برنامه ای که میشه نوشت برنامه بالاست ولی برنامه بالا خیلی کند عمل خواهد کرد؛ شاید برای برنامه نویس کامپیوتر که قراره برنامه بر روی یک پردازنده چند گیگاهرتزی چند هسته ای اجرا بشه ؛ شاید زیاد اهمیت نداشته باشه این مساله ولی برای اجرا روی یک پردازنده Cortex-m که فرکانس چند مگاهرتزی داره مساله بازدهی خیلی مهمه !

بگذارید اول نحوه عملکرد برنامه رو توضیح بدیم ، بعد خواهیم گفت چرا به لحاظ پرفومنسی جالب نیست ، در این روش ، ما به اندازه تعداد بیت های متغیر حلقه ایجاد کرده ایم و تک تک بیت ها رو به لحاظ یک بودن بررسی میکنیم در صورتی که بیت اول یک بود یک واحد به متغیر sum اضافه میکنیم ، بعد بیت دوم ، بعد سوم و همینطور تا آخرین بیت.

اما چرا میگیم این برنامه به لحاظ پرفومنسی بهینه نیست اولین مساله وجود حلقه است (که ظاهرا اجنتاب ناپذیره) دوم محاسباتی که توی حلقه انجام میشه همونطور که می بینید عملیات مقایسه ای داریم ، شیفت بیتی داریم عملیات منطقی(AND) و جمع داریم یعنی برای هر بار اجرای حلقه کلی محاسبه نیازه که انجام بشه ! اما چطور میشه برنامه رو بهینه کرد ؟ با مطالعه پست “میکروکنترلر مقصر نیست مقصر برنامه نویسی است” میتونید ایده بگیرد.

برنامه ای که بعد از فکر کردن می نویسید

برنامه فوق باز بهتر از برنامه قبلی شد ، چراکه یک عملیات شیفت بیتی و یک عملیات مقایسه ای رو حذف کردیم ؛ در واقع عملیات شیفت و مقایسه رو به داخل حلقه منتقل کردیم به این صورت که مقایسه با خود حلقه انجام بشه و کل متغییر به سمت چپ درون عملگر حلقه شیفت پیدا کنه ، با این صرفه جویی ها راندمان برنامه بهتر شد ولی هنوز اون مطلوبی که باید باشه نیست ؛ آیا هنوز ایده ای برای بهتر شدن برنامه دارید ؟

برنامه ای که مهندس سخت افزار مسلط به میکروکنترلر می‌نویسه

این جایی است که دید سخت افزاری و آشنایی با سخت افزار به کمک شما می آید و برنامه رو بهتر میکنه ! همونطور که می بینید حلقه که به قوت خودش باقی است ولی عملیات شیفت و And منطقی حذف شده که باعث افزیش سرعت میشه ! اما واقعا در برنامه چه اتفاقی می افته ؟ چطور سخت افزار به کمک ما میآد ؟

سری میکروکنترلر های Cortex-m قابلیتی دارند تحت عنوان Bit-Banding ؛ این قابلیت به میکروکنترلر اجازه میده که به صورت بیتی به حافظه SRAM دسترسی داشته باشد ، یعنی یک بیت از RAM رو بخونیم یا بنویسیم! از اونجایی که خانواده Cortex-m مخصوص میکروکنترلر ها توسعه پیدا کرده ، این قابلیت که کمک فراوانی به سادگی برنامه نویسی میکنه بهش اضافه شده ، اما این کار چطور ممکنه ؟ برای درک بهتر به تصور زیر دقت کنید.

قابلیت بیت بند مورد استفاده در برنامه نویسی

همانطور که در تصویر فوق مشاهده می کنید هر بیت از حافظه Sram روی یک آدرس دیگه مپ شده که با خوندن یا نوشتن اون آدرس از حافظه میشه به مقدار اون بیت دسترسی داشت.

برنامه ای که حرفه ای ها می نویسند

تا اینجا چند روش ساده رو بررسی کردم و تا جای ممکن اون روش رو با دانش برنامه نویسی و دید سخت افزاری بهینه کردیم ، اما آیا فکر می کنید باز هم میشه بهتر این برنامه رو نوشت ؟ قطعا جواب مثبت هست اما چطور ؟ برای دید بهتر به برنامه زیر دقت کنید

بله در برنامه فوق حلقه For حذف شده است و به جای آن از جدول استفاده کرده ایم ، این کار باعث افزایش چشم گیر سرعت اجرای برنامه خواهد شد ، در واقع جدول BitsSetTable256 شامل تعداد بیت های یک اعداد 0 تا 255 هست یعنی یک بایت.

این که چطور با چهار خط #define چنین جدولی را ایجاد کردیم یک چالش باشد برای شما که جوابش رو پیدا کنید. هر 32 بیت متشکل از 4 بایت است که اگر مجموع بیت های یک هر بایت را هم جمع کنیم حاصل مجموع بیت های متغیر خواهد بود.  این اتفاقی است که در ادامه کد افتاده است.

چالش انتهایی

خوب به سادگی برنامه فوق هم میشه این کار رو انجام داد!اما این برنامه دقیقا چطور کار میکنه ؟

این روشی نیست که همه بخوان ازش استفاده کنند؛ نوشتنش که هیچ ، حتی درک این که چطور این برنامه کار میکنه هم کار هر کسی نیست !

آیا کسی میتونه بگه چطور این برنامه کار میکنه ؟

حمایت از Zeus ‌

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

1 نفر

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

توجه

Zeus ‌
Zeus ‌

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

دیدگاه ها

17 دیدگاه

  • mhsh
    ۱۲ آذر ۱۴۰۰

    سلام. ممنون ازین مطلب عالی.
    بنظرتون اگه بخوایم از لحاظ سرعت اجرا برسی کنیم کدی که از جدول استفاده میکنه سریع تره یا کدی که تو چالش انتهایی نوشته شده؟

    • Zeus ‌
      Zeus
      ۱۳ آذر ۱۴۰۰

      قطعا جدول سریعتره – چون فقط به اندازه یک دسترسی به حافظه زمان میبره 🙂

  • امیرحسین روزیطلب
    ۹ آذر ۱۴۰۰

    احساس پوچی کردم ای بابا :)))

    • Zeus ‌
      Zeus
      ۱۳ آذر ۱۴۰۰

      چرا احساس پوچی دوست عزیز !‌
      تا وقتی میشه چیزای جدید یاد گرفت، جای بسیار زیادی برای امیدواری هست

  • امیرحسین اریا
    ۲۳ خرداد ۱۳۹۹

    سلام. ممنون از سایت خوبتون. یه سوال داشتم. من برنامه نویسی avr كار كردم و از سخت افزار هم تا حدودی سر در میارم. سال بعد دانشكاه میرم. خواستم ببینم arm یاد بگیرم بهاره یا ای وی ار رو ادامه بدم. و این كه شركت های بزرك مثلا تسلا یا اسپیس ایكس و… كه پیچیده ترین كد نویسی ها رو برای سخت افزار انجام میدن از چه تراشه هایی استفاده میكنن؟ آیا تراشه های arm به اندازه كافی قدرت دارن؟ اكر كسی بخواد برنامه نویسی در اون حد بیشرفته رو یاد بگیره باید چیكار كنه؟

    • Zeus ‌
      زئوس Zeus
      ۲ تیر ۱۳۹۹

      سلام دوست من – خودتون محدود به نوع پردازنده نکن
      هر میکروکنترلری برای هدفی ساخته شده و اینطور نیست مثلا با یادگیری یک مدل پردازنده همه کارهایی که میخوای بکنی رو بتونی پوشش بدی – اگه بخوام بهت توصیه ای داشته باشم میگم اصول رو یاد بگیر از بیس یاد بگیر
      مثلا پروتکل uart یه استاندارده که همه جا به همون شکل هندل میشه – حالا از یه میکرو به میکروی دیگه فقط چند تا رجیستر تغییر میکنه به همین سادگی !!!
      شرکت های بزرگ بسته به کاری که میخوان انجام بدن سخت افزار رو انتخاب می کنند.

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

      بله متشکر

    • shm
      ۸ مهر ۱۳۹۸

      مطالب لینکی که بالا دادم فوق العادست برای همین Counting bits set اومده ۷ روش روگفته
      کلی چالش دیگه هم داره
      —سوال —-
      منبع کامل آموزش دقیق C با رویکرد embedded چیزی معرفی می کنید؟ مثلا همین volatile رو خیلی جاها توضیح نداده

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

        چالش های دیگه اش هم جالبه 🙂
        — جواب —
        نه متاسفانه ؛ فکر نمیکنم زبان سی فرقی بین امبدد و خیر امبدد داشته باشه ؛ شناخت از سیستم های امبدد هست که کمک میکنه برنامه شما خاص اون سخت افزار باشه یا نباشه

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

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

  • محمد
    ۲۶ شهریور ۱۳۹۸

    سلام ممنون از سایت خوبتون. اما کاش منابع رو هم ذکر میکردید. تا الان که توی سایت میگشتم هیچ پستی منبع نداره.
    وقتی خودتون اصرار دارید مطالب با منبع ذکر بشن پس بهتره خودتون هم منبع رو ذکر کنید?

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

      سلام دوست گرامی
      تمام مطالبی که ترجمه هستند یا از منبعی بازنشر شده باشند دارای منبع هستند ِ به عنوان نمونه تمام آموزش های STM8 یا آموزش ها و رفرنس Arduino و… همه دارای منبع هستند ِ اگر میبینید مطلبی دارای منبع نیست ِ‌یعنی از اول نوشته شده توسط نویسنده نه این که از جایی کپی شده باشد که نیاز به ذکر منبع داشته باشد
      فکر میکنم همه سایت رو ندیدید !!!

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

    (unsigned char *) &data; این یعنی چی

    • Zeus ‌
      زئوس Zeus
      ۲۷ مرداد ۱۳۹۸

      سلام ؛
      &data در واقع آدرس حافظه ای که متغییر data توی اون ذخیره شده رو بر میگردونه ؛ خوب حالا این حافظه از چه نوعی هست ؟ خوب معلومه دیگه static const unsigned char ؛ وقتی بخوایم اونو تو یه اشاره‌گر از نوع unsigned char بریزیم کامپایلر خطا میده ! برای این که با این خطا مواجه نشیم با این شکل نوشتاری ((unsigned char *) &data;) به کامپایلر میگیم داداش تو فکر کن متغییر ما از نوع unsigned char* هستش 🙂

  • حسین
    ۳۱ اردیبهشت ۱۳۹۸

    با سلام و خسته نباشید .
    اون کدی که با چند خط دیفاین جول رو تولید میکنه داره از توابع بازگشتی استفاده میکنه و این خطB6(0), B6(1), B6(1), B6(2) درواقع کل جدول رو تولید میکنه .به این صورت کهB2(n) مربوط به اعداد 2بیتی است .و B2(0) میشه 0,1,1,2
    اگر برای اعداد 3 بیتی هم بخواهیم محاسبه کنیم 0,1,1,2,1,2,2,3 اگر کمی دقت کنیم دنباله مربوط به 3 بیتی میشهB2(0),B2(1) یا به طور کلی B3(n)=B2(n),B2(n+1)
    به طور خلاصه هر بار که یک بیت به طول عدد اضافه میشه دنباله جدید عبارت است از دنباله مربوط به حالت قبلی که جملاتش 1 واحد اضافه شده و در ادامه دنباله قبلی اومده . به طور مثال برای 4 بیت میشه B3(0),B3(1) که اگر به جای b3 معادل اون بر اساس b2 رو بنویسیم میشه
    B2(0),B2(1),B2(1),B2(2) که در حالت کلی B4(n)=B2(n),B2(n+1),B2(n+1),B2(n+2) که همون فرمول جدول هست منتها برای صرفه جویی حالتهای B3(n) و B5 و B7 حذف شدن . و فرمولها مستقیم بر اساس 2 مرحله قبل نوشته شدن .

    ولی کد آخری فهمیدنش واقعا مشکل هست!!!

    • 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 ‌
  • 11 ماه پیش

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

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

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

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

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

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

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

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

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

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

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

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

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