STM32 Led Yakma sıfırdan %100 e

STM32 led başlangıçta bize de oldukça karışık gelmekte. STM32 programlamak biraz üst seviye olduğu için Arduino bilmenin de bir faydası dokunmayabilir. Çünkü Arduino’da gördüğümüz hemen hiçbir şeyi burada kullanmayacağız.

Hatta kütüphaneler Arduino kütüphaneleri gibi basit olmadığından anlamak için biraz tecrübe ve ileri seviye programlama bilgisi gerektiriyor. Eğer AVR öğrendiyseniz sizin için biraz daha kolay olsa da donanım bakımından öğrenmeniz gereken yine pek çok konu olacaktır. Aynı zamanda yazılımsal olarak AVR programlamak STM32’ye göre oldukça kolaydır. Fakat AVR programlamayı bilen birisine Arduino’da olduğu gibi hemen hemen her şey yabancı gelmeyecektir. Çoğu konuyu ve özellikle yazmaçları önceden kavradığımız için sıfırdan başlamak yerine mevcut bilgimizin üzerine ilave etmemiz gereklidir. O yüzden STM32’ye başlamak için C kitaplarını okuyup üzerinde çalışmak ve öncelikle AVR öğrenmek işinizi kolaylaştıracaktır. Bu alanda yeteneğinizi keşfettiğinize inanıyorsanız sizin için STM32 öğrenmek zor olmamalıdır.

STM32 led Projeye başlayalım..

Öncelikle TrueStudio’yu açıp yeni bir proje oluşturmamız gerekli. Bunun için seçmemiz gereken özel seçenekler olduğu için öncelikle proje oluşturmayı adım adım anlatacağız. Menüden New / C Project diyerek projemizi oluşturuyoruz. C dilinde program yazacağımız için bunu seçtik.

Yeni Proje oluşturma
Yeni Proje oluşturma

Sonrasında karşımıza çıkan ekranda Embedded C Project kısmını seçiyoruz ve projemize bir isim veriyoruz. Embedded C seçmemizin sebebi beraberinde kütüphane ve ayar dosyalarıyla beraber gelmesinden ve ARM derleyicisini bulundurmasından dolayıdır.

Yeni Proje oluşturma 2
Yeni Proje oluşturma 2

STM32 led Aygıt Seçimi

Bundan sonra karşımıza mikrodenetleyici ya da kart seçeceğimiz ekran geliyor. STM32F3 Discovery kullandığımızdan bu kartı seçiyoruz. Bu kartı seçmemizle bu karta ait ek dosyalar da gelecektir.

Yeni Proje oluşturma 3
Yeni Proje oluşturma 3

Bundan sonra bizi proje sayfası karşılıyor. Burada ana ekran main.c dosyasını bize göstermekte. Burada boş bir sayfa yerine pek çok ayar ve tanımların olduğu bir dosyayı görmekteyiz. Üstelik bunun beraberinde bir sürü kütüphane ve başlık dosyası projemize eklenmiş durumda. AVR programlarken karşımıza çıkan boş bir sayfayı görmemekteyiz. Aslında bize zor gelen de bu karmaşıklığı çözmektir.

Yeni Proje oluşturma 4
Yeni Proje oluşturma 4

Bundan önce ekranın sol kısmında yer alan Project Explorer penceresinden bahsetmemiz gerekir. Atmel Studio, Visual Studio tabanlı olduğu için ve TrueStudio Eclipse tabanlı olduğu için arayüz olarak farklıdır. Project Explorer kısmında projemize ait tüm dosyaları görmemiz mümkündür. Şimdi resmini verelim ve sonrasında açıklamasını yapalım.

Yeni Proje oluşturma
Yeni Proje oluşturma 5

Görüldüğü gibi bazı başlıklarda çeşitli dosya türleri yer almakta. Bunlardan “Binaries” olanı adı üstünde makine dilinde ve debug yaparken kullanacağımız program kodunu içermektedir. “Includes” ise kütüphaneleri ve başlık dosyalarını içerir. “Driver” sürücü dosyalarını ve “src” ise bizim “kaynak” dosyalarımızı içerir. Yani burada bizim program yazacağımız ana klasör src klasörüdür. Kaynak klasörüne baktığımızda pek çok dosya görmekteyiz. Bu dosyaların fazlalığı başlangıçta kafamızı karıştıracaktır.

Yeni Proje oluşturma 6
Yeni Proje oluşturma 6

Şimdilik diğer dosyalara dikkat etmemize gerek yoktur. Bu dosyalarda gerekli ön ayarlar zaten biz kartımızı seçerken yapılmıştır. Eğer kartı aynı şekilde kullanacaksak dokunmamıza gerek yoktur. Şimdi main.c programını açalım ve yazılım kısmına geçelim. Main dosyası oldukça uzun olduğu için parça parça incelemeye başlayacağız. Sonrasında ise açıklamaları kaldırıp sade bir görünüm elde edeceğiz.

/* Includes ------------------------------------------------------------------*/#include "main.h"

stm32 led Kodun başında gördüğümüz açıklama bloku aslında bir lisans dosyasıdır. Fark edeceğiniz üzere çeşitli kütüphanelerin ve kaynak kodlarının başında böyle lisans dosyaları bulunmaktadır. Aynı bir bilgisayar yazılımı yüklerken başta okuduğumuz ve onayladığımız lisans dosyası gibi buradaki şartları da kodu kullanırken okumuş ve onaylamış sayılırız. Bu programın açıklamasında GPIO ayaklarının STM32F3xx HAL API ile kullanımından bahsedilmektedir. Yani ana program aslında bir örnek kod ile karşımıza çıkmaktadır.

main.c olduğu gibi bir de main.h dosyası bulunmaktadır. Burada ana programımıza main.h dosyası eklenmiştir. Bu dosyada ne olduğuna bir bakalım.

Project Explorer’den baktığımız üzere bu dosyanın bomboş olduğunu görüyoruz. Sadece programımıza stm32fxx_hal.h adında HAL kütüphanesi başlık dosyası eklenmiş ve geri kalanı boş bırakılmış. Buraya biz tanımları, sabitleri, makroları ve fonksiyonları yazabiliriz. Şimdilik boş olan fakat programlarken ihtiyacımız olacak bir dosyayı görmekteyiz.

1static GPIO_InitTypeDef  GPIO_InitStruct;

Bu aslında HAL kütüphanesine ait bir yapı tanımlamasıdır. Hal kütüphanesi Arduino kütüphaneleri gibi basit bir yapıda olmayıp C diinde olsa bile karmaşık veri yapılarına sahiptir. Bu karmaşık veri yapıları yüzünden Arduino veya AVR kütüphanesi gibi birkaç sabit ve fonksiyonla kullanacağımız bir kütüphane basitliğinde değildir. Bizim için zor olan noktalardan biri de bu HAL kütüphanesinin karmaşık veri yapılarını öğrenmek olacaktır. Burada GPIO_InitStruct adında bir yapı tanımlaması yaptık. Bu tip tanımlaması şeklindeki yapının içeriğinin ne olduğunu CTRL + Sol Tık ile üzerine tıklayarak görebiliriz. TrueStudio kullanırken başta unutmamamız gereken en önemli noktalardan biri bilmediğimiz bir yapı ya da fonksiyonun CTRL + Sol Tık ile kaynak kodunu ve beraberinde kod açıklamarını görmemizdir.

GPIO_InitTypeDef yapısının içeriğine bakmak için CTRL + Sol Tık uygulamasını GPIO_InitTypeDef yazısının üzerine yapıyoruz. Karşımıza yapının kaynak kodu çıkıyor.

1234567891011121314151617typedef struct{  uint32_t Pin;       /*!< Specifies the GPIO pins to be configured.                           This parameter can be any value of @ref GPIO_pins_define */   uint32_t Mode;      /*!< Specifies the operating mode for the selected pins.                           This parameter can be a value of @ref GPIO_mode_define */   uint32_t Pull;      /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.                           This parameter can be a value of @ref GPIO_pull_define */   uint32_t Speed;     /*!< Specifies the speed for the selected pins.                           This parameter can be a value of @ref GPIO_speed_define */   uint32_t Alternate;  /*!< Peripheral to be connected to the selected pins                             This parameter can be a value of @ref GPIOEx_Alternate_function_selection */}GPIO_InitTypeDef;

Görüldüğü gibi bu yapı belli değerleri almakta ve bu değerler de enum yapısı ile sembolleştirilebilmektedir. Yine bu enum yapılarını HAL kütüphanesinin giriş ve çıkış kaynak kodu olan stm32f3xx_hal_gpio.h başlık dosyasından görebilirsiniz. Biz bu noktada şimdilik pek meşgul olmayalım ve main.c dosyası üzerinde ilerleyelim.

12static void SystemClock_Config(void);static void Error_Handler(void);

Burada SystemClock_Config adında bir fonksiyon prototipinin olduğunu görüyoruz. Bu fonksiyon kartımızın saat değerine ait ayarları yapacağından dokunmamakta fayda vardır. Error_handler de aynı zamanda bizim yazacağımız programı ilgilendirmeyen fakat sistemi ilgilendiren bir fonksiyon olduğu için buna da dokunmadan devam ediyoruz. Dikkatinizi çeken bir başka nokta da bazı açıklama satırlarıdır. Kullanıcı için hazır tanımlanan açıklama satırları aynı bizim yaptığımız gibi programı sanal olarak parçalara bölmektedir. Bunları kalabalık olmasın diye silebiliriz.

1234/* Private typedef ———————————————————–*//* Private define ————————————————————*//* Private macro ————————————————————-*//* Private variables ———————————————————*/

Şimdi ana program yapımıza bakalım. Burada da bazı açıklamaları görmekteyiz. Sizin için inceleyelim.

12345678910111213141516int main(void){  /* This sample code shows how to use STM32F3xx GPIO HAL API to toggle PE8 to PE15   IOs (connected to LED3 to LED10 on STM323F3-DK board) in an infinite loop.    To proceed, 3 steps are required: */    /* STM32F3xx HAL library initialization:       – Configure the Flash prefetch       – Systick timer is configured by default as source of time base, but user          can eventually implement his proper time base source (a general purpose          timer for example or other time source), keeping in mind that Time base          duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and          handled in milliseconds basis.       – Set NVIC Group Priority to 4       – Low Level Initialization     */

Ana program yine bildiğimiz gibi başlıyor ve açıklamalarda hazır program hakkında bilgiler yer almakta. Ayrıca hal kütüphanesinin başlatılmasına dair bilgiler yer almakta. Şimdi hal kütüphanesinin nasıl başlatıldığını görelim.

1HAL_Init();

Bu fonksiyon ile hal kütüphanesi başlatılıyor ve kullanıma hazır hale geliyor. Bunun ayrıntılı yapısını yine CTRL + Sol Tık ile görmeniz mümkündür.

12  /* Configure the system clock to 72 Mhz */  SystemClock_Config();

Burada ise SystemClock_Config fonksiyonunun çalıştırıldığını görmekteyiz. Bu fonksiyon sistemin saat ayarlarını yapmaktadır. Saat ayarları AVR’de olduğu gibi basit değildir ve anlatılması için ayrı bir konu gereklidir.

12  /* -1- Enable GPIOE Clock (to be able to program the configuration registers) */  __GPIOE_CLK_ENABLE();

GPIO kullanmak için ilgili GPIO biriminin saatini açmamız gereklidir. Sistemimiz AVR’de olduğu gibi otomatik sistem saatinden beslenen bir yapıdan çok her yapının beslendiği saat  bulunup bunlar güç tüketimi açısından kapalı haldedir. O yüzden ADC, SPI, USART, GPIO gibi birimlerin öncelikle saatini etkinleştirmemiz gereklidir. Saat sinyali gidince o birimler çalışmaya başlayacaktır. Bu fonksiyonun aslında bir makro olduğunu ve şu komutu çalıştırdığını görmekteyiz.

1#define __GPIOE_CLK_ENABLE()         (RCC->AHBENR |= (RCC_AHBENR_GPIOEEN))

RCC -> AHBENR |= 0x00200000;  yazmakla aynı anlama geldiğini görüyoruz çünkü RCC_AHBENR_GPIOEEN adı 0x00200000 olarak tanımlanmıştır. Onu da şu satırdan görebiliriz.

1#define  RCC_AHBENR_GPIOEEN                  ((uint32_t)0x00200000)        /*!< GPIOE clock enable */

HAL kütüphanesinin donanım soyutlama katmanı olarak adlandırılmasının sebebini buradan anlamış olmanız lazımdır. Görüldüğü gibi yazmaç, bit ve değerlerle uğraşmak yerine fonksiyonlarla, yapılarla ve sabit değerlerle uğraşıyoruz. Donanıma ait her bir konu her bir bit ve özellik bir fonksiyon, tanım ya da sabit olarak tanımlanmıştır. 0x00200000 değerinin ikilik olarak “0000 0000 0010 0000 0000 0000 0000 0000” değerine geldiğini söylememiz gerekir. 8-bit AVR denetleyicilerde çalışırken bu on altılık ve ikilik sayılar pek sorun olmuyordu. Çünkü 8-bit oldukça küçük bir veri yapısıydı ve rahatça işlem yapabiliyorduk. Burada ise 32 bitten bahsetmekteyiz ve bit bazlı işlemler oldukça kafa karıştırıcı olabilmekte.

1234567  /* -2- Configure PE.8 to PE.15 IOs in output push-pull mode to drive external LEDs */  GPIO_InitStruct.Pin = (GPIO_PIN_15 |GPIO_PIN_14 |GPIO_PIN_13 |GPIO_PIN_12 |GPIO_PIN_11 | GPIO_PIN_10 | GPIO_PIN_9 | GPIO_PIN_8);  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  GPIO_InitStruct.Pull = GPIO_PULLUP;  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

Burada temel giriş ve çıkış ayaklarının tanımlarının yapıldığını görmekteyiz. AVR’de DDRx yazmacına attığımız değerle bu kolayca belirlenirken burada iş oldukça karmaşık bir hal almış durumda. Kütüphane değil de yazmaç tabanlı işlem yapsak da AVR’de olduğu gibi basit değil. Burada yukarıda verdiğimiz InitStruct yapısına ait Pin, Mode, Pull ve Speed değerlerine atama yapıldığını görmekteyiz. GPIO_PIN_15 dediğimizde yazmacın 15 numaralı bitine denk gelen ayak anlaşılmalıdır. Aynı AVR’de PB5 dediğimizde 5 numaralı bite denk gelmesi gibi burada da belli bir sabite binary değeri tanımlanmıştır. Şimdi GPIO_PIN_15’in aslında ne olduğuna bakalım.

1#define GPIO_PIN_15                ((uint16_t)0x8000)  /* Pin 15 selected   */

0x8000 değerini ikilik değere çevirdiğimizde (0000 0000 1000 0000 0000 0000) 15 numaralı bitin yani 16. bitin “1” olduğunu görüyoruz.  Bunu da yine stm32fxxx_hal_gpio.h dosyası içerisinde görmemiz mümkündür. Pin, Mode, Pull ve Speed değerlerinin uint32_t  tipinde birer değişken olduğunu unutmayalım. Yani bu değişkenlere attığımız değerler sonrasında ilgili PORT yazmaçlarına atılacaktır. RM0316 numaralı referans kılavuzunu üreticinin sayfasından indirip bu yazmaçlara siz de bakabilirsiniz. Şimdi yazmaçları yazımıza dahil etmek istemiyoruz. Şimdi diğer değer atamalarına bakalım ve GPIO yapısını tam şekliyle anlayalım.

1GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

Burada giriş ve çıkış yapısının çıkış olacağı ve push-pull şeklinde çıkış alınacağı anlatılmış. Open drain ve push-pull olarak iki farklı çıkış tipi elimizde vardır. Bunları sonra anlatacağız. Diğer GPIO modlarını ise stm32f3xx_hal_gpio.h dosyasında açıklamaları ile beraber görmekteyiz.

123456789101112131415#define  GPIO_MODE_INPUT                        ((uint32_t)0x00000000)   /*!< Input Floating Mode                   */#define  GPIO_MODE_OUTPUT_PP                    ((uint32_t)0x00000001)   /*!< Output Push Pull Mode                 */#define  GPIO_MODE_OUTPUT_OD                    ((uint32_t)0x00000011)   /*!< Output Open Drain Mode                */#define  GPIO_MODE_AF_PP                        ((uint32_t)0x00000002)   /*!< Alternate Function Push Pull Mode     */#define  GPIO_MODE_AF_OD                        ((uint32_t)0x00000012)   /*!< Alternate Function Open Drain Mode    */ #define  GPIO_MODE_ANALOG                       ((uint32_t)0x00000003)   /*!< Analog Mode  */    #define  GPIO_MODE_IT_RISING                    ((uint32_t)0x10110000)   /*!< External Interrupt Mode with Rising edge trigger detection          */#define  GPIO_MODE_IT_FALLING                   ((uint32_t)0x10210000)   /*!< External Interrupt Mode with Falling edge trigger detection         */#define  GPIO_MODE_IT_RISING_FALLING            ((uint32_t)0x10310000)   /*!< External Interrupt Mode with Rising/Falling edge trigger detection  */ #define  GPIO_MODE_EVT_RISING                   ((uint32_t)0x10120000)   /*!< External Event Mode with Rising edge trigger detection               */#define  GPIO_MODE_EVT_FALLING                  ((uint32_t)0x10220000)   /*!< External Event Mode with Falling edge trigger detection              */#define  GPIO_MODE_EVT_RISING_FALLING           ((uint32_t)0x10320000)   /*!< External Event Mode with Rising/Falling edge trigger detection       */

Burada her sabitin bir hex değerine tanımlandığını görebilirsiniz. Ayrıca kaynak kodunun aynı zamanda bir kütüphane referansı niteliğini taşıdığını söylememiz mümkündür. Burada kullanabileceğiniz bütün GPIO yani temel giriş ve çıkış modları görülmektedir.

1GPIO_InitStruct.Pull = GPIO_PULLUP;

AVR’de sadece dahili pull-up işlevinden söz etmemiz mümkündü. Burada ise pull-up, pull-down ve no-pull olarak üç adet pull işlemimiz bulunuyor. Hazır kodda pull-up olarak tanımlandığı için buna dokunmayacağız. Pull değerine üç farklı değer atamamız mümkündür çünkü kaynak kodunda böyle belirtilmektedir.

123#define  GPIO_NOPULL        ((uint32_t)0x00000000)   /*!< No Pull-up or Pull-down activation  */#define  GPIO_PULLUP        ((uint32_t)0x00000001)   /*!< Pull-up activation                  */#define  GPIO_PULLDOWN      ((uint32_t)0x00000002)   /*!< Pull-down activation                */

En son olarak hız ayarımızın bulunduğu Speed değişkenine değer atayacağız.

1GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

Biz temel giriş ve çıkış birimlerinin hızını ayarlayabiliriz. AVR’de olduğu gibi işlemcinin saat hızına bağlı olmayıp farklı bir saat hızında çalıştıkları yani aslında işlemcinin gelişmiş bir saat donanımı olduğu için bu temel giriş ve çıkış birimlerinin hızını değiştirmemiz işlemci hızını değiştirmeyecektir. Hızını artırıp azaltmamız ise güç tüketimine bağlıdır bu yüzden HIGH yapıyoruz. Diğer modları ise kaynak dosyasında şöyle görmemiz mümkündür.

123#define  GPIO_SPEED_LOW         ((uint32_t)0x00000000)  /*!< Low speed     */#define  GPIO_SPEED_MEDIUM      ((uint32_t)0x00000001)  /*!< Medium speed  */#define  GPIO_SPEED_HIGH        ((uint32_t)0x00000003)  /*!< High speed    */

Böylelikle GPIO_InitTypeDef yapısına ait tip tanımlamasına göre GPIO_InitStruct olarak tanımladığımız yapı değişkenine ait tüm değerleri ve parametreleri görmüş olduk. Şimdi bu değişkene ait konfigürasyon değerlerini mikrodenetleyicinin yazmaçlarına yüklememiz gerekli. Bunun için ise HAL_GPIO_Init fonksiyonunu kullanmaktayız.

1HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

Burada GPIOE argümanı port adı olup GPIOx yani x yerine herhangi bir harf değeri alabilir. Örneğin A portu ise GPIOA değerini kullanırız. STM32f303xc.h başlık dosyasında ise kullanabileceğimiz GPIOx değişkenleri yazılıdır.

123456#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)#define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)#define GPIOD               ((GPIO_TypeDef *) GPIOD_BASE)#define GPIOE               ((GPIO_TypeDef *) GPIOE_BASE)#define GPIOF               ((GPIO_TypeDef *) GPIOF_BASE)

Bu başlık dosyası bizim kullandığımız mikrodenetleyicinin donanım özelliklerine ait tanımlamaları içerir. Aynı AVR’de PORTx, DDRx, PINx tanımlamalarının olduğu mikrodenetleyici başlık dosyası gibidir. Şimdi while(1) içindeki programı silelim ve kendi programımızı yazalım. Biz sadece bir adet ledi yakıp söndüren bir program yazacağız.

Burada hazır olarak gördüğümüz iki fonksiyon yer almaktadır. Bunlardan biri HAL_GPIO_TogglePin fonksiyonu öteki ise HAL_Delay fonksiyoınudur. Program tekrarlayan biçimde şu iki fonksiyonu kullanmaktadır.

123  HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_15);    /* Insert delay 100 ms */    HAL_Delay(100);

Bu iki fonksiyonun işlevini adlarından da öğrenebiliriz. Bir tanesi yakıp söndürme (toggle) özelliği öteki ise delay (bekletme) özelliğine sahip. Aldıkları parametreleri öğrendikten sonra istediğimiz gibi kullanma imkanımız olur. Önceden nasıl ayak tanımlaması yapacağını öğrendik şimdi ise sadece tanımladığımız ayakları bu fonksiyonlarla doğru bir şekilde kullanacağız.

HAL_GPIO_TogglePin fonksiyonunun parametrelerinin şu şekilde olduğunu görüyoruz.

1void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

Yani bir adet GPIOx argümanını başta almakta ve sonrasında bizim kullandığımız GPIO_Pin değerini uint16_t yani işaretsiz 16 bitlik tam sayı olarak almaktadır. Bu durumda buraya ikilik ya da onaltılık olarak da değer yazabilsek de önceden tanımlanmış GPIO_PIN_x ( x = 0-15) değerini yazabiliriz. Bu tanımlamayı yukarıda bahsetmiştik.

GPIOx dediğimiz ise yine önceden bahsettiğimiz tanımlanan GPIO tiplerinden biri olabilir. Burada A-F arası harfler olduğunu görüyoruz. Bu durumda fonksiyonun örnek söz dizimi şöyle olabilir.

1HAL_GPIO_TogglePin(GPIOx, GPIO_PIN_x);

Bu fonksiyonun nasıl çalıştığını ise yine kaynak kodundan görmekteyiz. Aslında bu fonksiyon AVR’de kullandığımız PORT yazmaçlarına değer atamaktan veya Arduino’daki digitalWrite fonksiyonundan farklı bir iş yapmamakta. Tabi ki Arduino gibi ucuz bir kütüphanede ve AVR gibi bir sistemde bu giriş ve çıkış işlemi oldukça performanssız gerçekleşse de HAL kütüphanesinde bunu pek dert etmek gerekmez. Şekilde görüldüğü gibi tek bir komutla alınan değerlere göre ODR yazmacına (Output Data Register) değerler yazılmaktadır.

1GPIOx->ODR ^= GPIO_Pin;

HAL_GPIO_TogglePin  fonksiyonunu yeteri kadar anladıysak şimdi de HAL_Delay fonksiyonuna geçelim. Bu iki fonksiyonu anlamadan ezbere kod yazarak öğrendiğimizi iddia edemeyiz. Eğer ezbere kod yazarak bir şeyler yapmak istiyorsak STM32 ile hiç zahmete girmemize gerek yok. Arduino hazır kodu da ezbere kodu da kopyala yapıştır yöntemini de zirveye çıkarmış durumdadır.

Şimdi HAL_Delay fonksiyonuna bakalım.

1234567__weak void HAL_Delay(__IO uint32_t Delay){uint32_t tickstart = HAL_GetTick();while((HAL_GetTick() – tickstart) < Delay){}}

Görüldüğü gibi Arduino’daki delay fonksiyonuna benzer bir şekilde fonksiyon ilk başladığında alınan süreyi geçen süreyle kıyaslayıp programı sonsuz döngüye sokarak meşgul etmektedir. Aldığı argüman uint32_t büyüklüğünde olup mili saniye değeridir. Bu delay fonksiyonu SysTick adına donanımsal bir zamanlayıcıyı referans almaktadır. HAL/LL Referans kılavuzunda ise bu fonksiyondan bahsedilmektedir. Sadece kaynak dosyalarını inceleyerek öğrenmek zorunda değiliz.

Burada fonksiyonun ne işe yaradığı, adı, geri döndürdüğü değerler ve aldığı parametreler daha iyi açıklandığı için kütüphane referans kıavuzunu okumayı ihmal etmemek gereklidir.

Şimdi iki fonksiyonu da öğrenmiş olduk. HAL_GPIO_TogglePin bir ayağı açıp ya da kapatıyor. HAL_Delay() ise mili saniye bazında bekleme yapıyor. Şimdi tek bir ledi yakıp söndürecek kodumuzu yazalım.

123456while (1)  {    HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_15);    HAL_Delay(500);     }

Kodumuz bu kadar sade ve basit bir hale geldi. E portunun 15 numaralı ayağı 500 mili saniye aralıklarla yanıp sönecek. Fakat öncesinde derleme işlemini yapmamız gereklidir. Bunun için resimdeki “Build” düğmesine tıklıyoruz.

Eğer bir hata olmadıysa alt taraftaki konsol ekranından derlemenin başarı ile gerçekleştiğine dair bir mesaj almamız gereklidir.

Artık derleme başarı ile gerçekleştiyse böcek ile simgelenen debug düğmesine tıklayarak hata ayıklama moduna geçiyoruz. Böylelikle yazdığımız programı deneme imkanına sahip oluruz ve aynı zamanda hata ayıklama özelliklerini kullanabiliriz.

Debug ekranında pek çok özellik olsa da şimdilik ilgileneceğimiz tek bir düğme var. Debug moduna girince STM32F3 Discovery kartınaki programlayıcı ledi yeşil ve kırmızı olarak yanıp sönmeye başlayacaktır. Şu düğmeye tıklayarak programı başlatalım.

Debug işlemi başlayınca kartımızda program çalışacak ve led yanıp sönmeye başlayacaktır. Aşağıdaki videodan göreceğiniz üzere STM32 ile ilk programımızı yapmış olduk.  Bu ilk program bazı Youtube derslerinde olduğu gibi ezbere kod yazıp çalıştırmaktan öte size nasıl kod yazılacağını, fonksiyonların nasıl kullanılacağını ve nasıl programlama yapılacağını öğretti. Bunu “şu kodu yazıyoruz sonra şuraya tıklıyoruz” diyerek çok daha kolay bir şekilde anlatabilirdik fakat sizin bir kazanımınız olmazdı. O yüzden bu yazıda anlatılanların hepsini anlamaya çalışmanız gereklidir.

Hakkında Onur NP

Arduino Stm32 gibi Mikrodenetleyici PLC Otomasyon sistemleri ve Genel elektronik projeleri üzerine örnek paylaşımlar yapmaktayım Endüstriyel ve Kişisel proejelerinize Ücretli olarak destek verebilirim.

Kontrol edin.

STM32 PWM Nedir ?

STM32 Arduino PWM Nedir ? Nasıl Kullanılır ? İçerikSTM32 Pwm nedir ?STM32 PWM Nasıl Çalışır …

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir