Sıfırdan STM32F0 Dersleri – Sayıcı (Timer)
Bu 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); }
Son yorumlar