Hakan Kaya

ARM Uygulamaları – STM32F411 Karaşimşek

 

Aslında karaşimşek uygulaması aman aman önemli bir konu değil. Okulda öğretmenler verdikleri ödevlerde “sadece bir karaşimşek devresi yapmanız yeterli” gibi şeyler duyunca belki birilerinin işine yarayabilir diye paylaşıyorum.

 

Birden fazla algoritma ile kart üzerinde LED’leri sırasıyla yakacağız. Biraz challenge yapabiliriz aslında bu konuda 🙂

Öncelikle yeni bir proje açıp RCC, GPIO gibi kütüphaneleri projeye eklediğinizi varsayıyorum. Eski yazdıklarımda bunlara değinmiştim aratabilirsiniz.

Kart üzerinde 4 adet LED’imiz bulunmakta. Bu ledlerimiz aynı zamanda D portunun 12,13,14,15. pinlerine bağlı olduğunu datasheettinden öğrenmiştik.

ARM mimarisinde GPIO için bir bus interface aktifleştirmemiz gerektiğini ve D portu için bunun AHB1 olduğunu da öğrenmiştik.

Öncelikle stm32f4xx_rcc.c source (kaynak) dosyasına bakalım. İçerisindeki fonksiyonlara hızlı hızlı atlamak için pencerenin sağ üst köşesinde bulunan f() butonuna basabilirsiniz.

Bu butona bastığınızda;

gibi bir çok fonksiyonlar listelenecektir. AHB1 bus’ını açmamız için RCC_AHB1PeriphClockCmd fonksiyonuna gitmemiz gerek.

Bu fonksiyonu incelediğimizde;

Bir tane unsigned 32 bit integer olan RCC_AHB1Periph ve yeni bir tipten yaratılmış NewState adında iki adet argüman (parametre) aldığını görebiliyoruz sanırım. Demek ki biz bu fonksiyonu kullanmak istediğimizde 2 argüman vermemiz gerecek.

Peki buralara ne yazacağız?

Fonksiyonun hemen yukarısında ise;

fonksiyonda kullanmamız için tanımlanmış olan parametreler listelenmektedir, GPIOD için RCC_AHB1Periph_GPIOD kullanacağımızı öğrenmiş olduk. NewState ise clock durumunun on-off konumunu belirttiğini ve ENABLE yazmamız gerektiğini de öğrendik ayrıca.

Tekrar bir hatırlatma yapayım. Kütüphaneler sürekli aynı kodları yazmaktansa bir kere yazıp sonra istediğimiz kodu kütüphaneden çalıştırmasını sağlayan kod dosyalarıdır. Herkes kendi kütüphanesini yazabilir yada başkalarının kütüphaneleri kullanabilir. Burada kullanacağımız çeşitli kütüphaneleri dikkatlice göz atmanızı tavsiye ederim. Hazıra konmadan önce bu adamlar bunu nasıl yapmış bir bakalım demelisiniz.

D portu için GPIO clock bus’ı açmak için;


RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

Şimdi GPIO D portu için gösterici yaratıp, pin ayarlarını yapacağız;

GPIO_InitTypeDef GPIO_D;

GPIO_StructInit(&GPIO_D);

GPIO_Init(GPIOD, &GPIO_D);

Burada tek tek pin ayarlarini yapmak yerine kütüphane içerisindeki hazır bir fonksiyonu kullandım. Bakalım o fonksiyon nasılmış?

Daha önce fonksiyon içerisindeki kodları kopyalayıp öyle yapmıştık ancak bu sefer değişik stilde kullanayım dedim. Reset değerlerini çıkış olarak tanımlıadım ve hızları, push pull’ları istediğim şekle soktum. Hazır fonksiyonu kullanmadan önce istediğiniz şekilde mi kontrol edin, ufak düzenlemeler yapma gereği duyabilirsiniz.

Sonra tüm bunları daha yakışıklı durması amacıyla GPIO_Ayarlari adında bir fonksiyon içerisine yazdım.


void GPIO_Ayarlari(){

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

GPIO_InitTypeDef GPIO_D;

GPIO_StructInit(&GPIO_D);

GPIO_Init(GPIOD, &GPIO_D);

}

 

Basit bir zamanlayıcı fonksiyonu kuruyoruz sırada;


void delay(unsigned long zaman){
while(zaman > 0){
zaman--;
}
}

 

Şimdi geldik main kodumuzu stm32f4xx_gpio.h header dosyasına baktığımızda GPIO Pin adreslenmeleri aşağıdaki gibidir;

Biz burada 12,13,14,15. pinlerimizi sırasıyla lojik-1 yapacağımıza göre küçük bir ayrıntıyı dikkat çekmek isterim 16 bitlik bir sayının herhangi bir bitindeki 1 sayısını sağa yada sola kaydırmayla bir sonraki pini aktifleştirmiş oluyoruz. Hesap makinesinde kendiniz bunu gözlemleyebilirsiniz.

 

Örneğin 13. pine ait binary formatındaki sayı 0010000000000000 şeklinde yazılır ve 1 değeri barındıran biti bir tık sola kaydırdığınızda decimal olarak 0x4000 değerini bulacaksınızdır.

uint16_t tipinde bir değişken yaratıp 12. pini lojik-1 yapmamız için gerek değeri başlangıç değer olarak veriyorum. While döngüsünde bu değeri sürekli 1 bit sola kaydırıyorum ta ki son değer ulaşana kadar. Son değere ulaştığında ise tekrar başlangıç değerine eşitleyip bu şekilde sonsuz döngüde bırakıyorum.

Ancak 16 bitlik bir sayının (bu bitinde 15. ledimiz bulunmakta) son bitinden sonra değeri 0 (sıfır) olacaktır. Burada eşitlemeyi 0 olarak yapıyoruz.


int main()
{
 GPIO_Ayarlari();

 uint16_t pin = 0x1000; 
 
 while(1){ 
 GPIO_ToggleBits(GPIOD, pin);
 pin = pin << 1;
 delay(2000000);
 if(pin == 0x0) pin = 0x1000;
 } 
}

 

Tüm kodların derli toplu hali aşağıdaki gibi olacaktır.

Kod:


/* Karasimsek - Stm32f411
** @author: Hakan Kaya
** @date : 2.11.2016
** @mail : mail@hakankaya.kim
*/

#include "stm32f4xx.h"

void GPIO_Ayarlari();
void delay(unsigned long zaman);



int main()
{
 GPIO_Ayarlari();

 uint16_t pin = 0x1000; 
 
 while(1){ 
 GPIO_ToggleBits(GPIOD, pin);
 pin = pin << 1;
 delay(2000000);
 if(pin == 0x0) pin = 0x1000;
 } 
}

void GPIO_Ayarlari(){
 
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

 GPIO_InitTypeDef GPIO_D;

 GPIO_StructInit(&GPIO_D);

 GPIO_Init(GPIOD, &GPIO_D);

}

void delay(unsigned long zaman){
 while(zaman > 0){
 zaman--;
 }
}

Exit mobile version