STM32 Cube IDE – INTERRUPT IRQ ve CALL BACK FONKSİYONLARI

Herhangi bir kesinti oluştuğunda mikro denetleyicimiz, o kesintiye ilişkin bir IRQ – Interrupt Handler fonksiyonunu çağırır. Oluşan kesinti ile ne yapacak isek bu handler fonksiyonlarını ona göre hazırlayarak main.c dosyası içine koymamız gerekiyor.

Bu durumda bu fonksiyonun adı, tipi ve argümanları, sistem kütüphanelerinde tanımlanmış olanlarla uyumlu olmak zorunda.

Bu yayında, STM32 cube IDE ile çalışırken hazırlayacağımız IRQ intterupt handler fonksiyonunlarına ait bu bilgilere nasıl ulaşılacağını -TIM3 zamanlayıcısı örneği üzerinde- anlatacağım.

BİZE GEREKEN IRQ ve CALL BACK FONKSİYONLARINI BULMAK

Mikro denetleyicide TIMER’lar bir kesinti yarattığında “IRQ Handler” -kotarma- adı verilen kesinti fonksiyonları devreye girer,  bu fonksiyonlar kesintinin gerektirdiği işlemleri yaptıktan sonra akışı tekrar ana döngüye bırakır.

Cube IDE kütüphanelerinde de her türlü kesinti için ayrı bir kotarma (IRQ Handler) fonksiyonu var,  kesinti oluştuğunda her kesintinin kendi IRQ fonksiyonu çağrılır.

Kesinti programının başlığı belirlenmiş olmakla birlikte içi boş olup, programcı tarafından ne isteniyorsa onu yapacak bir kod ile doldurulması gerekiyor.

Yukarıda sözünü ettiğimiz kesinti rutin başlıkları startup.s dosyası içinde aşağıdaki gibi listeleniyor.

Örneğimizde kullandığımız TIM3 ile ilgili olan handler fonksiyonunun 190. satırda TIM3_IRQHandler olduğunu görüyoruz. Bu fonksiyonun prototipi ise bir başka yerde stm32f1xx_it.c dosyasında TIM3_IRQHandler() olarak bulunuyor.

IRQ Fonksiyonumuzu bulduk ama HAL fonksiyonlarını kullanmakta olduğumuz için yapılacak işlem burada  tanımlanmıyor. Bu fonksiyon da işi HAL_TIM_IRQhandler(&htim3) fonksiyonuna havale ediyor.

HAL_TIM_IRQhandler(..) fonksiyonu stm32f1xx_hal_tim.c dosyasında bulunuyor.

Böyle oradan oraya gidiyor olmak biraz yorucu oluyor olsa da sonunda ulaştığımız HAL_TIM_IRQhandler fonksiyonu bizi epeyi bir kod yazmaktan kurtarıyor.

Birincisi kesinti sinyalinin hangi kanaldan geldiğine bakıp 2803. ve daha aşağıdaki başka satırlarda olduğu gibi tim->channel = … şeklinde kaydedip bize veriyor. Gereken kesinti bayraklarını indirip kaldırıyor, bize sadece kesinti oluştuğunda ne yapacağımızı kodlamak kalıyor.

Bunun için HAL_TIM_IRQhandler() , süreci bizim kodlamamız için “HAL_TIM_OC_DelayElapsedCallback()“, “HAL_TIM_IC_CaptureCallback()“, “HAL_TIM_PriodElapsedCallback()” gibi Call Back fonksiyonlarına gönderiyor. Bu Call Back fonksiyonlarının bu isimler altında main.c dosyasında hazırlanması gerekiyor.

Aşağıdaki örnekte, TIM3 den gelen iki farklı kesintiye karşı düşen iki adet Call Back fonksiyonu görülüyor. Bu fonksiyonları Main.c dosyası içinde User Code 4 bölümüne yerleştirmiş durumdayız. Bu fonksiyonları CubeMX hazırlamıyor, bizim hazırlayıp koymamız gerekiyor.

Call back fonksiyonunu hangi isim altında hazırlayacağımızı “stm32f1xx_hal_tim.c” içinde küçük bir araştırma yaparak bulabiliyoruz. Orada bu isim altında (ya da başka bir kesinti işlemi ile ilgileniyorsan onun adı altında, her bir callback fonksiyonu için) “weak” ön eki ile bir şablon bulunuyor.

Aşağıda, stm32f1xx_hal_tim.c dosyası içindeki  bu “weak” Call Back fonksiyonlarına iki örnek görülüyor.

Bu şablonu kopyalayarak main.c ye yapıştırıp içini istediğimiz gibi doldurabiliyoruz.

Bu fonksiyonlardan istediklerimizi kopyalayıp main.c içinde yapıştırdıktan sonra içlerini işimizin gerektirdiği gibi doldurabiliyoruz. Aşağıdaki gibi, bu defa önlerinde “weak” kelimesi olmadan: :

CallBack fonksiyonları bizi epey bir ayrıntıyı ezberlemekten ve yeniden kodlamaktan kurtarıyor. Sadece kesme geldiğinde yapmamız gereken işe odaklanabiliyoruz.

Bu yayının sonu – Selçuk Özbayraktar Ağustos 2020