داده volatile در برنامه نویسی آردوینو (کلیدواژه volatile)

volatile یک کلمه کلیدی است که به عنوان یک متغیر شناخته می شود، معمولاً قبل از نوع داده یک متغیر برای اصلاح روش استفاده از کامپایلر و برنامه بعدی با متغیر استفاده می شود.
متغیر volatile یک دستورالعمل برای کامپایلر است. به طور خاص ، volatile کامپایلر را به دریافت متغیر از RAM (و نه از یک رجیستر ذخیره سازی) هدایت می کند. RAM یک حافظه موقت است که متغیرهای برنامه در آن ذخیره و دستکاری می شوند. تحت شرایط خاص ، مقدار یک متغیر ذخیره شده در ثبات ها می تواند نادرست باشد. هر زمان که مقدار متغیر توسط چیزی خارج از کنترل قسمت کدی که در آن ظاهر می شود تغییر کند باید متغیر به صورت volatile ایجاد شود. در برنامه نویسی آردوینو اغلب در ایجاد وقفه ها از متغیر های volatile استفاده میشود.
volatile های long و int
اگر متغیر volatile از یک بایت (معادل 8 بیت) بزرگتر باشد، میکروکنترلر نمیتواند آن را بخواند زیرا میکروکنترلر مورد استفاده 8 بیتی است. یعنی در حالی که بخش اصلی کد شما (مثلا قسمت loop) 8 بیت اول متغیر را میخواند، وقفه ممکن است 8 بیت دیگر را تغییر دهد.
نمونه کد با متغیر volatile
اصلاح کننده فرار اطمینان حاصل می کند که تغییرات متغیر حالت بلافاصله در حلقه قابل مشاهده هستند (). بدون تعدیل کننده فرار ، ممکن است متغیر حالت در هنگام ورود به تابع در یک رجیستر بارگیری شود و تا پایان کار دیگر به روز نمی شود.
// روشن کردن ال ای دی در صورت تغییر ورودی volatile byte changed = 0; void setup() { pinMode(LED_BUILTIN, OUTPUT); attachInterrupt(digitalPinToInterrupt(2), toggle, CHANGE); // راه اندازی واحد وقفه } void loop() { if (changed == 1) { // تابع toggle فراخوانی شده است // برگرداندن متغیر به حالت قبل changed = 0; // چشمک زدن ال ای دی digitalWrite(LED_BUILTIN, HIGH); delay(200); digitalWrite(LED_BUILTIN, LOW); } } void toggle() { changed = 1; }
برای دسترسی به متغیری با اندازه بزرگتر از 8 بیت، از ماکرو ATOMIC_BLOCK استفاده کنید. ماکرو تضمین می کند که متغیر را در هنگام خواندن نمی توان تغییر داد.
#include <util/atomic.h> // کتابخانه مورد نیاز برای ماکرو ATOMIC_BLOCK volatile int input_from_interrupt; // جایی در کد مثلا در loop ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { // کد با وقفه های غیرفعال int result = input_from_interrupt; }