قسمت ۰ : شروع برنامه نویسی AVR

اگه با بردهای آردینو (Arduino) کار کرده باشی‌، احتمالا تو هم با لذت سادگی برنامه نویسی و آپلود کردن کد روی برد و بعدش تماشای چشمک زدن LED با گرفتن ورودی از سنسورهایی که به بردت وصل کردی آشنایی؛ ولی زیر این ظاهر کاربر پسند و راحت آردینو، دنیای قدرتمند برنامه نویسی ماشین بدون واسطه (bare-metal) و میکروکنترلرهای AVR قایم شدن؛ دنیایی که توش هر چرخه پردازنده و پین و رجسیترها رو کنترل میکنی.

به عنوان یک توسعه دهنده که تصمیم به مهاجرت از اکوسیستم آردینو، به C خالص روی تراشه های AVR رو داره، در مسیر باز کردن دروازه هایی از بهینه سازی، کارایی بیشتر، و درک عمیقتر از سیستم های تعبیه شده (embedded systems) هستید.

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


میکرو کنترلر AVR چیست و چرا هنوز استفاده میشوند؟

میکروکنترلرهای AVR تراشه های ۸ بیتی مبتنی بر RISC هستند که توسط Atmel توسعه یافته اند، از دهه ۱۹۹۰ میلادی مغز متفکر پروژه های بسیار زیادی مثل ترموستات های هوشمند، کنترلر های از راه دور و حتی برخی از سیستم های خودرو ها بوده اند. از مدل های محبوب این سری از میکروکنترلرها میتوان به ATmega328P که در آردینو مدل Uno استفاده میشود اشاره کرد. مدلی که ما در این مجموعه به دلیل پین های ورودی خروجی زیاد و حافظه مناسبش از آن استفاده میکنیم؛ ATmega16 هست.

AVR ها از معماری هاروارد استفاده میکنند که در آن حافظه برنامه و داده ها جدا از یکدیگر میباشد و شامل حافظه فلش برای ذخیره سازی کدها، SRAM برای متغیرهای زمان اجرا و EEPROM برای داده های پایدار است. آنها همچنین از دستگاه های جانبی مثل تایمرها، مبدل های آنالوگ به دیجیتال (ADCمدولاسیون پهنای پالس (PWM) و ارتباط سریال پشتیبانی میکنند.

بخش های تشکیل دهنده یک تراشه AVR

اما در دنیایی که تحت سلطه تراشه های ARM 32 مثل Raspberry Pi Pico یا STM32 است و در سال ۲۰۲۵ چه دلیلی برای یادگیری برنامه نویسی برای میکروکنترلر ۸ بیتی وجود دارد ؟

۱. ساده و کم مصرف

avr ها سبک هستند و در حالت فعال در حد میلی وات و در حالت خواب در حدود میکرو وات مصرف میکنند و این ویژگی ها یعنی سبکی و مصرف کم باعث میشود که برای استفاده دستگاه های پوشیدنی یا اینترنت اشیا باتری دار مناسب باشند.

۲. مقرون به صرفه و در دسترس

تراشه هایی مثل ATmega16 در حدود ۳ دلار (۲۷۰ هزار تومان امروز) قیمت دارند و قیمت آنها برای استفاده در تولید انبوه به نسبت بردهای آردینو با قیمت هایی که از ۱۵ دلار شروع میشوند به شدت توجیح اقتصادی دارد.

۳. ارزش آموزشی و جامعه برنامه نویسان

برنامه نویسی AVR مهارت هایی را آموزش میدهد که حتی در برنامه نویسی آٰردینو هم به شما کمک میکند. همچنین کتابخانه های متن باز مثل AVR libc و منابع گسترده آنلاین مثل انجمن ها و مطالب زیادی برای این کار در دسترس است که شما را در این مسیر همراهی میکنند.

اگر شما یک کاربر آردینو هستید که به دنبال نوشتن برنامه های بهینه، کم مصرف و سریع قابل اجرا بر روی تراشه های ارزان قیمت و امکان تولید و فروش انبوه محصولات خود هستید، برنامه نویسی AVR همراه شما در این مسیر خواهد بود.


برنامه نویسی با C در مقابل آردینو

آردینو با محیط توسعه Arduino IDE و بردهای آماده استفاده خودش، برنامه نویسی میکروکنترلر رو راحت تر کرده ولی این راحتی استفاده با خودش یک سری تفاوت هایی نسبت به برنامه نویسی AVR با C خالص رو به همراه داره که این تفاوت ها شامل موارد زیر میشوند:

۱. لایه انتزاعی

توابع آردینو مثل digitalWrite یا analogRead جزییات اتفاقاتی که در رجسیتر رخ میدن رو از برنامه نویس میپوشونند و کدهای نوشته شده رو خواناتر و قابل حمل میکنند ولی این ویژگی به قیمت از بین رفتن بهینگی کد شما خواهد بود. برای مثال در AVR برای تغییر مقدار باینری یک پین خروجی، مستقیما مقدار رجسیتر مربوط به اون پین (مثلا DDRB) تغییر میدیم که باعث میشه ‍overhead کمتری در کدمون داشته باشیم.

۲. بوت لودر در برابر فلش مستقیم کد

آردینو از بوت لودری استفاده میکنه که امکان آپلود کردن کدها از طریق USB و استفاده از کدهای آردینویی رو برامون فراهم میکنه ولی این بوت لودر حدود ۲ کیلوبایت از حجم فلش رو اشغال میکنه و باعث به وجود اومدن تاخیری در بوت شدن میکروکنترلر ما میشه. استفاده از AVR ساده با C بجای این کار، مستقیما کدهای شما رو از طریق ISP در حافظه فلش میکروکنترلر ذخیره میکنه و این حجم اضافی اشغال شده رو برای کد شما آزاد میکنه.

۳. عملکرد و بهینه سازی

کتابخانه های آردینو راحتی رو به همراه دارند ولی حجم بالای رو اشغال میکنند. با استفاده از C خالص، شما سرعت و حجم کدتون رو بهینه میکنید که این ویژگی برای وظایف لحظه ای و حساس به زمان و سرعت حیاتی هست.

۴. انعطاف پذیری سخت افزاری

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

۵. اشکال زدایی و منحنی یادگیری

آردینو با سریال مانیتور، روند اشکال زدایی و تشخیص ایرادها رو راحت تر میکنه ولی در هنگام برنامه نویسی AVR ها امکانات شما به LED ها و آنالیزورهای منطقی یا URART محدود میشود؛ که ماه عسل این محدودیت ها آشنایی بیشتر شما میکروکنترلرها میباشد.

مهاجرت به برنامه نویسی با C باعث تقویت مهارت کد نویسی شما، افزایش دانش سخت افزاری، تقویت مهارت خواندن datasheet ها و آماده کردن شما برای برنامه نویسی سایر میکروکنترلرها میشود. اگر در هنگام استفاده از آردینو احساس محدودیت میکنید، زبان C خام قدم بعدی شما در راستای استقلال از محدودیت های آردینو خواهد بود.


نصب ابزار های مورد نیاز برنامه نویسی AVR

برای برنامه نویسی AVR ها با زبان C به یک سری ابزار (toolchain) نیاز دارید :

  • کامپایلر avr-gcc

  • آپلودر کد avrdude

  • اتوماسیون ساخت make

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

اوبونتو (ubuntu) یا توزیع های مبتنی بر دبیان

sudo apt update
sudo apt install gcc-avr binutils-avr avr-libc avrdude make

فدورا (Fedora)

sudo dnf install avr-gcc avr-binutils avr-libc avrdude make

آرچ (Arch)

sudo pacman -Syu avr-gcc avr-binutils avr-libc avrdude make

ویندوز (Widnows)

برای ویندوز روش های مختلفی وجود دارد که بعضی از آنها منسوخ شده اند و پشتیبانی از آنها توسط توسعه دهندگان صورت نمیگیرد ولی ما از یک محیط POSIX به نام MSYS2 استفاده میکنیم که به ما امکان استفاده از پکیج های مورد نیازمان را در ویندوز میدهد.

ابتدا MSYS2 را از این لینک دانلود و نصب کنید؛ سپس ترمینال آن را باز و دستورات زیر را وارد کنید.

pacman -Syu
pacman -S mingw-w64-x86_64-avr-gcc mingw-w64-x86_64-avr-libc mingw-w64-x86_64-avrdude make

و پس از آن محل فایل های باینری MSYS2 را (معمولا C:\msys64\mingw64\bin) به متغیر PATH ویندوز خود اضافه کنید.

چک کردن نصب صحیح ابزارها

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

avrdude -v
make --version
avr-gcc --version

همچین برای چک کردن نصب بودن بقیه موارد میتوانید یک فایل به نام test.c بسازد و در آن خط زیر را بنویسید

#include <avr/io.h> int main(){return 0;}

و اجرای موفق این فرمان

avr-gcc -mmcu=atmega16 -o test.elf test.c

به معنی نصب موفقیت آمیز کامپایلر شما میباشد.

برای نوشتن راحت تر کدها و فایل های make میتوانید از vscode با افزونه های مربوطه استفاده کنید.


سخت افزارهای مورد نیاز در این دوره

میکروکنترلر MCU

میکروکنتلر ATmega16 که پردازنده اصلی ما با ۱۶ کیلوبایت حافظه فلش، ۱ کیلوبایت حافظه متغیرهای دائمی، ۵۱۲ بیت SRAM و ۳۲ پین ورودی و خروجی خواهد بود که در هنگام کار با LCD از آنها استفاده میکنیم.

پروگرمر Programmer

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

لوازم دیگر

یک بردبورد breadboard و تعدادی سیم و led های کوچک دو پایه به مقدار لازم :)

مقاومت های ۲۲۰ اهم برای led ها، چند دکمه و مقاومت های ۱۰ کیلو اهم برای استفاده های دیگر.

پتانسیومتر یک یا دو عدد (در پروژه استفاده نمیشود ولی میتوانید برای تغییر کنتراست یا روشنایی تصویر LCD از آنها استفاده کنید؛ همچین برای دریافت ورودی آنالوگ در صورت نیاز به آن احتیاج خواهید داشت.)

منبع تغذیه ۵ ولت که ما باز هم از آردینو استفاده میکنیم ولی شما میتونید از ترکیب یک آداپتور ۵ ولت با خازن برای تثبیت ولتاژ در صورت نیاز استفاده کنید.

یک LCD سازگار با HD44780 با قابلیت نمایش 16x2 کرکتر

چیدمان

میکروکنتلر را طوری در وسط برد قرار بدهید که تمامی پین های آن در سوراخ های دو طرف شیار وسط بردبورد قرار بگیرند. در گوگل pinout میکروکنتلر خود را سرچ کنید (مثلا Atmega16a pinouts) و با توجه به تصاویر موجود در سایت ها و دیتاشیت میکروکنتلر :

  • پین های VCC و AVCC را به سمت مثبت (در ATmega16 پین های ۱۰ و ۳۰)

  • و پین های GND میکروکنتلر را به قطب منفی (در ATmega16 پین های ۱۱ و ۳۱)

منبع تغذیه خود متصل کنید.

جمع بندی

الان دیگه هرچیزی که برای برنامه نویسی میکروکنترلر AVR نیاز بوده رو نصب و تهیه کردید و آماده اید که برنامه نویسی آردینو رو کنار بزارید و توی مهارت کدنویسی با C مسلط بشید.

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