Picproje Elektronik Sitesi

PROGRAMLAMA DİLLERİ => C/C++ => Konuyu başlatan: selimkoc - 01 Ağustos 2017, 10:22:29

Başlık: Struct değişkenini long değişkene aktarma
Gönderen: selimkoc - 01 Ağustos 2017, 10:22:29
Merhaba forum üyeleri,

aşağıdaki yapıda long tipindeki değişkene yapıyı aktarmak istiyorum. Ama başarısız oldum. Amacım tarih ve saat bilgisini daha az EEpromda saklamak. Normal saklamak istersem 6 byte alan gerekiyor. Bu şekilde 4 byte sığdırabiliyorum. Long temp değişkenini 4 byte bölüp eepromda saklamayı düşünüyorum.

  long temp=0;
 
  struct tarihSaat {
    byte yil:5;
    byte ay:4;
    byte gun:5;
    byte saat:5; 
    byte dakika:6;
    byte islem:2;   
  };

  tarihSaat zaman={17,7,24,12,50,1};


Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: baran123 - 01 Ağustos 2017, 10:42:05

typedef union
{
struct tarihSaat {
    byte yil:5;
    byte ay:4;
    byte gun:5;
    byte saat:5; 
    byte dakika:6;
    byte islem:2;   
  }

struct {
long temp;
}
}Datastruct_t;

Datastruct_t myStruct;

mystruct.gun = 3;
...
...

long tempData = myStruct.temp;
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: selimkoc - 01 Ağustos 2017, 11:27:08
typedef union
{
struct tarihSaat {
    byte yil:5;
    byte ay:4;
    byte gun:5;
    byte saat:5; 
    byte dakika:6;
    byte islem:2;   
  };

struct {
long temp;
};
}Datastruct_t;

Datastruct_t myStruct;
myStruct.yil=17;
myStruct.ay=7;
myStruct.gun=24;
myStruct.saat=12;
myStruct.dakika=50;
myStruct.islem=1;
long tempData = myStruct.temp;


"myStruct" does not name a type  hatası alıyorum.
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: Klein - 01 Ağustos 2017, 12:15:27
Değişkenler arası aktarımın çok yolu var. Fakat 6 byte  uzunluktaki bir yapıyıı 4 byte uzunluğunda bir değişkene aktarmanın bir yolu olduğunu zannetmiyorum. Ancak 4 baytlık kısmını aktarabilirsiniz.
Fakat sisteminiz 32 bit ise Long değişkeniniz 8 byte olacaktır. O zaman aktarabilirsiniz.
En basit yolu

temp = *(long *)&tarihsaat;

şeklinde olur. Fakat burada şöyle bir sorun olur. long uzunluğu 8 byte ise , tarihsaat yapısının sonrasındaki 2 baytlık kısmı da alır.

6 baytlık bir yapıyı 4 bayta nasıl sığdırdığınızı biraz daha açarsanız, belki daha uygun yollar bulabiliriz.
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: M_B - 01 Ağustos 2017, 12:16:38


typedef union{
long temp;
    struct
      {
          char yil:5;
          char ay:4;
          char gun:5;
          char saat:5;
          char dakika:6;
          char islem:2;
       };
}Datastruct_t;

Datastruct_t  myStruct;
long tempData;


   myStruct.yil=17;
   myStruct.ay=7;
   myStruct.gun=24;
   myStruct.saat=12;
   myStruct.dakika=50;
   myStruct.islem=1;

tempData = myStruct.temp;


Hocam işinizi gorur mu ?
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: selimkoc - 01 Ağustos 2017, 13:06:27
byte yil:5;
    byte ay:4;
    byte gun:5;
    byte saat:5; 
    byte dakika:6;
    byte islem:2;   


toplam 27 bit. 4byte bilgi 32 bit eder. Dolayısı ile bu verinin uzunluğu 4 byte sığar.

Aynı hatayı alıyorum. Kullandığım platform Arduino 1.8.0

Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: M_B - 01 Ağustos 2017, 13:16:17
Hocam uC de denedim herhangi bir hata vermedi. Arduino da denemedim.
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: Klein - 01 Ağustos 2017, 15:11:20
Alıntı yapılan: selimkoc - 01 Ağustos 2017, 13:06:27
byte yil:5;
    byte ay:4;
    byte gun:5;
    byte saat:5; 
    byte dakika:6;
    byte islem:2;   


toplam 27 bit. 4byte bilgi 32 bit eder. Dolayısı ile bu verinin uzunluğu 4 byte sığar.

Aynı hatayı alıyorum. Kullandığım platform Arduino 1.8.0

Bit alanlar olduğunu farketmemişim.

union içerisindeki struct'a isim vermezseniz bazı platformlarda hata verir. Kullandığınız derleyicinin dokümanlarında "anonymous struct"  ararsanız gerekli direktifleri bulabilirsiniz. Ya da struct'a isim verin.

ya da daha önce önerdğim gibi 

tip x = *(tip *)&struct_ismi;

şeklinde işaretçi ile aktarabilirsiniz.

ya da doğrudan struct'ı eeproma yazmak için aşağıdaki gibi bir kod kullanabilirsiniz.

unsigned char *c = (unsigned char *)&struct_ismi;
for(int i=0; i< 4; i++)
{
   eeprom_yaz(adres + i , *c++);
}


okurken de

unsigned char *c = (unsigned char *)&struct_ismi;

for(int i=0; i< 4; i++)
{
   *c++ = eeprom_oku(adres + i);
}


Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: baran123 - 01 Ağustos 2017, 17:53:26
Şöyle dene birde.


typedef union
{
    struct tarihSaat {
        unsigned yil:5;
        unsigned ay:4;
        unsigned gun:5;
        unsigned saat:5; 
        unsigned dakika:6;
        unsigned islem:2;
        unsigned RESERVED:5;
    };

    struct tempData {
        unsigned long temp;
    };
}Datastruct_t;

int main()
{
    Datastruct_t myStruct;
    long tempData;
   
    myStruct.yil = 17;
    myStruct.ay = 7;
    myStruct.gun = 24;
    myStruct.saat = 12;
    myStruct.dakika = 50;
    myStruct.islem = 1;
   
    tempData = myStruct.temp;
   
    return (0);
}
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: muhittin_kaplan - 01 Ağustos 2017, 18:30:13
paketleyip saklayın
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: qeek - 02 Ağustos 2017, 16:31:47
Hocam şöyle bir şey denedim olmadı.


char *bb = "merhaba";

typedef struct{

    char me[2];
    char rha[3];
    char ba[2];
}Atama_t;

Atama_t atanan;

int main()
{
    atanan =*(Atama_t*)bb;
    printf("%s\n",atanan.me);
    printf("%s\n",atanan.rha);
    printf("%s\n",atanan.ba);
    printf("%s\n",bb);
}


Çıkış

merhaba
rhaba
ba
merhaba


Yukarda 3 tane yer ayırmama rağmen neden acaba sadece oraları almadı.
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: foseydon - 02 Ağustos 2017, 18:41:38
şu şekilde aktarabilirsiniz;


temp = 0;
temp |= zaman.yil;
temp <<= 4;
temp |= zaman.ay;
temp <<= 5;
temp |= zaman.gun;
temp <<= 5;
temp |= zaman.saat;
temp <<= 6;
temp |= zaman.dakika;


şu şekilde de aktarabilirsiniz;

unsigned long *ptr;
ptr = &zaman;
unsigned long x = *ptr;


birinci yöntem daha güvenilirdir. ikinci yöntem daha hızlıdır.
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: OptimusPrime - 02 Ağustos 2017, 19:02:53
belirlemis oldugun yapi 27 bitlik 4 byte ediyor zaten. derleyici bu yapinin boyutuna 6 byte diyorsa paketlemeyi dene
__attribute__ ((__packed__))
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: bymrz - 02 Ağustos 2017, 22:11:48
@geek ;


char *bb = "merhaba";

Aslında yukarıdaki gibi bir string tanımladığınızda, derleyici dizinin sonuna 0x00 karakterini ekler.
printf komutu da stringi yazarken 0x00 karakterini görene kadar yazmaya devam eder. Sendeki sorun bu yüzden.


[/size]atanan =*(Atama_t*)bb;
[/size]

Ayrıca bu komut ile bb stringini atanan dizinine aktarmış olmuyorsunuz. bb dizinin ilk byte'ının bulunduğu adres bilgisini "atanan" işaretçisine aktarıyorsunuz. Veriyi kopyalamıyorsunuz yani...
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: Klein - 02 Ağustos 2017, 22:51:30
Alıntı yapılan: alone_lover - 02 Ağustos 2017, 22:11:48
@geek ;

atanan =*(Atama_t*)bb;

Ayrıca bu komut ile bb stringini atanan dizinine aktarmış olmuyorsunuz. bb dizinin ilk byte'ının bulunduğu adres bilgisini "atanan" işaretçisine aktarıyorsunuz. Veriyi kopyalamıyorsunuz yani...

Hayır  tam aksi.  atanan değişkeninin veri büyüklüğü kadar veri değişkene aktarılır.

eğer atatan dipi işaretçi lsaydı ve baştaki '*' olmasaydı

atanan = (atanan_t *)bb;

şeklinde olsaydı o zaman adres atamasından bahsedebilirdik.
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: foseydon - 03 Ağustos 2017, 10:53:55
Bilaharr yazacağım
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: bymrz - 03 Ağustos 2017, 11:49:41
Aynen ben de öyle görmüşüm orayı :)
atanan = (atanan_t *)bb;

Fakat mevcut şekliyle de sıkıntılı

atanan = *(atanan_t *)bb;

yapıldığında da bb'nin ilk değişkenini "atanan"ın ilk değişkenine atayacak. Structure'ın tamamını değil yani. Sadece ilk harfi... Değil mi?
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: qeek - 03 Ağustos 2017, 11:56:24
Hocam benim anlamadığım ben me[2] yaptığımda neden dizinin sonuna kadar alıyor normalde 2 tane alıp durması gerekmiyor mu?
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: bymrz - 03 Ağustos 2017, 12:08:22
Alıntı yapılan: qeek - 03 Ağustos 2017, 11:56:24
Hocam benim anlamadığım ben me[2] yaptığımda neden dizinin sonuna kadar alıyor normalde 2 tane alıp durması gerekmiyor mu?


Dediğim gibi bu printf komutu ile ilgili. texti sonlandırmak için 0x00 karakterini görmek ister. Ya bu dizilerin sonuna kendin 0x00 ekleyeceksin. Yada "putchar" gibi bir komut kullanacaksın. dizi boyutu kadar putchar göndereceksin.

yani şöyle yap mesela :
me[2] değil de me[3] olsun ve printf demeden önce bir yerlerde
me[3]=0x00;  yap.
Ardından printf komutunu gönder...
Başlık: Ynt: Struct değişkenini long değişkene aktarma
Gönderen: Klein - 03 Ağustos 2017, 13:33:45
Alıntı yapılan: alone_lover - 03 Ağustos 2017, 11:49:41

atanan = *(atanan_t *)bb;

yapıldığında da bb'nin ilk değişkenini "atanan"ın ilk değişkenine atayacak. Structure'ın tamamını değil yani. Sadece ilk harfi... Değil mi?
Hayır.
"atanan" isimli değişken 4 byte ise ,"bb" dizisinin başlangıç adresinden 4 byte aktarır.  burada "bb" dizisinin ya da değişkeninin kaç bayt olduğunun ya da tipinin bir önemi yok.
Eğer struct 4 byte ise tamamını alır.