C dilinde byte byte gelen veriyi long int e atma!

Başlatan elt42at, 14 Temmuz 2009, 16:54:04

elt42at

Slm arkadaşlar!

Pic C de bi örnekte görmüştüm. Long int bir değere seri porttan bir byte geldiğinde değişkenin yüksek değerlikli ve diğer gelen bytı da düşük değerlikli kısmına atılabildiğini görmüştüm.

Peki bunu anci C dili için düşünürsek, yani atmele yada pic e istisnayen değilde, nasıl bir işlem yapabiliriz.

Mesela pointer kullanarak ilgili değişkenin adresine ilk byte veriyi yazıp bir üst adrese de düşük değerlikli byte veriyi yazmak gibi denebilir.

Bunu pointer kullanmada da yapılabilecek bi arguman var mı?

arslan74

Alıntı yapılan: "elt42at"Slm arkadaşlar!

Pic C de bi örnekte görmüştüm. Long int bir değere seri porttan bir byte geldiğinde değişkenin yüksek değerlikli ve diğer gelen bytı da düşük değerlikli kısmına atılabildiğini görmüştüm.

Peki bunu anci C dili için düşünürsek, yani atmele yada pic e istisnayen değilde, nasıl bir işlem yapabiliriz.

Mesela pointer kullanarak ilgili değişkenin adresine ilk byte veriyi yazıp bir üst adrese de düşük değerlikli byte veriyi yazmak gibi denebilir.

Bunu pointer kullanmada da yapılabilecek bi arguman var mı?

Bunun çözümünün bircok yolu var. Ama en basidi union yapısını veya bahs ettiğiniz gibi Pointer kullanarak yapabilirsin.

parda

merhaba;

Sorunuzu doğru anladım ise;
Mantık aşağıdaki gibidir. Daha sade ve/veya kısa yazılabilirdi.

unsigned char cHighByte, cLowByte;
unsigned int nInteger;

nInteger = 0;
nInteger = cHighByte;
nInteger <<= 8;
nInteger |= cLowByte;
Bildiğim tek şey, hiç bir şey bilmediğimdir.

arslan74

Bitsel işlemler uzun işlemlerdir onun yerine doğrudan atama işlemleri daha az hızlı olur ve daha kısa kodlardır.

long değişkeni 32 bit yani 4 byte değerindedir. Bunu 4 bytelik char dizi ile ilişkilendirirsek. O zaman söyle örnek kod cıkar.

örneğin:

union L_U
{
    unsigned char  char_dizi[4];
    unsigned long u_long;
} long_union;

//atama işlemi
long_union.char_dizi[0]=1;
long_union.char_dizi[1]=2;
long_union.char_dizi[2]=3;
long_union.char_dizi[3]=4;

// longdan okuma

x = long_union.u_long;


Selamlar

elt42at

evet çok teşekkürler!

Ben de aynen bunun gibi bir mantık üzerinde durmaya çalıştım.

Döngüsel olarak gelecek olan seri port verilerinde özel bir handshake yaparak en hızlı ve en sade koordinat verisi göndereceğim.

Mesela  2 byte uzunluğunda bir X1 saklacına 6666h verisini direkt atamak istersem;
X1_H = 0x66;
X1_L = 0x66; gibi bir işleme tabi tutmak istiyorum. Şöyle bir şey var;
X1 saklacı eğer derleyici tarfından tanınırsa yani X1_h ve X1_L nin adresleri bilinirse bu olur.

Peki matematiksel işlem yapmadan 6666h değerini nasıl atama yapabiliriz direk bunun üzerinde durursam belki tersinden bir yere gelebiliriz.

Bu işlemleri sırf asm bilgim sıfıra yakın olduğundan karşılaşıyorum.

C de binbir türlü yolu var çünki ama asm ci arkadaşlar çok hızlı ve pratik yollar sunabiliyor.

Yapacağım iş
rastgele 2 byte lık bir değişkene seri porttan 2 çevrimde gelecek veriyi atmak olacak. Ama metot herkesin işine yarayacağı için ben konu hakkında tüm bilgiye açığım ve arkadaşlarımıza da faydalı olur inancındayım.

Prescaler

Diğer bir yol da union kullanmak yerine hedefte yer alan objenin bellek adresinden faydalanmak. Aşağıdaki kaynak kodun karmaşası sizi yanıltmasın, iyi bir derleyici bu kod için etkin bir makine dili dönüşümü yapacaktır.

unsigned char lowByte, highByte;
unsigned long ul;
//...
*(unsigned char *)&ul = lowByte;
*((unsigned char *)&ul + 1) = highByte;

elt42at

Çok teşekkürler ilginize ve cevabınıza!

Evet, burada iki ayrı byte değerine atama yapıyoruz.

adres değerlerinden faydalanarak

tersini de düşünürsek ul nin bellek adresine büyük ve 1 üst adresine de küçük değerlikli byte atama yaparsak iş tamamdır.

Özetle, adres değeri tanımlanmamış bir değişken için en uygun metod bellek adresini alıp onunla işlem yapmak.

Pic için özel C derleyicilerde gördüğümüz atama işlemler sanırım tamamiyle o derleyicinin ek özelliği.