ARM Cortex-M SysTick Zamanlayıcısının Basit Gecikmeler İçin Kullanımı

ARM Cortex-M tabanlı mikroişlemcilerde çekirdeğin bir parçası olarak bir sistem tik zamanlayıcısı bulunur. Nispeten basit olan bu zamanlayıcının ana amacı, bir RTOS’un tik zamanlayıcısı olarak kullanılmaktır. Gelişmiş özellikleri olmayan bu zamanlayıcının özelliklerini şöyle listeleyebiliriz:

  • Sadece aşağı yönde sayar (azalarak)
  • 24 bit
  • Otomatik yükleme saklayıcısı
  • Kesme
  • Kesme periyodu için kalibrasyon saklayıcısı
  • Dahili veya harici saat girişi (*)
  • Giriş ölçme veya çıkış üretme gibi özellikler yok

(*) SysTick zamanlayıcısının özellikleri üreticiden üreticiye fark etmektedir. Dolayısıyla dökümantasyonu kontrol etmenizi tavsiye ederim. STM32F4 mikroişlemcisinde, harici saat girişi aslında sistem saatinin 8 ile bölünmüş halidir. Daha fazla bilgiyi STM32F4 Programlama Manualinde PM0214 bulabilirsiniz.

SysTick zamanlayıcısının konfigürasyonu için kullanılan saklayıcılar şöyledir.

  • CTRL : zamanlayıcı konfigürasyonu, saat seçimi, kesme aktivasyonu, 0’a düşme kontrolü
  • LOAD : otomatik yükleme saklayıcısı, sayıcı 0’a düştüğünde, VAL’a bu değer otomatik olarak yüklenir
  • VAL : sayıcının anlık değeri
  • CALIB : kalibrasyon saklayıcısı, sadece kesmeler için kullanılır

Aşağıda verilen tik sayısı kadar gecikme yapan bir fonksiyon verilmiştir.

void delay_ticks(unsigned ticks)
{
    SysTick->LOAD = ticks;
    SysTick->VAL = 0;
    SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;

    // COUNTFLAG biti sayıcı 0'a ulaştığında 1 olur.
    // Saklayıcı okunduğunda otomatik olarak 0 olur.
    while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
    SysTick->CTRL = 0;
}

Zamanlayıcı başlangıçta sistem saatinin 8’e bölünmüş halini kullanır. Örneğin, 84MHz’lik bir sistem saati için, zamanlayıcı saati 10,5MHz’tir. Bu durumda zamanlayıcı tik süresi 0,095µs~=0,1µs’dir. Bu fonksiyonu ticks=105 parametresi ile çağırmak, 10µs’lik bir gecikme oluşturacaktır.

Şimdi parametre olarak mikrosaniye ve milisaniye değerleri kabul eden fonksiyonlar yazalım.

static inline void delay_us(unsigned us)
{
    delay_ticks((us * (STM32_SYSCLK / 8)) / 1000000);
}

static inline void delay_ms(unsigned ms)
{
    delay_ticks((ms * (STM32_SYSCLK / 8)) / 1000);
}

Oldukça basit fonksiyonlar oldukları için bu fonksiyonları, bir başlık dosyasına yukarıda tanımlandığı gibi inline fonksiyonlar olarak eklemenizi tavsiye ederim. Böylece derleyici iyi bir optimizasyon yaparak, çarpma ve bölme işlemlerini ortadan kaldırabilir. Bu arada STM32_SYSCLK, sistem saatini belirten bir tanımlamadır. Örneğin benim sistemimde bu tanımlamanın değeri 84000000’dir. Kullandığınız platform veya kütüphanenin mutlaka benzer bir tanımlaması vardır.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.