STM32F407VG Driver Geliştirme – 6 (EXTI.c)
EXTI.c ‘nin 2. sayfası.
SYSCFG ile işlemlerimizi bitirdik şimdi EXTI ile ilgili işlemlere geldi. Bir önceki yazımızda SYSCFG Registerları üzerinde işlemler yaptık ama burada EXTI Registerları üzrenden işlemleri yapacağız.
EXTI_Init() adında bir fonksiyon oluşturuyoruz ardından içerisine EXTI_InitTypeDef_t türünden bir değişken oluşturuyoruz.
– Oluşturudğumuz değişkenin ismi EXTI_InitStruct, bu değişkeni kullanarak kullanıcının girdiği değerleri çekebileceğiz.
– uint32_t türünden tempValue adlı geçici değişken oluşturduk. Bu değişkenin amacı EXTI Register Hattının Adresinin değerini tutması.
– Diğer 2 satırlı kodlar ; EXTI hattı üzerinde bulunan IMR ve EMR Registerlarını kullanıcının giridiği pin numarası kadar kaydırıp uygun bitleri sıfırlamaya yarıyor , bu sayede işlem yapılacak bitler temizlenmiş oluyor.
– if yapısı , kullanıcı tarafından EXTI hatını ‘Aktif’ edildiğini kontrol ediyor. İçerisindeki işlemler sırayla alt tarafta incelendi.
– tempValue EXTI adresinin başlangıç değerini tutuyordu, bunun üzerine girilen Modu toplayınca (Intterupt Mode: 0x00 , Event Mode : 0x04) , EXTI_BASE_ADDR + 0x00 veya EXTI_BASE_ADDR + 0x04 toplamları değişkenin üzerine yazılıyor. Bu sayede iki moddan istenilenin başlangıç adresine ulaşılmış oluyor.
– *tempValue işlemi değişkenin tutuğu adrese gitmeyi yarıyor, (__IO uint32_t*) işlemi ise tekrardan 32 bitlik cast işlemi yapıyor. Gidilen adres değeri hangi register ise istenilen pin/line numarasaı kadar kaydırılıp ‘1’ yazılıyor. Bu sayede istenilen modda istenilen pin numarası ‘Aktif’ edilerek kesme işlemi için izin veriliyor.
-Geçici değişkenimin üzerine farklı bir işlem yapılacağı için tekrardan sadece EXT Adresimin başlandıç değeri veriliyor.
– EXTI hattı üzerinde bulunan FTSR ve RTSR (düşük ve yüksek tetikleme) Registerları temizleniyor.
– Eğer kullanıcı tetiklemeyi hem yükselen hemde alçalan seçtiyse o zaman bu koşula girecek.
– EXTI hattı üzerinde bulunan FTSR ve RTSR (düşük ve yüksek tetikleme) Registerları üzerine kullanıcının belirlediği pin/line numarası kadar kaydırılıp ‘1’ yazılacak.
-Yukardaki şart geçerli değilse gir
– Geçici değişkenimizin üzerine yeniden bir adres yazılacak , bu adres EXTI adresinin başlangıçı üzerine kullanıcının seçtiği moda göre yükske veya düşük tetikleme offseti de eklenerek istenilen tetikleme registerına gidilecek . Mantığı yukardaki EXTI_Mode algoritması ile aynı.
– Değişkenimizin tutuğu adres’e giderek uygun bite 1 yazılacak.
– Eğer en baştaki if’e girmezse yani kullanıcı tarafından EXTI Hattındaki istenilen pin için ‘DISABLE’ et komutu gelirse, o zaman geçici dedğere EXTI hattının başlangıç adresini tut ve sonra üzerine uygun mod değerini ekleyerek istenilen mod’a gel ve ardından istenilen pin numarası kadar kaydırark biti sıfırla. Bu sayede kesme işlemine kapatılmak istenilen pin kapatılır.
Artık ana sayfamıza gidip içerisine işlemimizi test etme zamanı.
EXTI_ButtonConfig() adında bir fonksiyon oluşturduk ve içerisine EXTI ile alakalı tüm yapıları girdik.
– EXTI_InitTypeDef_t veri türünden bir değişken oluşturuyorum.
– RCC Faz hatını ektif ediyoruz
– Line Config işelmi için port ve pin bilgilerini giriyoruz.
– EXTI Regsiter üzerine yazılması gerekn herşeyi burda çağırıyoruz
* .... = ENABLE; (enable : 0x00)
* .... = EXTI_MODE_Interrupt; (Interrupt : 0x00)
* .... = EXTI_LineSource_10; (10. Line/Pin : 0xA)
* .... = EXTI_TRIG_RISING; (Rising : 0x08)
Yani eşitliğin sağındaki değerler birer adres , solundaki değerler ise işlemci adreslerin üzerlerine yazılacak structure yapısı.
– Oluşturulan struct yapısı artık işlemci üzerine yazılmak için EXTI_Init() fonksiyonuna gönderilir (bu fonksiyonu yukarda detaylıca işledim).
-Oluşturduğumuz fonksiyonu int main() içerisinde çağırıyoruz.
Daha önce yaptığımız DEBUG izleme işlemini sizler kendiniz yaparak bu yapıların doğru çalışığ çalışmadığını kontrol edebilirsiniz.
Son olarak NVIC işlemine geldik. Hatırlarsanız SYSCFG ve EXTI işlemlerini sırasıyla gördük şimdide 3. aşamamıza olan “NVIC Configuration” kısmındayız.
SYSCFG ve EXTI işlemleri Mikrodenetleyici’nin çevre birimleri’dir. NVIC işlemi ise Mikroişlemci’nin çevre birimi’dir.
Bu işlemlere geçmeden mikrodenetleyicinize ait işlemcinin ‘USER GUID’ dosyasını indirin . Benim kullandığım mikrodenetleyici STM32F407VG ve üzerinde ‘CORTEX-M4’ işlemcisi var. Aşağıdaki linke tıklayarak bu işlemcinin ‘USER GUID’ dosyasını indirebilirsiniz.
[button text=”Tıkla ve dökümanı indir” new_tab=”yes” size=”medium” icon=”” url=”https://documentation-service.arm.com/static/5f2ac76d60a93e65927bbdc5?token=”]
‘Name’ kısmında NVIC_ISER 0-7 yazıyor bunun anlamı 8 adet Registra işlem yapabiliriz demek.
‘Description’ a tıkladığımızda aşağıda bulunan kısmı göreceğiz. Burada 32 bitlik bir işlem yapmamız gerekiyor .
Eğer kesme işlemini aktif etmek istiyorsak ilgili Registra (1) yazmamız gerekiyor. Eğer okuma yapıldığında (1) değerini görüyorsak bu kuduğumuz kesme kanalının ektif olduğunu göstermektedir.
Mikrodenetleyiciye ait ayarlar bitti ve sıra geldi NVIC ayarına , işte burda dikkat edilemsi gereken ilk kural hangi EXTI hattı hangi IRQNumber üzerine işlem görüyor . ”Startup_stm32f407vgtx.s” adlı dosyanın içerisinden aldığım bilgi aşağıda, bu bilgiye göre EXTI0 : LINE0, EXTI4 : LINE 4 ‘e karşılık geliyor.
Bu EXTI0_IRQHandler yada diğerleri aslında birer fonksiyon , eğer biz NVIC işlemine dalanıp orada istediğimiz değerleri yaptıracak isek bu fonksiyonları çağırıp içlerine kısa ve öz kodlar yazıyoruz. Burada EXTI 0-4 arası var ama aslında EXTI0-7 arasıdır.
Şimdi size bu işin mantığını anlatacağım.NVIC_ISR0 – NVIC_ISR7 , toplamda 8 tane kanal var. Bu kanallar’ın her biri 32 bitlik ve benim ‘IRQNumber’ ın alabileceği değerler 0-81 arasıdır .
Mesela kişi IRQNumber olarak 65 değerini girdi o zaman aşağıdaki adımlar uygulanarak , 3. Register ve 2. bit olduğunu söylebiliriz. 3. Register NVIC_ISR2 oluyor . Bu durumda veri NVIC_ISR2 Registrının 2. bitine yazldı.
Aşağıdaki tabloyu daha iyi anlayabilelim diye çizdim. NVIC_ISR işleminin başladığı adres ‘0xE000E100’ dür ve her register artığında 4 bayt’lık bir artışla adreste artıyor.

Anlatığımız algoritmayı aşağıda koda döküyoruz. Geçiçi bir değişken oluşturuyoruz ve ardından kullanıcıdan aldığımız IRQNumberı kaydırma işlemi ile(>>5) 32’ye bölüyoruz ve bunun üzerine NVIC_ISR adresini ekliyoruz ve çıkan sonuç bir adres olduğu için bunu pointer olarak kullanıp geçiçi değer atıyoruz.
Belirlediğimiz Registerın uygun bitini önce temizliyoruz sonra üzerine (1) yazarak durumunu (ENABLE) olarak ayarlıyoruz. Tüm işlemleri geçici değişkene yaptık şimdi bunları pointer mantığı ile belirlenen adrese atayalım.
Ok ile gösterilen yerde yukaardaki fonksiyonu main.c içerisinde çağırdık ve EXTI 0 hatını kullancağımızı söyledik.
En sonunda yukarıda bahsetiğim fonksiyonlarda EXTI0’a uygun olan Handlerı çağırıp içerisine istediğim kodları yazıyorum.
if yapısı ile EXTI hattı üzerindeki PR(Pending-Durum) Registerının 0.bitinin 1 olup olmadığını kontrol ediyoum eğer şart TRUE dönerse içeriye girecek ve aynı biti ilk olarak temizleyecek çünki o bit tekrardan Kesmeye gidebilir. Ardından led yakma işlemi yaparak Kesme işleminin gerçekten çalışığ çalışmadığını kontrol ediyorum. Eğer led yandıysa o zaman tüm adımları başarılı olarak yaptığınız fakat yinede hereyi parça parça analiz etmekte fayda var.















