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};
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;
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.
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.
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 ?
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
Hocam uC de denedim herhangi bir hata vermedi. Arduino da denemedim.
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);
}
Şö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);
}
paketleyip saklayın
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ı.
ş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.
belirlemis oldugun yapi 27 bitlik 4 byte ediyor zaten. derleyici bu yapinin boyutuna 6 byte diyorsa paketlemeyi dene
__attribute__ ((__packed__))
@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...
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.
Bilaharr yazacağım
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?
Hocam benim anlamadığım ben me[2] yaptığımda neden dizinin sonuna kadar alıyor normalde 2 tane alıp durması gerekmiyor mu?
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...
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.