22 Eylül 2016 Perşembe

6- STM32F4 ADC Kullanımı

Merhaba Arkadaşlar,

                Sıradaki örneğimiz Stm32f4 ile ADC ( Analog to Digital Converter) nasıl kullanılır, bunun hakkında kısa bilgi ardından da kod paylaşımı yapılacaktır.

STM32F4’de aşağıdaki tabloda gösterildiği gibi 3 adet ADC ve her birine bağlı olarak 16 kanal bulunmaktadır.


Son olarak da STM32F4’de ADC 12Bit çözünürlüğe sahiptir. ADC hakkında daha fazla bilgiye ihtiyaç olmadığı için direkt kod yazımına geçebiliriz.

Aşağıdaki tabloda da görüldüğü üzere ADC1, ADC2 ve ADC3 hepsi de APB2 bus hattına bağlıdır.



Artık kod yazma kısmına geçebiliriz:
uint16_t ADC_Degeri;                   // ADC için değişken
1 - Öncelikle gerekli kütüphane eklemelerini yapmamız gerek. Bunlar:
#include "stm32f4xx.h"                             //stm32f4 kütüphanesi
#include "stm32f4xx_gpio.h"                    //GPIO kütüphanesi
#include "stm32f4xx_rcc.h"                      // RCC clock kütüphanesi
#include "stm32f4xx_adc.h"                     // timer kütüphanesi

2- Periph clock hatlarını aktifleştirelim:
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);

3- Output portunu ayarlamasını yapalım:
void GPIO_led_Config()
{
GPIO_InitTypeDef  GPIO_InitStructure;              // Port yönlendirmesi
   /* PD12, 13, 14 ve PD15 pinleri kullan1lacak */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;      //Pinler cikis olarak belirlendi
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //Pin PushPull olarak ayarlandi
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;      //GPIO Bus hizi 100 MHz ayarlandi
GPIO_Init(GPIOD, &GPIO_InitStructure);    
//Yukarida tanimlanan bilgileri GPIOD adresine ait oldugu belirtilir
}

4- ADC pin ayarlamaları için:
void ADC_GPIO_Config()
{
GPIO_InitTypeDef  GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;    //Pinler analog giris olarak belirlendi
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;   //Pin PushPull olarak ayarlandi
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;       //GPIO Bus hizi 100 MHz ayarlandi
GPIO_Init(GPIOA, &GPIO_InitStructure);                                                                                         //Yukarida tanimlanan bilgileri GPIOA adresine ait oldugu belirtilir
}

4- ADC konfigürasyon ayarlamaları için:
void ADC1_Config()
{
ADC_InitTypeDef                        ADC_InitStructure;
ADC_CommonInitTypeDef         ADC_CommonInitStructure;
               
ADC_CommonInitStructure.ADC_Mode      = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay =  ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
               
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1,&ADC_InitStructure);
ADC_Cmd(ADC1,ENABLE);
}

5- ADC bilgisinin okunması

uint16_t ADC_Oku()
{
  ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_56Cycles); 
  //ADC için KANAL 0 SECILDI VE 56 CYCLES KONUMUNDA

  ADC_SoftwareStartConv(ADC1);          //DONUSUME BASLA DEDIK
  while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET); 
    //HER DÖNUSUM SONRASI BAYRAGI SIFIRLAYALIM

   return ADC_GetConversionValue(ADC1);
}

//ANA Fonksiyon

int main(void)
{
                Periph_Config();
                GPIO_led_Config();
                ADC_GPIO_Config();
                ADC1_Config();
                                                              
                while (1)              //Sonsuz donguye girilir
                               {                                            
                                     ADC_Degeri = ADC_Oku();
                                              
                                     if ( ADC_Degeri < 1024 )
                                           {
                                                  GPIO_ResetBits(GPIOD, GPIO_Pin_12);
                                                  GPIO_ResetBits(GPIOD, GPIO_Pin_13);
                                                  GPIO_ResetBits(GPIOD, GPIO_Pin_14);
                                                  GPIO_ResetBits(GPIOD, GPIO_Pin_15);
                                             }
                                                              
                                        else if ( 1024 < ADC_Degeri && ADC_Degeri < 2048 )
                                             {
                                                   GPIO_SetBits(GPIOD, GPIO_Pin_12);
                                                   GPIO_ResetBits(GPIOD, GPIO_Pin_13);
                                                   GPIO_ResetBits(GPIOD, GPIO_Pin_14);
                                                   GPIO_ResetBits(GPIOD, GPIO_Pin_15);
                                             }
                                                              
                                        else if ( 2048 < ADC_Degeri && ADC_Degeri < 3072 )
                                             {
                                                   GPIO_SetBits(GPIOD, GPIO_Pin_12);
                                                   GPIO_SetBits(GPIOD, GPIO_Pin_13);
                                                   GPIO_ResetBits(GPIOD, GPIO_Pin_14);
                                                   GPIO_ResetBits(GPIOD, GPIO_Pin_15);
                                              }
                                                              
                                       else if ( 3072 < ADC_Degeri && ADC_Degeri < 3800 )
                                              {
                                                    GPIO_SetBits(GPIOD, GPIO_Pin_12);
                                                    GPIO_SetBits(GPIOD, GPIO_Pin_13);
                                                    GPIO_SetBits(GPIOD, GPIO_Pin_14);
                                                    GPIO_ResetBits(GPIOD, GPIO_Pin_15);
                                               }
                                                              
                                        else
                                               {
                                                     GPIO_SetBits(GPIOD, GPIO_Pin_12);
                                                     GPIO_SetBits(GPIOD, GPIO_Pin_13);
                                                     GPIO_SetBits(GPIOD, GPIO_Pin_14);
                                                     GPIO_SetBits(GPIOD, GPIO_Pin_15);
                                               }
                                              
                               }
}

Aşağıda kodun resmini bulabilirsiniz:




İyi Çalışmalar.

3 Eylül 2016 Cumartesi

5 - STM32F4 PWM Kullanımı

Merhaba Arkadaşlar,

                Sıradaki örneğimiz Stm32f4 ile PWM nasıl üretilir, bunun hakkında kısa bilgi ardından da kod paylaşımı yapılacaktır.
Öncelikle PWM frekansı üretmek için Timer’lara ihtiyaç duyarız ve bu yüzden timer ayarları yapmamız gerekir. Daha sonra timer’ın hangi kanalından ya da kanallarından pwm vereceğimizi belirtiriz.

Aşağıda ahngi timer’ın hangi pin ve dolayısıyla kanallardan pwm üretebileceğinin şeması bulunmaktadır. Bu şemaya bakarak çok rahat bir şekilde hangi timer’ı kullanıyorsak, hangi portun hangi kanalını kullanacağımızı bulabiliriz.


Yukarıdaki tabloya bakacak olursak, örneğin timer 8 kullanacaksak, kanal1 olarak PC6 veya PI5 pinini kullanmamız gerekir. Kanal2 olarak PC7 veya PI6 pinini kullanabiliriz. Aynı şekilde kanal3 ve kanal 4 için de aynı yorumları yapabiliriz.

1 – bütün timerların çalışma frekansı aynı değildir. Bunun sebebini bir önceki yazımızda vermiştik. Çünkü bazı timerlar APB1, bazıları da APB2 bus hattına bağlıdırlar. Bu hatlar farklı bus hızına sahip olduğu için timerların çalışma frekansları da farklı olacaktır. Aşağıda yine bus hattı tablosu verilmiştir.


2 – Bütün timerlar 16Bit Prescaler değerine sahiptirler.
3 – Timer6 ve Timer7 basit timer’lar demiştik. Bu yüzden bu timerlar pwm sinyali üretemezler.
4 - Timer2 ve Timer5 32bit timerlardır.
5 – Timer9 ve Timer12 iki kanal PWM üretebilirler.
6 – Timer10, Timer11, Timer13 ve Timer14 ise tek bir kanal PWM çıkışı verebilirler.
7 – Bir Timer’daki tüm kanallar aynı pwm frekansına sahiptirler. Sadece doluluk oranları farklı olabilir.

Artık kod yazma kısmına geçebiliriz:
Biz bu örnekte timer5’i kullanacağız. Timer5 32Bit timer, yukarıdaki tabloya bakarak kanal1’i kullanacağız ve bu yüzden de PA0 veya PH10 pinini kullanmamız gerekiyor. Biz PA0 pinini tercih ettik. 10Khz (10 000 Hz)’lik bir Pwm üretelim.

Bunun için Prescaler değeri belirlememiz gerekiyor. Prescaler değeri 16Bit olduğunu unutmayalım. O yüzden programın başına:

uint16_t PRSC_Degeri = 0; adında bir değişken tanımlayalım. Peki bu prescaler değerini nasıl buluruz:

PRSC_Degeri = (uint16_t)(SystemCoreClock/ counter clock)-1; formülü ile bulunur. Ancak Timer 5 APB1 bus hattına bağlı olduğu için SystemCoreClock’un yarısını almamız gerekiyor. O yüzden APB1 bus hattı için formül ise :

PRSC_Degeri = (uint16_t)((SystemCoreClock/2 )/ counter clock)-1; olarak söyleyebiliriz. Diğer APB2 hattı için yukarıda verilen ilk formül geçerlidir.

Hesaplamalarımızı yapalım:

PRSC_Degeri = (uint16_t)((168 Mhz/2 )/ 4Mhz)-1;  //clock frekansı 4 Mhz olsun(biz belirledik)
PRSC_Degeri = (21) – 1 = 20 olarak belirlenir. Ancak zaten biz bunu koda formül olarak koyacağımız için burada gerekli olan kısım bizim belirlediğimiz counter clock değeridir. Biz 4 Khz için 4Mhz’lik(4000000Hz) bir counter clock belirledir. Peki 10 Khz pwm sinyali için 4Mhz ‘lik clock frekansını ne yapacağız. Periyod değerini öyle bir değer vereceğiz ki PWM sinyalimiz 10 Khz olsun. 

O halde:

10 Khz = 4 Mhz / period formülü kullanılır.
Period = 400 değeri olması gerekmektedir.

Genel bir toplarsak yukarıdakileri: 10Khz için:

uint16_t PRSC_Degeri = 0;   //değişken tanımladık.
PRSC_Degeri = (uint16_t)((168 Mhz/2 )/ 4Mhz)-1
Period = 400                olarak belirledik. Hesap kitap işlerinden sonra başlayalım:


1 - Öncelikle gerekli kütüphane eklemelerini yapmamız gerek. Bunlar:

#include "stm32f4xx.h"                                               //stm32f4 kütüphanesi
#include "stm32f4xx_gpio.h"                    //GPIO kütüphanesi
#include "stm32f4xx_rcc.h"                       // RCC clock kütüphanesi
#include "stm32f4xx_tim.h"                      // timer kütüphanesi

2- Periph clock hatlarını aktifleştirelim:

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);

3 – Timer’ın pin ayarlamalarını yapalım:

GPIO_InitTypeDef  GPIO_InitStructure;
               
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;   //Pinler analog function olarak belirlendi
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  //Pin PushPull olarak ayarlandi
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;      //GPIO Bus hizi 100 MHz ayarlandi
GPIO_Init(GPIOA, &GPIO_InitStructure);  //Yukarida tanimlanan bilgileri GPIOA adresine ait oldugu belirtilir
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM5); // timer5 PA0 pininden pwm verecek

4 – Timer ayarlarını yapalım:

TIM_TimeBaseInitTypeDef                        TIM_TimeBaseStructure;
               
PRSC_Degeri = (uint16_t)(SystemCoreClock/2 / 4000000)-1;  //yukarıda hesapladık aynısı
               
TIM_DeInit(TIM5);
 TIM_TimeBaseStructure.TIM_ClockDivision                 = 0;
TIM_TimeBaseStructure.TIM_CounterMode                   = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period                               = 400 - 1;             // 10 Khz için
TIM_TimeBaseStructure.TIM_Prescaler                           = PRSC_Degeri;
TIM_TimeBaseInit( TIM5,&TIM_TimeBaseStructure);

5 – PWM ayarlarını yapalım:

Eğer %20 dolulukta bir pwm sinyali istiyorsak bunun formülü ise:
Doluluk oranı = TIM_Pulse / Period formülü ile bulunur.

TIM_OCInitTypeDef      TIM_OCInitStructure;
               
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 80;                 //%20 doluluk oranı için 80/400 = %20
TIM_OC1Init(TIM5, &TIM_OCInitStructure);
               
TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM5, ENABLE);

6 – Son olarak timeri aktifleştiririz.:

TIM_Cmd(TIM5, ENABLE);          // timerı aktifleştiririz.


Normalde biz bunların hepsini bir ana döngü içerisinde yazabiliriz. Ancak biraz daha kodların anlaşılır ve düzenli olması için fonksiyonlarla yazalım:

#include "stm32f4xx.h"                             // stm32f4 kütüphanesi
#include "stm32f4xx_gpio.h"                    // GPIO kütüphanesi
#include "stm32f4xx_rcc.h"                      // RCC clock kütüphanesi
#include "stm32f4xx_tim.h"                      // timer kütüphanesi

uint16_t PRSC_Degeri = 0;

void Periph_Config()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
}

void Timer_GPIO_Config()
{
GPIO_InitTypeDef  GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;    //Pinler analog function olarak belirlendi
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  //Pin PushPull olarak ayarlandi
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;       //GPIO Bus hizi 100 MHz ayarlandi
GPIO_Init(GPIOA, &GPIO_InitStructure);  //Yukarida tanimlanan bilgileri GPIOA adresine ait oldugu belirtilir
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM5); // timer5 PA0 pininden pwm verecek
}

void Timer_Config()
{
TIM_TimeBaseInitTypeDef                        TIM_TimeBaseStructure;
PRSC_Degeri = (uint16_t)(SystemCoreClock/2 / 4000000)-1;  //yukarıda hesapladık aynısı
TIM_DeInit(TIM5);
 TIM_TimeBaseStructure.TIM_ClockDivision                     = 0;
TIM_TimeBaseStructure.TIM_CounterMode                   = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period                                   = 400 - 1;             // 10 Khz için
TIM_TimeBaseStructure.TIM_Prescaler                                             = PRSC_Degeri;
TIM_TimeBaseInit( TIM5,&TIM_TimeBaseStructure);
}

void PWM_Config()
{
TIM_OCInitTypeDef      TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 80;                 //%20 doluluk oranı için 80/400 = %20
TIM_OC1Init(TIM5, &TIM_OCInitStructure);    
TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM5, ENABLE);
}

//Ana fonksiyon
int main(void)
{
                Periph_Config();
                Timer_GPIO_Config();
                Timer_Config();
                PWM_Config();
                               
  while (1)            //Sonsuz donguye girilir
                               {                                            
                                               TIM_Cmd(TIM5, ENABLE); //Timer5 aktifleştirilir
                               }
}

Osiloskoptan bakıldığında da PWM sinyalinin aşağıdaki gibi olduğunu göreceksiniz:

Frekans = 1/100us = 1/100*10^-6 = 10000 Hz
toplam periyod 100us, doluluk oranı = 20us = %20


Aşağıda kodun resmini bulabilirsiniz:


İyi Çalışmalar.

                                                                                                                            




1 Eylül 2016 Perşembe

4 - STM32F4 ile Timer Kesmesi

Merhaba Arkadaşlar,

         Sıradaki örneğimiz Stm32f4 ile Timer kesmesi nasıl yapılır bunun hakkında kısa bilgi ardından da kod paylaşımı yapılacaktır.

Öncelikle STM32F4 işlemcisi 14 adet Timer’a sahiptir. Bunlar:

Timer1 ve Timer8 (ikisi de 16 bit) gelişmiş özelliklere sahiptirler.  

TIM2 (16bit), TIM3 (32bit), TIM4 (32bit) ve TIM5(16bit) genel amaçlı kullanım için uygundurlar.

Timer9’dan Timer14’e kadar olanlar da farklı ayarlanabilir özelliklere sahip olan timer’lardır.

Timer6(16Bit) ve Timer7(16Bit) basit özellikleri olan timer’lardır.

Aşağıda bu timerların gösterildiği bus hatlarına bakabilirsiniz:



Datasheet’lerden daha detaylı bilgilere ulaşabilirsiniz. Burada ise Timer2 ile bir örnek yapılacaktır.
Öncelikle Timer için Clock hattının aktifleştirilmesi gerekmektedir. Yukarıda da görüldüğü üzere Timer2 APB1 hattına bağlıdır. O halde:
/* timer2 Periph clock hatti aktif edilir */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM2 APB1’e bağlı gözüküyor. APB1’in çalışma hızı 42 MHz. Ancak Datasheet’e bakıldığında önemli bir uyarı ile karşılaşıyoruz:

       APB2’ye bağlı olan zamanlayıcılar için clock hattı 168Mhz’e kadar olabilir, APB1 içinse 84Mhz olabilir. Burada bir ikilem var gibi duruyor ancak datasheet’te bunu şöyle açıklıyor:  APB ön bölücü değeri 1 ise timer clock hattı da aynı frekansta çalışır, ancak ön bölücü değeri 1 değilse veya 1’den farklı bir değerde ise timer clock hattı APB hattının 2 katı hızda çalışır.

Timer2’ye baktığımızda APB1 bus hattına bağlıdır. Bu hattın clock frekansı 42 Mhz. Daha önce CMSIS klasöründe oluşturduğumuz system_stm32f4xx.c dosyasında ön bölücü değeri 4 olarak kullanıldığı için bu hat 42*2 yani 84 Mhz clock frekansında çalışmaktadır. Daha detaylı bilgiye datasheet’ten bakılabilir.

Prescaler değeri ise:      Timer hızı  = Bus hızı / (prescaler + 1)  formülünden bulunur.

O halde 0.5 sn’lik timer kesmesi için:

0.5sn = 1/0.5 = 2Hz frekansa eşittir.

Öncelikle 2Khz (2000Hz) için:            2000 = 84Mhz(buz hızı) /(prescaler+1)
                                                             2000 = 84000000 / (PRSC + 1) = > PRSC = 41999 olmaktadır.

Periyodu da biz 1000’e kadar saydırırsak:             2000hz / 1000 = 2Hz
                                                                                2Hz = ½ = 0.5sn demektir.

Prescaler değeri: 41999
Periyod: 1000 -1 = 999 (sayıma 0’dan başladığı için 1 eksiği olur)
0.5sn için değerlerimizi yukarıdaki gibi hesaplarız.

Kod yazma kısmına geçebiliriz. 
     Öncelikle projemize timer kütüphanesinin eklenmesi gerekmektedir. Daha önceki konularda bu anlatıldığı için burada değinilmeyecektir. Ayrıca main.c dosyasına kodu yazarken en üstte #include "stm32f4xx_tim.h" kodunu yazmayı unutmayın. 

TIM_TimeBaseInitTypeDef                        TIM_TimeBaseStructure;                            //timer için
NVIC_InitTypeDef                                         NVIC_InitStructure;                                      //kesme için
Port yönlendirmeleri ana döngü içerisinde tanımlanır.
/*timer2 Periph clock hatti aktif edilir */     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
Timer kodları ise:
TIM_DeInit(TIM2); //daha önce timer ayarlamaları yapıldı ise temizle
 TIM_TimeBaseStructure.TIM_ClockDivision = 0;             //gonderilen clock bilgisinin kac parça halinde gönderilecegini gosterir
TIM_TimeBaseStructure.TIM_CounterMode    = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period    = 1000-1;                             //periyod girilir
TIM_TimeBaseStructure.TIM_Prescaler              = 42000-1;                         //prescaler değeri girilir
TIM_TimeBaseInit( TIM2,&TIM_TimeBaseStructure);   //timer2’ye ait olduğu belirtilir
TIM_Cmd(TIM2, ENABLE);                         //timer2 aktif edilir
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);                              //timer kesmesi bayrağı aktif edilir
               
//Kesme için gerekli açıklamaları daha önceki yazımızda bulabilirsiniz.
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority  = 0x00; //farkli türler arasi oncelik
NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0x00; //kendi turunun icindeki oncelik
NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
NVIC_Init(&NVIC_InitStructure);

Kesme fonksiyonu:
void TIM2_IRQHandler()
{
    if(TIM_GetITStatus(TIM2, TIM_IT_Update) == 1 ) //kesme bayrağı 1 mi?
        {
                TIM_ClearITPendingBit(TIM2, TIM_IT_Update);             //bayrağı temizle
                GPIO_ToggleBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
        }
}

/*************************************************************
Aşağıda tüm kodları baştan aşağı sıra ile yazılmıştır:

#include "stm32f4xx.h"                               //stm32f4 kütüphanesi
#include "stm32f4xx_gpio.h"                    //GPIO kütüphanesi
#include "stm32f4xx_rcc.h"                       // RCC clock kütüphanesi
#include "stm32f4xx_tim.h"


void TIM2_IRQHandler()
{
                if(TIM_GetITStatus(TIM2, TIM_IT_Update) == 1 )          //kesme bayrağı set oldu mu?
                {
                TIM_ClearITPendingBit(TIM2, TIM_IT_Update);                             //bayrağı sıfırla
                GPIO_ToggleBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
                }
}


//Ana fonksiyon
int main(void)
{
                TIM_TimeBaseInitTypeDef        TIM_TimeBaseStructure;
                NVIC_InitTypeDef                          NVIC_InitStructure;
                GPIO_InitTypeDef  GPIO_InitStructure;                              // Port yönlendirmesi

  /* GPIOD Periph clock hatti aktif edilir */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
/* timer2 Periph clock hatti aktif edilir */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
  /* PD12, 13, 14 ve PD15 pinleri kullanilacak */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
               
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                              //Pinler cikis olarak belirlendi
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                               //Pin PushPull olarak ayarlandi
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;     //GPIO Bus hizi 100 MHz ayarlandi
GPIO_Init(GPIOD, &GPIO_InitStructure);           //Yukarida tanimlanan bilgileri GPIOD adresine ait oldugu belirtilir

 TIM_DeInit(TIM2);
TIM_TimeBaseStructure.TIM_ClockDivision= 0;                              //gonderilen clock bilgisinin kac parça halinde gönderilecegini gosterir
TIM_TimeBaseStructure.TIM_CounterMode    = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period                   = 1000-1;
TIM_TimeBaseStructure.TIM_Prescaler                              = 42000-1;
TIM_TimeBaseInit( TIM2,&TIM_TimeBaseStructure);
               
TIM_Cmd(TIM2, ENABLE);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
               
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority  = 0x00; //farkli türler arasi oncelik
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; //kendi turunun icindeki oncelik,
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
                              
GPIO_ResetBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
                                              
  while (1)            //Sonsuz donguye girilir
                               {                                            
                                              
                               }
}

Aşağıda kodun resimleri bulunmaktadır.


İyi Çalışmalar.