Bir önceki dersimizde basit şekilde led nasıl yakılır ve pic14,
pic16 serisine mensup mikrodenetleyicilerin sigorta ayarlarının
yapılmasındaki farkı anlamaya çalıştık. Aslında tek kelimelik
bir farkmış :) Dikkat ettiyseniz derslerimizde bir tek işlemci
üzerinden anlatımı yapmak yerine neredeyse her derste farklı bir
işlemci ile örnek yapıyoruz. Esasında bu şekilde yapmak bayağı
bir zorluyor insanı. Kitap yazarlarının neden tek
mikrodenetleyiciye bağlı kitap yazdıklarını şimdi daha iyi
anlıyorum. Benim farklı mikrodenetleyicileri seçmemin sebebi zaten
bilinen led yak söndür, butona bas zıplasın örneklerini hemen
hemen tüm kitaplarda birbirinin kopyası niteliğinde
bulabiliyorsunuz. Bunları birde benim tekrarlamamda bir anlam yok.
Bize bilinmeyen farklılıklar lazım. Sdcc ile ilgili Türkçe bilgi
azlığından dolayı bende elimden geldiğince öğrenilmesi gereken
farklılıklara dikkat çekip, yazı yazarken bir taraftanda kendime
de öğretmek.
Bu dersimizde piyasanın en çok üzerine belki yazılıp çizilmiş
mikrodenetleyicisi olan PIC16F877A yı kullanıp buton led yakma
uygulaması yapacağız. Şunu artı bilgi olarak paylaşmak
istiyorum; microchip firması PIC16F877 yerine PIC16887 yi önermekte.
Bazı yerlerde iyileştirme yaptıklarından da bahsediğini duydum.
Herneyse buda aklınızda bulunsun. Hem daha da ucuz.
Devre şemamızı ve mikrodenetleyici kodumuzu aşağıda vererek işe
başlayalım.
//
Copyright (C) 2015 Durali Kiraz
//
PIC16F877A için hazırlandı.
#define
NO_BIT_DEFINES
#include
<pic14regs.h> //Mikrodenetleyici Ayar adreslerini ve
seçenekleri içerir
//#include
<stdint.h> //uint16_t tanımı için gerekliydi. Şimdi ise
tipi kendimiz tanımladık.
typedef
unsigned short int uint16_t;
//sigorta
tanımlarımızı yapıyoruz.
__code
uint16_t __at _CONFIG __configword =
_FOSC_XT
&&
_WDT_OFF
&&
_BOREN_OFF
&& //Brown Out
Reset (BOR) Disable
_LVP_OFF;
#define
LED_PORT PORTBbits.RB0
#define
BUTON PORTAbits.RA0
#define
TRIS_A0 TRISAbits.TRISA0
#define
TRIS_B0 TRISBbits.TRISB0
void
main(void)
{
ADCON1
= 0x07; //PortA yi dijital olarak yönlendirdik.
TRIS_A0
= 1; //A0 giriş olarak seçildi.
TRIS_B0
= 0; //B0 çıkış olarak seçildi.
LED_PORT
= 0; // LED sönük
BUTON
= 0; // Buton pasif
while(1)
{
LED_PORT
= BUTON;
}
}
Bu
koddaki birinci değişiklik tek bir adet uint16_t tipi için
<stdint.h>
başlık
dosyasını koda ekleyip gereksiz bir kod şişkinliği yapıyorduk.
Bunun yerine bu tipi bu ana kodun içinde tanımlayıp bizim için
çok önemli olan microdenetleyici program hafızasından tasarruf
etmiş olduk. Mikrodenetleyici programı yaparken bu hususa dikkat
edilmediği takdirde daha yüksek hafızalı ve daha pahalı olan
entegrelere para yatırmış olursunuz. Buda istenmeyen bir durumdur.
Yine
dikkatinizi çektiği üzere sigorta ayarlarımızı kullanacağımız
16F877A aygıtına göre şekillendirdim. Bu konuda pic16F877a.h
isimli dosyanın içine (/usr/local/share/sdcc/non-free/include/pic14
dizininden bulabilirsiniz) bir göz atmam gerekti. Buradaki osilatör
ve sigorta tanımlarına ve açıklamalarına bakarak bu tanımlamayı
kendi ihtiyacıma göre yaptım. Diğer derslerde belirtmediğim
_BOREN_OFF
&& //Brown
Out Reset (BOR) Disable Sigorta
ayarı kısaca giriş voltajı eşik değerin altına indiğinde
mikrodenetleyici kendini resetlemesin anlamında bir ayardır. Voltaj
eşik değeri genelde +5 volttur. Diğer
bir sigorta ayarı olan _FOSC_XT
ile XT
tipinde harici bir kristal osilatör kullanacağımı derleyiciye
bildirdim. Eğer
yüksek hızlı misal 20 MHZ lik bir osilatör kullandıysam devrede
bu ayar _FOSC_HS
şeklinde olması gerekirdi. Dikkat
ettiyseniz bir önceki derslerde hep dahili osilatörle çalışmıştık.
PIC16F877A nın dahili osilatörü olmadığı için bu örnekteki
harici osilatör kullanma örneği bizim farkı anlamamız açısından
önemlidir. Burada
benim vermiş olduğum sigorta ayarları tamamen bir örnektir
arkadaşlar. Siz kendi ihtiyacınıza göre kendi sigorta
parametrelerinizi && işaretlerinin yanına ekleyerek
oluşturacaksınız. Yoksa burada yazılan hersatır kural değildir.
“#define
LED_PORT PORTBbits.RB0” şeklinde ifade tanımlarımızın nasıl
yapıldığını ve ne amaçla yapıldığını daha önceki
derslerde zannedersem bahsettim. İsterseniz LED_PORT gibi bir ifade
yerine program içinde PORTBbits.RB0 tanımını doğrudan
kullanarak program yazabilirsiniz. Genelde biz kod okunaklığını
daha iyi yapmak adına yeni bir sembol tanımlayıcı ile yani
LED_PORT gibi bir isimler kullanırız. Dediğim gibi isterseniz
kullanmayabilirsiniz.
Main
ana fonksiyonumuzda sırasıyla
-
ADCON1 = 0x07;ile PORTA nın dijital olacağını (anolog olamayacağını),
-
TRIS_A0 = 1; ile A0 ın giriş için kullanılacağını
-
TRIS_B0 = 0; ile B0 in çıkış için kullanılacağını
-
LED_PORT = 0; ile led_port a lojik sıfır sinyali atadığımızı
-
BUTON = 0; ile butonumuzun basılı olmadığını yine lojik sıfır ile atamasını yapıyoruz.
Daha
sonrasında while(1) işlem bloğumuz başlamakta. İsterseniz bu
ifadenin yerine for(;;) şeklinde bir blok başlatabilirsiniz.
Sonuçta iki ifadede sizin için sonsuz döngüyü başlatacaktır.
Bu bloğumuzun için de sadece bir satırlık LED_PORT
= BUTON;
ifadesi var. Bu ifade LED_PORT içine BUTON ile tanımlı ifadenin
sayısal değerini atar. Yani BUTON 1 ise LED_PORT' a lojik 1 yani 5
voltu gönderir. Dolayısıyla led eğer buton 1 ise yani basılı
ise yanar. Eğer buton 0 ise yani basılı değilse ledimiz sönük
olacaktır. Bu sonsuz döngü içerisindeki kod bloğumuz sonsuza
kadar butona basılımı? Değilmi? Sorgulamasını yapıp led imize
sonuç gönderecektir. Zaten bu koddan amaçlanan bu.
Bir
sonraki derslerde daha iyi
örneklerle buluşmak üzere hoşçakalın.
duralikiraz.blogspot.com
16
Haziraz 2015
“Muvaffakiyet
Allahtandır”
Hiç yorum yok:
Yorum Gönder