volatile(geçici)

Tanımı

"volatile", değişken niteleyicisi olarak bilinen bir anahtar kelimedir, genellikle derleyicinin ve sonraki programın değişkeni işleme biçimini değiştirmek için bir değişkenin veri türünden önce kullanılır.

Değişkeni volatile(geçici) olarak bildirmek, derleyiciye yönelik bir yönergedir. Derleyici, C/C++ kodunuzu Arduino'daki Atmega çipi için gerçek talimatlar olan makine koduna çeviren bir yazılımdır.

Spesifik olarak, derleyiciyi, değişkeni program değişkenlerinin depolandığı ve işlendiği geçici bir bellek konumu olan bir depolama kaydından değil, RAM'den yüklemesi için yönlendirir. Belirli koşullar altında, kayıtlarda saklanan bir değişkenin değeri yanlış olabilir.

Bir değişken, aynı anda çalışan bir iş parçacığı gibi göründüğü kod bölümünün kontrolü dışındaki bir şey tarafından değeri değiştirilebildiğinde geçici olarak bildirilmelidir.Arduino'da, bunun meydana gelmesi muhtemel olan tek yer, "servis rutinini kesintiye uğratmak" olarak adlandırılır.


"int" veya "long" geçicileri (variables)

Geçici değişken bir bayttan büyükse (örneğin 16 bit int veya 32 bit uzunluğunda), mikro denetleyici 8 bitlik bir mikro denetleyici olduğu için tek adımda okuyamaz. Bu, ana kod bölümünüz (örneğin döngünüz) değişkenin ilk 8 bitini okurken, kesmenin ikinci 8 biti zaten değiştirebileceği anlamına gelir. Bu, değişken için rastgele değerler üretecektir.

Çözümü:

Değişken okunurken, kesmelerin devre dışı bırakılması gerekir, böylece okunurken bitlerle uğraşamazlar. Bunu yapmanın birkaç yolu vardır:

1.)noInterrupts

2.)ATOMIC_BLOCK makrosunu kullanın. Atomik işlemler tek MCU işlemler ve mümkün olan en küçük birimdir.

Örnek Kod:

volatile değiştirici, durum değişkenindeki değişikliklerin loop() içinde hemen görünmesini sağlar. Volatile(geçici) değiştirici olmadan, durum değişkeni işleve girerken bir kayıt defterine yüklenebilir ve işlev sona erene kadar artık güncellenmeyecektir.

                    

                 
                // "input" değiştiyse LED'i 1 saniye yanıp söner
                // önceki saniyede.
                
                
                    volatile byte changed = 0;
                
                
                
                    void setup() {
                
                  pinMode(LED_BUILTIN, OUTPUT);
                  attachInterrupt(digitalPinToInterrupt(2), toggle, CHANGE);
                }
                
                void loop() {
                  if (changed == 1) {
                     // toggle() kesintilerden çağrıldı!

                     // sıfırlama 0(sıfır) olarak değiştirildi.
                     changed = 0;
                     // 200 ms boyunca yanıp sönen LED
                     digitalWrite(LED_BUILTIN, HIGH);
                     delay(200);
                     digitalWrite(LED_BUILTIN, LOW);
              }
               }
                
                
                    void toggle() {
                
                  changed = 1;
                }
            
        

Mikrodenetleyicinin 8 bitlik veri yolundan daha büyük boyutlu bir değişkene erişmek için ATOMIC_BLOCK makrosunu kullanın. Makro, değişkenin atomik bir işlemde okunmasını sağlar, yani içeriği okunurken değiştirilemez.

#include util/atomic.h // Bu kitaplık, ATOMIC_BLOCK makrosunu içerir.

volatile int input_from_interrupt;

// Kodun içinde bir yerde,örn. inside loop()

ATOMIC_BLOCK(ATOMIC_RESTORESTATE){

// kesintili kod bloke edildi (ardışık atomik işlemler kesintiye uğramaz)

int result = input_from_interrupt;

}