Sıfırdan STM32F0 Dersleri – Sayıcı (Timer)

stm32f0discoveryBu yazımda sizlere Timer dan bahsedeceğim.Timer adındanda anlaşılacağı üzere sayıcıdır.Ayarladığımız değerlere göre arkada planda sayım yapar ve bu ayarladığımız değer belirli bir süreye denk gelir ve bu süre dolunca yani timer taşınca bir kesme oluşturur.Yani Timer kesmesi diyebiliriz.Ben bu yazıda kesme özelliğini anlatmaya çalışacağım.İlerki yazılarda PWM içinde kulanıldığını göreceğiz.STM32F051 de bir den çok timer bulunmakta biz 16 bitlik olan Timer3’ü kullanacağız.
Peki bu timer bize ne kazandıracak ? ne işe yarayacak ? Kesme özelliğini kullanıp belirli zamanlarda işlem yapmamızı sağlayabilir.Yani herhangi bir bekleme yapmayarak diğer işlemleri aksatmadan zamanlı olarak çalışmamızı sağlayacak.Timer’ın hesaplanmasına bakalım şimdi.
Basit bir formülü var.
Timer3 16 bitlikdir yani maximum 2^16 dan 65536 olur.(0 – 65535)

1 saniyelik kemse için bir örnek üzerinde hesaplayalım.

      (Period) * (Prescaler)
sn   = ----------------------
	  (Clock Speed)


       (48.000)  *  (1.000)
1   = ----------------------
	  (48.000.000)


          (48.000.000)
1   = ----------------------
	  (48.000.000)
         
1  =  1

1 saniyelik kesme için gerekli olan Period ve Prescaler değerlerini bulduk. Şimdi kodlar üzerinde işleyelim.

Öncelikle yapıları tanımlıyorum.

GPIO_InitTypeDef        GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM3_InitStructure;
NVIC_InitTypeDef        NVIC_InitStructure;

Daha sorna led için C portuna ve timer için APB1’e clock veriyoruz.

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

LED’i hazırlayalım.Basit GPIO işlemi

GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1;
GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC,&GPIO_InitStructure);

Şimdi Timer ayarlarına bakalım.

TIM3_InitStructure.TIM_Prescaler         = 1000; //Prescaler değeri.
TIM3_InitStructure.TIM_CounterMode       = TIM_CounterMode_Up; //Timer yukarı sayacak şekilde ayarlandı.
TIM3_InitStructure.TIM_Period            = 48000;//Period değeri.
TIM3_InitStructure.TIM_ClockDivision     = TIM_CKD_DIV1;//Bölme oranı 1 yani geçersiz-kapalı.
TIM_TimeBaseInit(TIM3, &TIM3_InitStructure);//Ayarları yükle
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); // Kesmeyi aktif ediyoruz.

Bu kesmeyi belirtmek için yine NVIC’i ayarlıyoruz.

NVIC_InitStructure.NVIC_IRQChannel          = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority  = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd       = ENABLE;
NVIC_Init(&NVIC_InitStructure);

Ve işlemler bitince Timer’ı çalışırıyoruz.

TIM_Cmd(TIM3, ENABLE);

Kesme fonskiyonu

static unsigned char Led_State = 0x00;

void TIM3_IRQHandler(void)
{
    if(TIM_GetFlagStatus(TIM3, TIM_FLAG_Update) != RESET) //Timer update bayrağı reset'e(reset = 0) değil ise ?
        Led_State ^= (1 << 0); // Led_State in 0. bitini tersle
    TIM_ClearITPendingBit(TIM3, TIM_FLAG_Update); //Bayrağı temizle
}

Ana programda bunu kontrol ediyoruz.

while(1)
{
   if(Led_State == 0x01) // 0b 0000 0001 mi ? (çünkü 0.biti tersliyoruz)
      GPIO_SetBits(GPIOC, GPIO_Pin_8); //evet ise ledi yak
   else //değil ise
      GPIO_ResetBits(GPIOC, GPIO_Pin_8);//ledi söndür
}

Programın son hali

#include "stm32f0xx_conf.h"

static unsigned char Led_State = 0x00;

void TIM3_IRQHandler(void)
{
    if(TIM_GetFlagStatus(TIM3, TIM_FLAG_Update) != RESET)
        Led_State ^= (1 << 0);
    TIM_ClearITPendingBit(TIM3, TIM_FLAG_Update);
}

int main(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM3_InitStructure;
    NVIC_InitTypeDef        NVIC_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOC,&GPIO_InitStructure);

    TIM3_InitStructure.TIM_Prescaler         = 1000;
    TIM3_InitStructure.TIM_CounterMode       = TIM_CounterMode_Up;
    TIM3_InitStructure.TIM_Period            = 48000;
    TIM3_InitStructure.TIM_ClockDivision     = TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM3, &TIM3_InitStructure);
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel          = TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority  = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd       = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    TIM_Cmd(TIM3, ENABLE);

    while(1)
    {
        if(Led_State == 0x01)
            GPIO_SetBits(GPIOC, GPIO_Pin_8);
        else
            GPIO_ResetBits(GPIOC, GPIO_Pin_8);
    }
    return (0);
}

 

 

 

You may also like...

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir