Merhabalar,

Bu yazımda STM32F429 içerisindeki TIM1 timer modülünün kullanımı hakkında giriş seviyesinde bilgi vereceğim.

Timer’lar genel olarak mikrodenetleyicilerde, main fonksiyonu çalışırken belirli periyotlarda timer alt programına inerek oradaki işlemleri yapmasını sağlar. Periyodik olarak ana program ve timer alt programı sürekli olarak çalışır.

Klasik 16F 18F PIC mikrodenetleyicilerinde timer modülleri sadece belirli periyotlarda bir işlemi yada işlem grubunu çalıştırmak için kullanılıyor. Fakat STM32F429’da 14 adet Timer bulunuyor ve her timer’ın kendine özel kullanım alanları var. Ayrıca her Timer’ın birden fazla işlevi var.

TIM1’i biraz inceleyecek olursak… Bunu yapabilmemiz için öncelikle CubeMX’i açmamız ve MCU’muzu tanımlamış olmamız gerekir 🙂

Soldaki peripheral’lar üzerinden TIM1’e geldiğinizde altında 4 adet Channel olduğunu görürsünüz.
Sadece Channel1’e bakacak olursak:

channel1

– Input Capture, Output Compare, PWM Generation, Forced Output özellikleri olduğu görülür. Bu özelliklere ait işlemcide TIM1’e dedicate edilmiş pinler de bulunur. Özellikleri seçtikçe sağdaki pinout’da bunları görebilirsiniz.

TIM1’in periyodunu ayarlandığında, her bir periyotta sizin istediğiniz işlemlere ek olarak Channel altından seçtiğiniz işlemleri de yapar. Bunlardan kısaca bahsedelim :

Input Capture : Gelen pulse’lerin uzunluğunu ölçmek için kullanılır.
PWM Generation : PWM sinyali üretmek için kullanılır.
Forced Output : Kendine ayrılmış pin üzerinde başka bir işlem yapılsa bile, Timer kesmesi oluştuğunda o pinin kontrolünü ele geçirerek, dijital çıkış vermeyi sağlar.

Ayrıca yine orada Slave Mode ve Trigger Source parametreleri mevcut. Bu ayarlar da 2 TIM’in birbirine bağlanarak birbirlerini tetiklemeleri için kullanılıyor.

Bu özelliklere daha sonra değineceğim. Şuanki uygulamamız ayarladığımız periyot süresi oluştuğunda, timer alt programına yönlenilerek oradaki işlemin yapılmasıdır. Basitçe bir TIM nasıl kurulur ve devreye alınır bunu öğreneceksiniz.

Adım adım gidelim..

1) CubeMX’i zaten açmıştık 🙂 TIM1’in altına inin ve Clock Source olarak Internal Clock seçin. Diğer tüm özellikleri Disable edin. Clock ayarlarını şu linkteki gibi yapın : http://www.cagataykaynak.com/mikro/cubemx-stm32f429-ile-gpio-kontrolu-led-yakip-sondurme/

2) Configuration sekmesine tıklayın. Bu ekrandan da TIM1’e tıklayın.
Şimdi TIM1’imizin ayarlarını yapıyoruz.

tim1_1

Bu ayarların ne demek olduğunu açıklıyorum :

Clock ayarlarını eğer 1. adımda istenildiği gibi yaptıysanız HCLK = 50 MHz’dir.

Prescaler değerimizi 50000 olarak girdiğimizde : 50 Mhz / 50 KHz = 1000 Hz = 1 KHz bir frekans oluşur.

Counter period değerimiz, timer sayıcısının maksimum sayma değerini belirler. Bu değere ulaştığımızda TIMER trigger verecektir.

1 KHz ‘ i 1000 olarak alalım

1000 / 3000 = 1/3 Hz’lik frekans oluşmuş olur.

Periyodumuz : 1 / (1/3) = 3 sn olur.

Yaptığımız ayarlara göre TIMER1 3 saniyede bir trigger oluşturur.

Trigger oluştuğunda olmasını istediğimiz olay Update olmalıdır.

Update seçilmesi, sayma değerine ulaşıldığında sayıcının tekrar 0’dan başlayacağı anlamına gelir.

Ayrıca bu trigger’lar MCUdaki başka modüller tarafından takip edilebilir.
Örneğin ADC kullanımında, TIM1 update event olduysa ADC çalışsın şeklin ayar yapılabiliyor 🙂 Bununla da ilgili daha sonra makale yayınlayacağım.

01-timer

Bu ayarları yaptıktan sonra Ok veya Apply’e BASMAYIN.

2) İstediğimiz işlemi gerçekleştirebilmek için gerekli kesmeyi aktif etmeliyiz.
NVIC Settings sekmesine girin ve aşağıda gösterilen ayarı yapın.

nvic

Ayarlarımız bitti 🙂 OK’a basarak çıkın.

3) Pinout sekmesine geri dönün. PG14’e bağlı LED’i toggle yapacağımızdan bu pini GPIO_Output olarak ayarlayın.

4) Project / Generate Code yapın. Doğru derleyiciyi seçmeyi unutmayın !

5) Open Project’e basarak projenizi açın.

6) Soldaki dosya ağacımızdan Timer driver dosyasını açın.

hal_tim

7) Fonksiyonlar listesine baktığımızda HAL_TIM_Base_Start_IT’i görüyoruz.
Bu fonksiyon timer’ın interrupt(kesme) olarak kullanılacağını belirtir. Biz de timer’i kesme olarak kullanacağımızdan main.c dosyamıza geri dönerek; bu fonksiyonu çağırıyoruz.

handle

Fonksiyonu çağırırken, programımızın en başında tanımlanmış olan timer’ın handle typedef değerini de fonksiyonun parantezi içerisine yazmamız gerekiyor.

8) Driver dosyamıza tekrar geri dönüyoruz ve timer’a ait callback(çağırma) fonksiyonlarına bakıyoruz.

callback

Output compare, input compare gibi işlemler yapmayacağız. Bu sebeple bize uygun olan “Timer Period elapsed callback” (Yani zaman bazlı çağırma)

Bu listenin altına indiğimizde bize uygun çağrı fonksiyonunu buluyoruz.

fonks

Başındaki __weak kısmını almadan bu kısmı kesiyoruz. Kalan __weak kısmını da oradan silin.

– main.c dosyasını açın.

main(void) fonksiyonunun kapandığı süslü parantezin altına inin ve kestiğiniz yeri oraya yapıştırın.
İçine de timer periyodu dolduğunda yapılması istenilen işlemi yazın. Bu örnek uygulamamız için PG14’deki LED’in toggle’lanmasıdır.

cagir

Siz tabiki bu 2 parantez arasına istediğiniz işlemleri yazabilirsiniz 🙂 Bu tamamen örnektir.
Fakat delay komutu kullanmamanız gerekir !

Kodunuzu derleyin ve yükleyin. 3 saniyede bir PG14’e bağlı olan LED’in 1 yada 0 olduğunu göreceksiniz.

Kendinizce denemeler yapın. main’deki while(1) içerisine başka işlemler yazın ve göreceksiniz ki o işlemler devam ederken 3 saniyede bir de PG14 toggle oluyor 🙂

Gelecek yazılarımda ADC ve DMA kullanımına değineceğim. Web sayfamı takip edin 🙂
İyi çalışmalar.

Çağatay KAYNAK
Elektrik-Elektronik Mühendisi