BASIC kullanıcılarını C'ye alıştırma turları

Başlatan bunalmis, 28 Ekim 2011, 18:48:32

z

#90
Unutmadığımzı bir şey varmı bilmiyorum en sona bıraktığımız structure  ve union konusuna https://www.picproje.org/index.php/topic,35908.50.html  linkinden erişebilirsiniz.

Fakat burada sorularınızı tartışalım.

Burada eistain_54 e bir sorum olacak.

Tamam

int A,B;
char x;
gibi tanımlar yaparak C bana Ramda yer ayarlıyor. Sen de örneğin A=10; diyerek bunları kullanıyorsun.
Burada A değişkeninin adresi her şey olabilir.

Eğer   

int A,B;
char x;

Tanımı yerine

int Z,A,B;
char x;

Tanımı yaparsan biraz önceki A değişkeninin adresi ile şimdi yaptığımız tanımdaki A değişkeninin adresi farklı olur.

Fakat çiplerde bazı değişkenlerimizin adreslerinin sabit olması gerekir. Buna örnek olarak portları verebiliriz.

Peki nasıl olacak da olacak Örneğin adına PA dediğimiz portun C'deki adresini gerçek donanımdaki adresi olarak tanımlayacağız?

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

eistain_54

Ben bu soruyu anlamadım.Yani bir donanımsal port var.Porta gibi.Bunun C deki adresini nasıl buluruz?Soru bu mu?Buysa bişey anlamadım...
Her gün 24 altın verilirken bunun için kime şükredersin ey ademoğlu!?!

muhittin_kaplan

Biraz ben açayım.
int A,B
şeklinde tanımlama yaptık ce derleyici A değişkeni olarak 0x05 Ram Bölgesine, B değişkeni olarak ta 0x06 Ram bölgesine bunları atadı.
Peki int Z,C,A,B yaparsak ne olur örnek olarak
Z   0x05
C   0x06
A   0x07
B   0x08
Adreslerine atar.

Burada A nın hep Aynı RAM adresine ayrılması istiyoruz. (Örneğin PORTlar öyle)

eistain_54

Anladım.O halde sıralamaya dikkat edeceğiz.Başka br yöntem olarak adreslerini yazabiliriz belki.#org komutu belki bir işe yarayabilir?Heralde bu konu pointer ile ilgili.Yanılıyormuyum?En son çare de pointer kullanmak olacaktır.?
Her gün 24 altın verilirken bunun için kime şükredersin ey ademoğlu!?!

muhittin_kaplan

Bunalmış hocanın sorusu istediğimiz herhangi bir değişkenin hep aynı RAM adresine denk gelmesini nasıl ayarlarız ? Sanırım.

eistain_54

Her gün 24 altın verilirken bunun için kime şükredersin ey ademoğlu!?!

z

Mesela PA portu çipin 0x1000 adresinde yer alıyor olsun.

C'de PA diye bir değişken tanımlayın. Bu değişkenin adresi 0x1000 de olsun.




Bana e^st de diyebilirsiniz.   www.cncdesigner.com

eistain_54

Gerçekten bilmiyorum.Daha evvel böyle bir ugulamaya ihtiyacım olmadı.Nasıl yapılır?
Her gün 24 altın verilirken bunun için kime şükredersin ey ademoğlu!?!

eistain_54

Buldum geçmişi karıştırırken fakettim.Ama bumu değilmi emin değlim.
https://www.picproje.org/index.php/topic,35908.60.html
[quote]
[]code
#define  // Tanım yapmak için kullanırız.
 
  //Ornekleri inceleyin.
 
#define  AlarmLediniYak 0x10
 
 
    GPIO.PORTA.ODR |=AlarmLediniYak;
 
    // Yukarıdaki ifade 
GPIO.PORTA.ODR |=0x10;  //komut satırına eştir.
 
     //Ancak 
     GPIO.PORTA.ODR |=AlarmLediniYak;  //okunaklığı ve anlaşılırlığı yüksektir.
 
//Yada aşağıdaki örneğe bakın
 
#define Yan GPIOD->ODR= 0x0000F000
#define Son GPIOD->ODR= 0x00000000
 
    if (LedFlag) Yan;     // Ledler yansin
      else Son;                  // Ledler sonsun
 
//Yukarıdaki iki satır aşağıdaki satırlarla aynı anlama gelir.
 
     if (LedFlag) GPIOD->ODR= 0x0000F000;     // Ledler yansin
       else GPIOD->ODR= 0x00000000;                  // Ledler sonsun

[/quote]
Her gün 24 altın verilirken bunun için kime şükredersin ey ademoğlu!?!

eistain_54

Yani #define ile yapılır.

#define PA 0x1000

şeklide yapılır.
Her gün 24 altın verilirken bunun için kime şükredersin ey ademoğlu!?!

z

#100
Alıntı Yap#define PA 0x1000

Eğer böyle yaparsan C derleyici, PA gördüğü her yere 0x1000 değeri yazmaya kalkar. Dolayısı ile yapmak istediğimiz bu değil.

PA portu, 8 bitlik bir port olsun.

Bu durumda bu porta unsigned char tipinde veriler yazacağız yada okuyacağız demektir.

unsigned char* PA;

tanımı yaptıktan sonra

PA=(unsigned char*)0x1000; diyebiliriz. Böylece PA pointerine 0x1000 değerini yüklemiş oluruz.

Artık *PA=78; dersek 0x1000 portundan 78 sayısını çıkmış oluruz.

Fakat burada PA nın önünde * görmek hoş olmuyor. Bunu görünmez yapalım. Üstelik bu şekilde tanımladığımız PA, RAM'da da yer kaplamaktadır. Bu sorunları da yok edelim.

Fakat yukarıdaki örnekte şu zamana kadar hiç bahsetmediğimiz type casting işlemi yapıldı.

Önce type casting sonra da define tanımını açıklayalım daha sonra da Bu sorunları da yok edelim dediğimiz konuya geri dönelim.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

eistain_54

Alıntı yapılan: CKITABI date=1320169023


int i,j;
int *ig,*jg;
ig=&i;
jg=&j;
 //Bu yazım şekli ig isminde integer tipinde tanımlanmış pointerın içerisine i isminde integer tiindeki deişkenin adresini yazar ve bu adres erişilebilir adres durumundadır.Yani içerisine değer yazabilir yada okuyabiliriz.Birde şu yazım şekli vardır ki;
ig=i; // Böyle bir yazımda i adresini ig ye koyacaktır ve ancak i değişkeni içindeki tam sayı bir adres olarak kullanıldığında işe yarayacaktır.C standardına uygun derleyiciler böyle bir durumda uyaracaklardır , çünkü değişkenlerin tipleri uymamaktadır.

C Kitabından alıntıdır.
Her gün 24 altın verilirken bunun için kime şükredersin ey ademoğlu!?!

ErsinErce

herkes beklemede galiba ben cevap vereyim;
linker'a belirttiğimiz adrese istediğimiz ismin verilmesini sağlamamız gerekli
çoğu linker @ işaretini kabul ediyor ama keil  __attribute__((at(0x8000))) ve ya .ARM.__at_0x00008000
dizelerinden birini istiyor. ( bunların kullanımı arasında da fark varmış aslında ama ilk seçeneği default olarak kullanabiliriz =) )

int reg @0x8000 =0;
int reg __attribute__((at(0x8000))) =0;

şeklinde de kullanılıyor

z

#103
@ErsinErce

Guzel bir bilgi vermissin.

Ancak hedef adresin içeriğini, nasıl byte olacağını belirleyeceğimizi anlamadım. Verdiğin örnekler hedefi int tanımlıyor.

Fakat biz simdilik isimizi linker ile değil de C derleyicisi ile cozelim.

Eğer sabit adresdeki 8 bitlik bir hedefe örneğin 0x10 sayısını yüklemek istersek aşağıdaki şekilde pointer yapısı ile ulaşabiliriz.

      *(unsigned char*)0x1000=0x10;

Burada yapılan;

unsigned char yani 8 bitlik bir adresi, işaret eden hayali bir pointere 0x1000 değerini ata ve bu pointerin gösterdiği yere0x10 değerini yerleştir

Fakat bu yazım, çok üstü kapalı ve okunaklığı zayıf bir gösterim olduğundan #define ile bu adres ifadesine özel bir isim verilebilir.

#define Reg  *(unsigned char*)0x1000

Bu durumda Reg=0x10 dersek derleyici Reg gördüğü yere *(unsigned char*)0x1000 yerleştirip öyle derleyecektir.

olası optimize işlemleri sonucu ortaya çıkacak sorunları kaldırmak için volatile ön ekini de getirirsek;

#define Reg    *(volatileunsigned char*)0x1000

aradığımız cevaplardan birisi olacaktır.

#define tanımlayıcısını anlamak

#define Carp *

y=a*b; ile  y=a Carp b; aynı anlama gelir.

Bu satırlara kadar olan kısımlar, BASIC kullanıcısı olarak artık size bir şeylerler ifade ediyorsa, https://www.picproje.org/index.php/topic,35908.0.html linkine muhakkak gözatın.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Bir konuda hatırlatma yapmak istiyorum.

Ben kart elime ulaşınca bu konuları takip edeceğim düşüncesindeyseniz konulara yetişemez çok geride kalırsınız. Bu nedenle kursumuzu takip edecekseniz ve C sorununuz varsa bunu mümkün olan en kısa zamanda kartlar size ulaşmadan halletmeye bakın.

C yi mükemmel kullanmak gibi bir hedefimiz yok. Bu aşamada kafamızdan geçen bir işlemi C satırlarına dökebilelim yeter.

Konuları kart olsun olmasın takip edebilir ve Keil'de denemeler yapabilirsiniz.

Keil'de basit kod parçacıkları yazıp derleyip debug etme konusunda sıkıntısı olanlar varsa https://www.picproje.org/index.php/topic,35719.0.html linkindeki
Keil programının kurulumu ve kullanılması başlığına gözatmaları yeterli olacaktır.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com