CCS-C Dersleri Önişlemci Direktifleri - 1
Aslında bu yazıyı tatilden önce yazmıştım ama insan tatil moduna girince hiç bir şeye dokunmak istemiyor. Tatil dediğimde memleket ziyaretinden ibaret. Kısa sürdü ama güzeldi
Bol bol hormonsuz sebze meyve yedim
İnsanın doğup büyüdüğü topraklar gibisi yok. Oralarda iş imkanım olsa İstanbulda bir dakika durmayacağımı garanti ederim
Önceki yazımda önişlemci direktiflerini anlatacağımı belirtmiştim. CCS-C derleyicisinde kullanılan önişlemci direktifleri hayli fazla olduğu için birkaç ders olarak yayınlayacağım.
Bu yazıda anlattığım önişlemci direktifleri arasında en önemli olanlar #byte ve #bit direktifleridir. CCS-C nin dahili fonksiyonlarını kullanmadan kod yazabilmek için bu direktiflerin bilinmesi gerekmektedir.
Bir çok arkadaşın CCS-C yi eleştirdikleri en önemli nokta, her şeyin kolay yoldan halledildiği hazır fonksiyonların kullanılması nedeniyle kodun başka platformlara taşınamamasıdır. CCS-C derleyicisi #byte direktifi ile PIC içerisindeki tüm SFR’leri kodunuzda tanımlamanıza izin verdiğinden bazı arkadaşların datasheet’e bakıp kod yazma dedikleri hadiseyi CCS-C ile de gerçekleştirebilirsiniz
YAZI İÇERİĞİ
#asm
#endasm
#byte
#bit
#locate
#word
#build
#case
#define
#device
#list
#nolist
#asm, #endasm
C kodunuzun içerisinde Assembly komutları yazmak istiyorsanız bu iki direktifi kullanmanız gerekir. Bilgisayar sistemlerinde de olduğu gibi çalışma hızının veya kod optimizasyonunun önemli olduğu kısımlarda Assembly komutları kullanılabilir. Kullanım şekli aşağıda gösterilmiştir.
#asm
Assembly Kodları
#endasm
CCS-C Help dosyasında örnek olarak verilen parity hesaplayan Assembly Fonksiyon
int find_parity(int data){
int count;
#asm
MOV #0x08, W0
MOV W0, count
CLR W0
loop:
XOR.B data,W0
RRC data,W0
DEC count,F
BRA NZ, loop
MOV #0x01,W0
ADD count,F
MOV count, W0
MOV W0, _RETURN_
#endasm
}
#BYTE, #BIT
Bu iki direktif oldukça önemlidir. Bilindiği gibi CCS-C derleyicisi her türlü işlem için hazır fonksiyonlara sahiptir. Sizin herhangi bir ayarlama yapmanıza gerek kalmaz. Böylelikle çok hızlı ve pratik bir biçimde istediğiniz programı yazarsınız ama bu programı başka platformlara aktarırken başınız ağrır.
#byte ve #bit direktiflerini kullanarak PIC içerisindeki tüm SFR’leri (Special Function Registers, ADCON,INTCON,TRISA vs.) Kodunuza tanıtabilir ve kod içerisinde rahatlıkla kullanabilirsiniz. Şahsen ben bu şekilde kullanmaya özen gösteriyorum.
#byte direktifi istenilen adres bölgesinde 8 Bitlik (1 Byte) değişken tanımlamak için kullanılır. Kullanımı aşağıdaki gibidir.
#byte id=x
id: Değişken adı
x: Adres bölgesi
Örneğin A portu ve A portuna ait Tris tanımlamalarını yapalım
Yukarıdaki resim PIC16f628 denetleyicisine ait datasheet’ten alınmıştır. Adres haritasında PORTA ve TRISA SFR’lerine ait adres bölgelerinin 0×05 ve 0×85 olduğu görülmektedir.
#byte A_PORTU = 0x05 // A portu PIC'te 0x05 adresindedir #byte A_TRIS = 0x85 // TRISA PIC'te 0x85 adresindedir bu tanımlamalar yapıldıktan sonra kod içerisinde şu şekilde kulanabilirsiniz. A_PORTU = 0; A_TRIS = 0x03; // A0,A1 giriş diğerleri çıkışa ayarlanıyor if(A_PORTU & 0x01) // A0 girişi pini 1 mi?
#bit direktifi #byte ile tanımlanmış veya int,int8 ile Ram de tanımlanmış 8 bitlik bir değişkenin istenilen bitini tanımlar. Kullanılışı aşağıdaki gibidir.
#bit id = x.y
id: Değişken adı
x: C değikeni veyahut #byte ile tanımlanmış değişken
y: 0-7, tanımlanmak istenen bit.
A0 Pin’inde Led bağlı olduğunu düşünelim. Bu ledi dahili fonksiyonları kullanmadan yakıp söndürmek için aşağıdaki kodu yazabiliriz.
#byte PORTA = 0x05
#byte TRISA = 0x85
#bit LED = 0x05.0 // A Portunun (0x05 adresinde) A0 Pini
void main(void)
{
PORTA = 0;
TRISA = 0; // A portu komple çıkış
while(TRUE)
{
LED = 1;
delay_ms(500);
LED = 0;
delay_ms(500);
}
}
Örnek 2
STATUS registerini Structure olarak tanımlayalım ve değişkene atayalım
struct {
int1 RBIF;
int1 INTF;
int1 T0IF;
int1 RBIE;
int1 INTE;
int1 T0IE;
int1 PEIE;
int1 GIE;
} status;
#byte status = 0x03 // status registeri PIC'te 0x03 adresindedir
staus.GIE = 0; // tüm interruptlar kapalı GIE biti = 0
status &= 0x7f; // tüm interruplar kapalı GIE biti = 0
if(status.T0IF) // Timer0 overflow olmuş mu?
Görüldüğü gibi CCS-C derleyicisinin hiç bir hazır fonksiyonunu kullanmadan kod yazabilirsiniz ve bu kodu başka platformlara rahatlıkla aktarabilirsiniz.
#locate
Bu direktif tıpkı #byte direktifi gibi bir değişkeni bir adres bölgesine atar. Aradaki fark #locate ile atanan adres alanının C tarafından kesinlikle kullanılmayışıdır.
float f; #locate f=0x50 // f değişkeni bellekte 50-53 adres bölgesini kullanacak (4 byte) long x; #locate x = 0x60 // x değişkeni bellekte 60-61 adreslerini kullanacak (2 byte)
#word
Bu direktif te hemen hemen aynı işi yapar. Tanımlanan adres bölgesinin diğer değişkenler tarafından kullanılabilme ihtimali unutulmamalıdır
#word id=x şeklinde kullanılır.
int16 h; #word h=0x85 // h değişkeni 0x85-86 adresine yerleşir #word k = 0x90 // k değişkeni tanımlanır ve 0x90-91 alanına yerleştirilir
#build
Bu direktifi pek kullanma ihtiyacı duymadım, muhtemelen sizde duymayacaksınız ama yinede bu direktifle neler yapılabilir örneklerle gösterelim.
#build(memory=0x20000:0x2FFFF) Kod bu adres bölgesine yerleştirilecek #build(reset=0x200,interrupt=0x208) Reset ve Interrupt vektörlerinin adresi değiştiriliyor #build(reset=0x200:0x207, interrupt=0x208:0x2ff) Reset ve Interrupt Vektorlerine Limit konuluyor #build(nosleep) main() fonksiyonun sonuna sleep koyma.
#case
CCS-C derleyicisi ön tanımlı olarak Büyük Küçük harf ayrımı yapmaz. Derleyicinin büyük küçük harf ayrımı yapmasını isitiyorsanız kodunuze #case ifadesini eklemeniz yeterli.
#case int X,x; // X ve x ayrı değişken olur x = 5; X = 6;
#define
Bu direktifi daha önce de anlatmıştık, #define ile sabit degerler veya Makrolar tanımlayabilirsiniz. Aşağıdaki örneği inceleyiniz.
#define ARTIS 10 #define hi(x) (x>>4) int a; a = a + ARTIS; // a = a + 10 a = hi(a); // a = (a>>4); ile aynı
#device
Bu direktif kullanacağınız PIC Denetleyicisini belirtmek ve bazı ayarlamaları yapmak için kullanılır. Bütün PIC header dosyalarında (16f877.h, 16f628a.h gibi) o pic’e ait device tanımlaması bulunur.
#device PIC16F877 gibi
PIC denetleyicileri farklı farklı RAM büyüklüklerine sahiptir, RAM bölgelerine ise pointer’lar aracılığıyla erişilir. #device direktifi ile RAM’e ulaşmak için kullanılacak pointer boyutu tanımlanabilir. 5 bitlik pointer ile tüm Denetleyicilere ulaşılabilse de yüksek ram’li Denetleyicilerin RAM alanı tam olarka kullanılamaz. Pointer boyutu şu şekilde ayarlanır
#device *=5 // 5 Bit poinetr kullan (Tum PIC'ler) #device *=8 // 8 Bit poiner kullan (14,16 Bit Serileri) #device *=16 // 16 Bit pointer kullan (16 Bit Serileri)
#device direktifi ile kullanılabilecek diğer ayarlar
ADC:
#device ADC = 10 //read_adc() 10 bitlik okuma yapsın #device ADC = 12 //read_adc() 12 bitlik okuma yapsın
ICD:
#device ICD=TRUE //Microchip ICD Debugger için uyumlu kod üret
OVERLOAD
Overload özelliği, isimleri aynı olan ama parametre türleri farklı olan fonksiyonlar tanımlayabilmenize imkan verir.
void ekranayaz(int x)
{
printf("8 Bit deger:%d",x);
}
void ekranayaz(long x)
{
printf("16 Bit deger:%lu",x);
}
yukarıdaki iki fonksiyonun da hata vermeden çalışabilmesi için
#device OVERLOAD = ekranayaz direktifi verilmelidir.
Birden fazla #device direktifi alt alta yazılabilir
#device PIC16F877 #device ICD=TRUE *=16 #device ADC=10
Tüm ayarlar tek satırda da yazılabilir
#device PIC16F877 ICD=TRUE *=16 ADC=10
Her nekadar #device direktifine ait başka kullanım özellikleri varsada başlangıç seviyesi kullanıcılar için bukadar yeterli olacağı kanaatindeyim.
#list #nolist
Derleyici kodu derlerken bir .lst dosyası üretir bu kod içerisinde C kodları ve asm kodları karışıktır. Derleyici #nolist direktifi gördüğünde kodları bu dosyaya aktarmayı keser, #list direktifini gördüğünde ise aktarmaya devam eder.
Şimdilik bu kadar, bir sonraki yazımızda da önişlemci direktiflerini anlatmaya devam edeceğiz.





















“CCS-C Dersleri Önişlemci Direktifleri - 1” yazısı için 4 Yorum yapıldı
Eline sağlık hocam, dersler çok güzel, CCS C gibisi yok
hocam verdiğiniz dersler gerçekten güzel anlaşılır bir şekilde. emeklerinize sağlık. Güzel örnek tafsiye projelerininizi bizlerle paylaşmanız dileğiyle..:)
@ferdem,@adventurer_gazi
Faydalı olabiliyorsak ne mutlu, daha fazla vakit olsa da daha çok şey anlatsak yoğun bir iş ve evli olunca anca bu kadar
ondan sonra esas mevzulara gelirim. senin anlayacağın daha var oralara gelmeye 
adventurer_gazi, benim huyum bole once ivir zivir ne buldum anlatirim
Hocam uzun bir aradan sonra tekrar başladık =)
En son A/D çeviricilerde kalmıştım ben de =)
Devamını bekliyoruz…