atmega8535Bugünkü C dili ile AVR programlama dersimizde, değişkenler ve operatörler konusu inceleyelim derim ben. Bunu yaparken konu olarak değil, bir program üzerinden giderek anlatacağım, böylece hep program yazımını görecek hem de konuyu anlamış olacaksınız. Ders başlıyor: Atmel AVR'de Operatörler ve değişkenler (variables).

Kara şimsek dediğimiz mikro denetleyici programlamaya yeni başlayanların ilk projesi olur genelde. Bu programda, sekiz ya da daha fazla led yan yana dizilir ve bunların hızlı biçimde teker teker ve sırasıyla yanıp sönmesidir. Aşağıdaki programı siz de AVR Studio 4’de WinAVR C derleyicisini kullanarak derleyiniz. Proje oluşturma ve derleme olaylarını bir daha anlatmıyorum, okumayanlar ilk dersimize dönsün ve baksınlar.


#include <avr/io.h>               // giriş çıkış registerlerin tutulduğu dosya
#define F_CPU 4000000UL     // Osilatör frekansı 4MHz
#include <util/delay.h>         // gecikme fonksiyonunun bulunduğu dosya

void main()
{

char AktifLed;                       // 8 bitlik değişken tanıttık

AktifLed = 0;                        // değişkene değer atadık
DDRB = 0xFF;                    // PORTB'yi çıkış olarak ayarladık
PORTB = 0x00;                   // PORTB'yi temizledik

do{

PORTB = (1 << AktifLed);          // Lojik-1'i, bir sola kaydır

_delay_ms(50);                      // 50ms bekle

AktifLed++;                          // kaydırılacak bit sayısını bir arttır

if(AktifLed == 8) AktifLed = 0;     // toplamda 7 kere kaydıysa kaymayı sıfırla

}while(1);                               // sonsuz göngü

return 0;

}


Program gözünüzü korkutmasın, yeşil yazılar programa dahil değil, onlar sadece birer açıklama ve derleyici onları değerlendirmez. Bunlara yorum satırı denir. ve İki slash ifadesinden "//" sonra yazılır.

A. Değişkenler (Variables)

Yukarıdaki programımızın en başında, char diye bir değişken tanımladık. Değişken tanımlamak demek, İşlemciden RAM alanında bize bir yer tahsis etmesini istemek demektir. Bu yeri niye talep ediyoruz? Çünkü kullanmak istediğimiz bilgiyi oraya koyacağız. Arsanız olmadan ev yapabilir misiniz? Olmaz değil mi?

İşte değişken, bize programımızın akışı içinde lazım olacak bilgileri sakladığımız register’a denir. Adının değişken (variable) olmasının sebebi nedir peki? Adı üstünde program süresince değerinin boyuna değişiyor olması. Mesela, bizim bu programımızdaki değişken AkitfLed++ satırıyla her çevrimde bir artıyor. Değişkenler boyutlarına göre tanımlanır. Bu da bizi değişken türlerine götürür. Başlıca kullandığımız üç değişken türü vardır:

char: 8 bitlik değişken türüdür. Yani 128’den -127’ye kadar değerler alır.

Int: 16 bitlik değişken türüdür. −32768 ’dan 32767’ye kadar değerler alır.

long Int: 32 Bitliktir. -2147483648'den  2147483647'a kadar değer alır.

Yukarıdaki üç değişken türünün başına “unsigned” ifadesini koyarsak sadece pozitif değerler alır, negatif değerler alamaz. Yani;

Unsigned char AktifLed dediğimizde, değişken 0’dan 255’e kadar,

Unsigned Int AktifLed dediğimizde, değişkenimiz 0’dan 65535’e kadar,

Unsigned Long Int dediğimizde ise değişkenimiz 0’dan 4294967295'e kadar değerler alır.

Değişken kavramını anladıysak geçelim. Kısaca değişkenler, benim programım içinde değerinin değişeceğini bildiğim değerleri saklamam için gereklidir.

Niye değişken tanımlama ihtiyacımız olduğuna dair şöyle somut bir örnek verelim mi? Yine komodin bir örneği. Ama değişkenin niye tanımladığını biliyorsak aşağıdaki örneği okumanıza gerek yok, geçebilirsiniz:

Şimdi yüz tane çekmecesi olan bir komidin düşünün. Elimde de elmalar, armutlar, erikler, muzlar vb… birçok meyve türü var. Babam bana ne zaman bir meyve verse götürüp komidin çekmecelerine koyuyorum.

Ama koyarken sınıflama yapmıyorum. Hâlbuki komidin çekmecilerine birer etiket yapıştırsam. Elma çekmecesi, Armut çekmecesi; muz çekmecesi vb diye ve babamın verdiği meyvaları bu etiketlere göre koysam daha iyi olmaz mıydı. Çünkü sonuçta o meyveler orada sonsuza kadar durmayacak, yeri geldiğinde alıp yiyeceğim yani kullanacağım. Örneğin canım muz istediğinde, gidip muz çekmecesinden alırım. Elma istiyorsa elma çekmecesinden. Hâlbuki etiket yapıştırmasaydım,  canımın istediği meyveyi bulana kadar bütün çekmeceleri karıştırmam gerekirdi. Gittim muz çekmecesinden bir muz aldım, elma çekmecesine bir elma koydum. Sürekli bir değişim (eksilme ya da azalma) var.

İşte ey gafil gönlüm, yukarıdaki misalde çekmece fani dünya, etiketler de amellerindir... Eee şey pardon hatlar karıştı :) Çekmeceler register, etiketler de değişken türleridir.

B. Operatörler

Operatörler, mantıksal işlemler, aritmetik işlemler ya da bit işleyici olarak kullandığımız işaretlerdir.

Aritmetik Operatörler:

Operatör

Yaptığı iş

Örnek

+

Toplama

a = a+b

-

Çıkarma

a = a-b

*

Çarpma

a = a*b

/

Bölme

a = a/b

++

1 ekleme

a++; a’ya 1 ekler

--

1 çıkarma

a--; a’dan 1 çıka

Diğer operatörleri uzun uzun yazmayacağım, yeri geldikçe tanırız. Bu tabloyu incelediyseniz yukarıdaki kara şimşek programında AktifLed++ yazarak ne yapmak istediğimizi anlamış olmalısınız. AkitfLed’in içeriğini 1 arttırdık, yani komidinin elma çekmecesine bir elma koyduk.

 

Bitwise Operatörü

Bu programda kullandığımız ve ileride de sıkça kullanacağımız bir operatör daha var.  Matematikte küçük küçük, ya da çok küçük manasına gelen “<<” işareti. Bu işaret C dilinde “sola kaydır, bakayım” demektir. Kullanımı;

PORTB = 1 << 5 yazarsak, Decimal “1” sayısını 5 defa sola kaydırır. Tabi binary olarak, Yani sayı 00000001 iken 00100000 olur.

PORTB = 3 << 4 yazarsak, Decimal “3” sayısını 4 defa sola kaydırır. Yani sayı 0000 0011 iken, 00011000 olur yani her bit 4 hane sola kayar.

Bizim kara şimşek örneğinin foyası ortaya çıkmış oluyor böylece. Her defasında kaydırma oranını bir artırarak bir sonraki ledin yanmasını sağlıyormuşuz meğer,  yani;

PORTB = (1 << AktifLed);

Satırında AktifLed en başta sıfır olduğu için kayma olmayacak ve PORTB = 1 değerini alacak.

Bir sonraki çevrimde AktifLed önceden ++ ile bir artırıldığı için PORTB = 2 olacak, Bir sonrakinde PORTB =4. böyle devam edecek, her seferinde 1 değerini bir sola kaydırmış olacağız. Bunun bir manasının da ikiyle çarpmak gibi olduğu gözünüzden kaçmasın. Dolayısıyla bizim PORTB sırasıyla 1,2,4,8,16,32,64,128 değerlerini alacak. Ama bu bahsettiğimiz Decimal değerler. Halbuki işlemciler binary ile gösterim yaparlar. Dolayısıyla PORTB’de sırasıyla;

00000001
00000010
00000100
00001000
00010000
00100000
01000000
10000000

Değerleri alacak. Delay_ms(100) ile bunların arasına biraz gecikme koyduk ki gözümüz ledlerin yanıp sönmesini yakalasın.  Bu gecikmeyi koymazsak gözümüz ledleri sürekli yanıyormuş gibi görür. Çünkü göz saniyede 25 haraketten fazlasını algılamaz.

if(AktifLed == 8) AktifLed = 0; satırıyla bit kaydırma miktarı 7’yi geçerse, kaydırma miktarını sıfırlıyoruz. Bizim PORTB 8 bitlik olduğu için en fazla 0 ile 7 arası kayar.
Do - while döngüsünün maharetini geçen hafta anlatmıştım. Süper döngü, olmazsa olmaz.

Aşağıdaki animasyon resimde, yukarıdaki programı proteusta simule edişimi görüyorsunuz.

karaşimşek devresi animasyon

Bu yazı yine uzadığı için daha fazla yazmayacağım.  Debug olayını anlatacaktık ama şuradaki yazımızdan bakarak siz de yapabilirsiniz. Bu programı Proteus’da nasıl simüle edebilirim sorusunun cevabını da şuradaki bir başka yazıdan bulabilirsiniz.

Haftaya if () ve switch () kontrol yapılarını ayrıntısıyla anlatalım. Tabi yine örnek bir program üzerinden. Haftaya kadar sorunuz varsa yorum kısmına yazabilirsiniz.

İyi günler.

 

Anahtar Kelimeler: Mikrodenetleyici, Atmega8 Programlama, Atmel AVR Dersleri, Atmel AVR Karaşimşek Devresi, Atmel AVR Tutorials, C de Değişken Türleri, C de Operatörler, C ile Karaşimşek Programı, Proteus AVR C Simülasyon, WinAVR Kullanımı

peynir6 suyu tozu , 19/02/2010-19:44 Facebook'ta Paylas