درک فیوزبیت های AVR برای بهبود عملکرد برد آردوینو

در این آموزش قصد داریم درباره فیوزها صحبت کنیم. زمانی که در دوران دانشگاه بودم و در حال یادگیری مفاهیم جذاب الکترونیک بودم، برای اولین بار اصطلاح Fuse را در AVR شنیدم. اولین برداشتم این بود که احتمالاً قطعهای درون AVR وجود دارد که اگر اشتباهی انجام دهم، خواهد سوخت. در آن زمان منابع زیادی در اینترنت برای بررسی این موضوع در دسترس نبود. جستجوی زیادی انجام دادم تا متوجه شوم این فیوزها در واقع به بیتهای خاصی درون میکروکنترلر AVR اشاره دارند. این بیتها مانند کلیدهای کوچکی در داخل AVR هستند و با فعال یا غیرفعال کردن آنها میتوان برخی قابلیتهای ویژه AVR را روشن یا خاموش کرد. منظور از روشن و خاموش کردن، تنظیم (Set) و ریست (Reset) کردن این بیتها است.
در این فرصت قصد داریم به طور کامل Fuse Bits در AVR را بررسی کنیم. برای سادهتر شدن موضوع، از برد Arduino که شامل میکروکنترلر محبوب ATmega328P است به عنوان مثال استفاده میکنیم. در اینجا یاد خواهید گرفت چگونه این فیوزها را برای فعال یا غیرفعال کردن برخی ویژگیها تنظیم کنید؛ قابلیتی که در پروژههای عملی و کاربردهای واقعی بسیار مفید است. بنابراین بدون اتلاف وقت، شروع میکنیم.
در مطالب قبلی، پروژههای متعددی با میکروکنترلرهای AVR ساختهایم، مانند ارتباط ماژول GSM با میکروکنترلر AVR و ارتباط ماژول HC-05 با میکروکنترلر AVR. اگر علاقهمند هستید میتوانید آنها را بررسی کنید تا درک عمیقتری از این پروژهها به دست آورید.
فیوز بیت در AVR
همانطور که پیشتر اشاره شد، فیوزها در میکروکنترلر مانند کلیدهای کوچکی هستند که میتوان آنها را فعال یا غیرفعال کرد تا قابلیتهای مختلف میکروکنترلر AVR فعال یا غیر فعال شوند. در اینجا سؤال مهمی مطرح میشود: چگونه این فیوزها را تنظیم یا ریست کنیم؟ پاسخ ساده است؛ این کار از طریق رجیسترهای فیوز (Fuse Registers) انجام میشود.
در آیسی ATmega328P در مجموع 19 بیت فیوز وجود دارد که در سه بایت فیوز تقسیمبندی شدهاند. این بایتها شامل Extended Fuse Byte، High Fuse Byte و Low Fuse Byte هستند.
اگر به جدول 27 در دیتاشیت ATmega328/P با نسخه Rev: 7810D–AVR–01/15 مراجعه کنید، میتوانید تمامی جزئیات مربوط به بیتهای فیوز را مشاهده کنید. با این حال، تصویر مربوط به این بخش در دیتاشیت دید واضحتری از ساختار فیوزها ارائه میدهد.

اکنون که آشنایی اولیه با بیتهای فیوز پیدا کردید، به دیتاشیت مراجعه میکنیم تا جزئیات لازم درباره این آیسی را بررسی کنیم.
Extended Fuse Bits:
با مراجعه به بخش Fuse Bits در دیتاشیت و کمی اسکرول کردن، جدول 27-5 را مشاهده خواهید کرد که مربوط به Extended Fuse Byte یا همان EFUSE است.

در این جدول تنها سه بیت قابل استفاده هستند و سه بیت دیگر رزرو شدهاند. این سه بیت مربوط به سطح Brown-out Detection هستند. همانطور که در بخش Note و جدول 28-5 مشاهده میکنید، جزئیات بیشتری درباره آن ارائه شده است.

همانطور که در جدول مشاهده میشود، Brown-out Detection قابلیتی است که در صورت کاهش ولتاژ تغذیه به کمتر از یک سطح مشخص، میکروکنترلر را ریست میکند. در ATmega328P میتوان Brown-out Detection را به طور کامل غیرفعال کرد یا آن را روی سطوح مشخصشده در جدول تنظیم نمود.
High Fuse Bytes:
مطابق جدول 27-6 در دیتاشیت، بیتهای High Fuse در ATmega328P نمایش داده شدهاند.

بایت High Fuse وظایف متعددی را در میکروکنترلر ATmega328 مدیریت میکند. در این بخش، عملکرد بیتهای مهم آن را بررسی میکنیم. ابتدا به بیتهای BOOTRST، BOOTSZ0 و BOOTSZ1 میپردازیم. این سه بیت اندازه Boot Size را تعیین میکنند؛ Boot Size به میزان حافظه رزرو شده برای نصب Bootloader اشاره دارد.
Bootloader یک نرمافزار ویژه است که روی میکروکنترلر اجرا میشود و وظایف مختلفی را مدیریت میکند. در برد Arduino، Bootloader برای آپلود کردن Sketch در میکروکنترلر استفاده میشود. در یکی از مقالات قبلی، روش Burn کردن Bootloader در ATmega328P با استفاده از Arduino توضیح داده شده است. سایر بیتهای High Fuse نیز کاربردهای مشخصی دارند. بیت EESAVE برای حفظ حافظه EEPROM در هنگام اجرای عملیات Chip Erase استفاده میشود. بیت WDTON برای فعال یا غیرفعال کردن Watchdog Timer به کار میرود.
Watchdog Timer یک تایمر مستقل در ATmega328P است که کلاک جداگانه دارد و به صورت مستقل اجرا میشود. اگر فعال باشد، باید در بازه زمانی مشخص ریست شود؛ در غیر این صورت، میکروکنترلر را ریست خواهد کرد. این ویژگی برای جلوگیری از قفل شدن پردازنده بسیار مفید است و از بروز خطا در کاربرد نهایی جلوگیری میکند.
بیت DWEN برای فعالسازی DebugWire استفاده میشود؛ پروتکلی که به صورت داخلی در سختافزار تعبیه شده و برای پروگرام و دیباگ کردن پردازندهها کاربرد دارد. با فعال بودن این قابلیت میتوان با استفاده از یک سیم، پردازنده را پروگرام و دیباگ کرد. البته برای استفاده از آن به سختافزار اختصاصی Atmel نیاز است.
دو بیت باقیمانده، بیتهایی هستند که باید از تغییر آنها خودداری کنید مگر اینکه کاملاً از عملکرد آنها آگاه باشید. این بیتها شامل RSTDISBL (بیت 7) و SPIEN (بیت 5) هستند. بیت RSTDISBL پین ریست سختافزاری خارجی را غیرفعال میکند و بیت SPIEN رابط برنامهریزی SPI را غیرفعال میکند. غیرفعال کردن هر یک از این دو بیت ممکن است باعث از کار افتادن کامل AVR شود، بنابراین بهتر است بدون نیاز آنها را تغییر ندهید.
Low Fuse Bytes:
مطابق جدول 27-7 در دیتاشیت، بیتهای Low Fuse در ATmega328P نمایش داده شدهاند.

این بایت فیوز مسئول تنظیم منبع کلاک و برخی پارامترهای مرتبط با کلاک در AVR است. در این بخش، این تنظیمات را بررسی میکنیم.
بیت 7 یا CKDIV8 میتواند برای تقسیم منبع کلاک بر 8 تنظیم شود؛ قابلیتی که هنگام پروگرام کردن AVR بسیار کاربردی است. بیت 6 یعنی CKOUT در صورت پروگرام شدن، سیگنال کلاک داخلی را روی پین PORTB0 خروجی میدهد.
بیتهای 5 و 4 یعنی SUT1 و SUT0 زمان راهاندازی میکروکنترلر را کنترل میکنند. این ویژگی از اجرای نادرست عملیات راهاندازی پیش از رسیدن ولتاژ تغذیه به سطح پایدار جلوگیری میکند. چهار بیت پایانی CKSEL0 تا CKSEL3 برای انتخاب منبع کلاک میکروکنترلر استفاده میشوند. جدول مربوط به انتخاب منبع کلاک در بخش Clock Source دیتاشیت قابل مشاهده است.

پیش از ادامه، لازم است به جدول تأخیر راهاندازی اسیلاتور اشاره کنیم. تأخیر راهاندازی به بیتهای 4 و 5 بایت Low Fuse مربوط میشود. مقدار این تأخیر بسته به شرایط کاری مدار و نوع اسیلاتور مورد استفاده تنظیم میشود. مقدار پیشفرض برای شرایط Slow Rising Power برابر با 6 سیکل کلاک هنگام اجرای توالی Power-up یا Power-down است. علاوه بر آن، پس از راهاندازی، تأخیری برابر با 14 سیکل کلاک همراه با 65 ms تأخیر اعمال میشود.

با وجود حجم زیاد اطلاعات، پیش از ادامه لازم است به یک نکته مهم اشاره کنیم.
اگر دیتاشیت را با دقت بررسی کرده باشید، متوجه شدهاید که پروگرام کردن یک بیت فیوز به معنای تنظیم آن روی سطح Low یعنی 0 است؛ که برخلاف روال معمول تنظیم پورتها به High یا Low است. هنگام پیکربندی Fuse Bits باید این نکته مهم را در نظر داشته باشید.
فیوز بیت ها در آردوینو
در بخش قبلی به طور مفصل درباره Fuse Bits در AVR صحبت کردیم، اما در این بخش به نحوه پیکربندی و نوشتن آنها در میکروکنترلر میپردازیم. برای این کار به ابزاری به نام Avrdude نیاز داریم. Avrdude یک ابزار قدرتمند برای خواندن، نوشتن و ویرایش حافظه در میکروکنترلرهای AVR است. این ابزار از طریق رابط SPI کار میکند و از طیف گستردهای از پروگرامرها پشتیبانی میکند. میتوانید این ابزار را از لینک زیر دانلود کنید. همچنین در این آموزش از میکروکنترلر محبوب Arduino استفاده خواهیم کرد.
http://download.savannah.gnu.org/releases/avrdude/avrdude-6.3-mingw32.zip
پس از دانلود Avrdude، باید فایل را استخراج کرده و در همان پوشه یک پنجره Command باز کنید. در صورت نیاز میتوانید مسیر پوشه را به Environment Variables ویندوز اضافه کنید تا در آینده دسترسی سادهتری داشته باشید. در این مثال، پوشه را روی Desktop قرار داده و از همانجا Command Window را باز میکنیم. سپس پروگرامر USBasp را به کامپیوتر متصل کرده و اطمینان حاصل میکنیم که درایور مناسب آن نصب شده است. پس از انجام این مراحل، ابتدا مقدار پیشفرض Fuse Bits را میخوانیم. برای این کار باید دستور زیر را اجرا کنید.
avrdude.exe -c usbasp -p m328p -U lfuse:r:low_fuse_val.txt:h -U hfuse:r:high_fuse_val.txt:h -U efuse:r:ext_fuse_val.txt:h
اگر همهچیز به درستی تنظیم شده باشد، این دستور بایتهای فیوز را خوانده و آنها را در سه فایل متنی جداگانه ذخیره میکند.

همانطور که مشاهده میکنید، Avrdude فیوز بیتهای Arduino Nano را خوانده و در سه فایل متنی مجزا ذخیره کرده است. پس از باز کردن این فایلها، سه مقدار به دست آمد: برای EFUSE مقدار 0xFD، برای HFUSE مقدار 0xDA و برای LFUSE مقدار 0xFF. اینها مقادیر پیشفرض فیوز در Arduino Nano هستند. اکنون این مقادیر را به مبنای باینری تبدیل کرده و با مقادیر پیشفرض دیتاشیت مقایسه میکنیم. جدول زیر این مقایسه را نشان میدهد.
برای سهولت، Fuse Bits به صورت مقادیر هگزادسیمال نوشته میشوند؛ اما با تبدیل آنها به باینری و مقایسه با دیتاشیت، میتوانیم عملکرد دقیق آنها را درک کنیم. ابتدا Low Fuse Byte را بررسی میکنیم. همانطور که مشاهده میشود مقدار آن 0xFF است که در مبنای باینری برابر با 0B11111111 خواهد بود.
مقایسه Low Fuse پیشفرض AVR با آردوینو
| Low Fuse Byte | شماره بیت | پیشفرض AVR | پیشفرض آردوینو |
| CKDIV8 | 7 | 0 (programmed) | 1 (unprogrammed) |
| CKOUT | 6 | 1 (unprogrammed) | 1 (unprogrammed) |
| SUT1 | 5 | 1 (unprogrammed) | 1 (unprogrammed) |
| SUT0 | 4 | 0 (programmed) | 1 (unprogrammed) |
| CKSEL3 | 3 | 0 (programmed) | 1 (unprogrammed) |
| CKSEL2 | 2 | 0 (programmed) | 1 (unprogrammed) |
| CKSEL1 | 1 | 1 (unprogrammed) | 1 (unprogrammed) |
| CKSEL0 | 0 | 0 (programmed) | 1 (unprogrammed) |
High Fuse Byte روی مقدار 0xDA تنظیم شده است که در مبنای باینری برابر با 0B11011010 میباشد.
High Fuse Byte در مبنای باینری
| High Fuse Byte | شماره بیت | پیشفرض AVR | پیشفرض آردوینو |
| RSTDISBL | 7 | 1 (unprogrammed) | 1 (unprogrammed) |
| DWEN | 6 | 1 (unprogrammed) | 1 (unprogrammed) |
| SPIEN | 5 | 0 (programmed) | 0 (programmed) |
| WDTON | 4 | 1 (unprogrammed) | 1 (unprogrammed) |
| EESAVE | 3 | 1 (unprogrammed) | 1 (unprogrammed) |
| BOOTSZ1 | 2 | 0 (programmed) | 0 (programmed) |
| BOOTSZ0 | 1 | 0 (programmed) | 1 (unprogrammed) |
| BOOTRST | 0 | 1 (unprogrammed) | 0 (programmed)) |
Extended Fuse Byte نیز روی مقدار 0xFD تنظیم شده است که در مبنای باینری برابر با 0B11111101 میباشد.
Extended Fuse Byte در مبنای باینری
| Extended Fuse Byte | Bit No. | پیشفرض AVR | پیشفرض آردوینو |
| – | 7 | 1 | 1 |
| – | 6 | 1 | 1 |
| – | 5 | 1 | 1 |
| – | 4 | 1 | 1 |
| – | 3 | 1 | 1 |
| BODLEVEL2 | 2 | 1 (unprogrammed) | 1 (unprogrammed) |
| BODLEVEL1 | 1 | 1 (unprogrammed) | 0 (programmed) |
| BODLEVEL0 | 0 | 1 (unprogrammed) | 1 (unprogrammed) |
با این بخش، توضیحات تئوری مربوط به Fuse Bits در AVR به پایان میرسد. تاکنون با ساختار و عملکرد فیوز بیتهای میکروکنترلر AVR آشنا شدیم. اکنون برای تکمیل آموزش، این مفاهیم را به صورت عملی در Arduino Nano آزمایش میکنیم.
قطعات مورد نیاز برای تست Fuse Bits در AVR
در بخشهای قبلی درباره مفاهیم تئوری صحبت کردیم، اما برای ادامه مقاله به برخی قطعات سختافزاری و ابزارهای نرمافزاری نیاز داریم. فهرست قطعات موردنیاز در ادامه آمده است.

- برد بورد
- برد آردوینو نانو
- پروگرامر USBasp
- کابل USB
- مبدل 10 به 6 پین AVR
- LED
- مقاومت 330 اهم
- سیم جامپر
شماتیک تست Fuse Bits در AVR
چیدمان سختافزاری در تصویر زیر نشان داده شده است. در این پیکربندی، Arduino Nano از طریق کابل USB به کامپیوتر متصل شده و همچنین پروگرامر USBasp نیز به کامپیوتر وصل است. هدف این آموزش برنامهریزی Fuse Bits در AVR است؛ بنابراین USBasp به Arduino متصل شده تا عملیات پروگرام انجام شود.

تست عملی تنظیم فیوز بیت
ستاپ تست در تصویر زیر قابل مشاهده است. همانطور که میبینید، Arduino و پروگرامر USBasp هر دو به پورت USB لپتاپ متصل شدهاند.

اکنون Arduino IDE را باز کرده و یک برنامه ساده Blink را آپلود میکنیم. عملکرد این برنامه کاملاً مشخص است و نیازی به توضیح بیشتر ندارد.
مشاهده خواهید کرد که LED متصل به پین 13 به درستی چشمک میزند. اکنون تنظیمات فیوز را تغییر داده و آن را به مقادیر پیشفرض دیتاشیت برمیگردانیم. همانطور که قبلاً بررسی شد، مقدار EFUSE برابر 0xFF، مقدار HFUSE برابر 0xD9 و مقدار LFUSE برابر 0x62 است. اکنون با استفاده از Avrdude این مقادیر را پروگرام میکنیم و نتیجه را بررسی میکنیم. دستور مورد استفاده به صورت زیر است:
avrdude -c usbasp -p m328P -U lfuse:w:0x62:m -U hfuse:w:0xd9:m -U efuse:w:0xff:m

پس از اجرای این دستور، مشاهده خواهید کرد که LED بسیار کند چشمک میزند. دلیل این موضوع آن است که برنامه برای کلاک 16MHz کامپایل شده بود، اما پس از تغییر فیوزها، میکروکنترلر از اسیلاتور داخلی 1MHz استفاده میکند. به همین دلیل سرعت اجرای برنامه کاهش یافته است. اکنون اگر دوباره بخواهیم برنامهای را آپلود کنیم، Arduino با خطا مواجه میشود و کد آپلود نخواهد شد. زیرا با تغییر فیوزها، تنظیمات Bootloader نیز دچار اختلال شده است.

برای رفع این مشکل و بازگرداندن Arduino به حالت اولیه، کافی است Bootloader را مجدداً روی برد پروگرام کنیم. برای این کار به مسیر Tools -> Programmer -> USBasp رفته و سپس گزینه Burn Bootloader را انتخاب کنید. با انجام این کار، Bootloader پیشفرض دوباره روی Arduino نوشته شده و تنظیمات به حالت اولیه بازمیگردد.

پس از پروگرام مجدد Bootloader، Arduino به وضعیت اولیه خود بازمیگردد و LED دوباره با سرعت عادی چشمک خواهد زد.
در اینجا این مقاله به پایان میرسد. امیدواریم این آموزش درباره Fuse Bits در AVR و نحوه تنظیم آنها در Arduino برای شما مفید بوده باشد. در صورت داشتن هرگونه سؤال درباره این مقاله، میتوانید آن را در بخش نظرات مطرح کنید.







