Picproje Elektronik Sitesi

DERLEYİCİLER => MikroC - PIC => Konuyu başlatan: ehliseyf - 27 Temmuz 2016, 09:34:48

Başlık: Float değişkeni Byte'lara bölme
Gönderen: ehliseyf - 27 Temmuz 2016, 09:34:48
4 Byte olan bir değişkeni byte byte almanın yöntemini öğretebilir misiniz. Kaydırma ile biraz düşündüm ama işin içinden çıkamadım. Aynı şekilde geri birleştirmenin de varsa güzel olur :)
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: ercan_t - 27 Temmuz 2016, 10:43:03
merhaba

union ile yapabilirsin.

union
{
  float f;
  int i;
  unsigned char [4];
} u;

vs vs
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: kantirici - 27 Temmuz 2016, 12:27:22
Forumda detaylıca anlatımlar ve farklı yaklaşımlar var.

Union yapısı ile ulaşım en sade ve kolay ve anlaşılır olanı bana göre. Şurada da mantığından bahsedilmiş;

https://ozcanfatih.wordpress.com/2016/02/01/c-dilinde-union-yapisi-ve/
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: kimlenbu - 27 Temmuz 2016, 12:38:24
ben makro kullanıyorum :




//degisken = 0x1234 olsun BYTE(degisken,0) yazinca 4 döndürüyor. BYTE(Degisken,0)= 9 yazýnca degisken 0x1239 oluyor.
#define BYTE(var,index) *(((unsigned char*)&var)+index)

Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: mufitsozen - 27 Temmuz 2016, 14:42:48
Alıntı yapılan: kimlenbu - 27 Temmuz 2016, 12:38:24
ben makro kullanıyorum :




//degisken = 0x1234 olsun BYTE(degisken,0) yazinca 4 döndürüyor. BYTE(Degisken,0)= 9 yazýnca degisken 0x1239 oluyor.
#define BYTE(var,index) *(((unsigned char*)&var)+index)



Cok kurnazca.


BYTE(Degisken,7)= 9 yazinca neler oluyor esas onu merak ettim  ;)

Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: ehliseyf - 27 Temmuz 2016, 21:19:14
Alıntı yapılan: kimlenbu - 27 Temmuz 2016, 12:38:24
ben makro kullanıyorum :




//degisken = 0x1234 olsun BYTE(degisken,0) yazinca 4 döndürüyor. BYTE(Degisken,0)= 9 yazýnca degisken 0x1239 oluyor.
#define BYTE(var,index) *(((unsigned char*)&var)+index)


Hocam kullandım işime yaradı teşekkür ederim. Union yapısını anlayamadım
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: mir_as82 - 28 Temmuz 2016, 08:14:09
Bu soruda, union yapıp For ile dolaşıp göndermek mi daha az makina kodu üretir yoksa, yukarıdaki makro kullanmak mı?örneğin biri diğerine göre % kaç daha az makina kodu üretir?
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: JKramer - 28 Temmuz 2016, 08:26:36
#define satırı, derlemede değiştiriliyor; yani *(((unsigned char*)&var)+index) ne üretiyorsa o. Ama böyle şeyler kullanmamak lazım, mufitsozen'in gösterdiği gibi, "tehlikenin" farkına varın :).
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: kimlenbu - 28 Temmuz 2016, 10:21:50
Alıntı yapılan: mufitsozen - 27 Temmuz 2016, 14:42:48
Cok kurnazca.


BYTE(Degisken,7)= 9 yazinca neler oluyor esas onu merak ettim  ;)



Selamlar @mufitsozen hocam, "tehlikenin farkında mısınız" durumuna değinmeniz iyi oldu, kim bilir hafızada hangi bölgeyi değiştirecek, debug edene kadar insanın gözleri kör olur böyle bir durumda. Ben "index" 0,1,2,3 diye kendim belirttiğim için bir sorunla karşılaşmadım ama atıyorum döngü içinde kazara şu şekilde bir kullanım olursa dediğiniz tehlike ortaya çıkıyor

for (x=0;x<5;x++)
{
BYTE(degisken,x)=0;
}
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: JKramer - 28 Temmuz 2016, 10:38:06
Bir de endian durumu var. Yarın biri gelip kodu big endian'da derlerse:
http://gph.is/1JSPK3Y (http://gph.is/1JSPK3Y)
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: kimlenbu - 28 Temmuz 2016, 10:53:48
Alıntı yapılan: JKramer - 28 Temmuz 2016, 10:38:06
Bir de endian durumu var. Yarın biri gelip kodu big endian'da derlerse:
http://gph.is/1JSPK3Y (http://gph.is/1JSPK3Y)

korkudan kullandığım derleyicide böyle bir ayar var mı diye baktım, yokmuş neyse ki :D little endian kullanıyor.
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: F493 - 28 Temmuz 2016, 13:44:29
Selam,

  Bir nokta dikkatimi çekti o nedenle yazmak istedim. Başlıkta float degişkeni byte lara bölme denmiş.

  Float değişken bir noktalı sayı tuttuğuna göre sağa sola shift işlemi yaptırmaz derleyici (<<, >>).

  Neden float tür kullanırız? Nedeni noktadan sonra değerleri de tutsun diye. Örneğin Adc den aldığımız değeri ekranda Voltaj olarak gösterecek ise 5.2v, 3.5v gibi float değişkene ihtiyaç duyarız. Buraya kadar aynı fikirde olduğumuzu düşünüyorum.

Asıl mesele yukarıdaki yöntemler veri kaybına neden olur yani 153.2 gibi bir değer için kullanırsanız 153 sonucunu elde edersiniz gibi. Yanlış mı düşünüyorum.
Ben de bazen yazılımda float değişkeni Eeprom'a kaydetmek için önce int'e sonra byte lara ayırmayı kullanıyorum ama bunu şu şekilde yapıyorum.

Sayımız 452.3 olsun ve bir kalibrasyon katsayısı olsun. Ekrandan ayarı yaptım ve bu değeri cihaz her açıldığında kullanmak için hafızaya kaydetmek için kaydet butonuna bastım.

float Kalibrasyon_Katsayisi = 452.3;
unsigned int KalibrasyonInt;


Bana noktadan sonra 1 hane yettiğinden    KalibrasyonInt = (unsigned int) (Kalibrasyon_Katsayisi * 10);

şekline dönüştürüyorum yani degeri 4523 haline dönüştürdüm. Şimdi byte lara ayırabilirim yani yukarıdaki yöntemleri kullabilirim diye düşünüyorum.


----------------------------------- En güvenli yöntem ise ------------------------------------------------

char buf[16];
float dataFloatTyte = 452.35655;


sprintf(buf, "%.1f", dataFloatTyte * 10);
// * 10 demek sayısı 10 ile çarp demek. Noktadan sonra 1 hane istiyoruz. İki hane isteseydik * 100 diyecektik.
// buf içinine 4523.56 değerini string olarak yazdık
result = atoi(buf);   // Bu fonksiyon 4523 degerini int olarak result değişkenine atar.
----------------------------------------------------------------------------------------------------------

Artık elimizde 4523 sayısı var. Bunu byte lara ayırabiliriz. Eeproma kaydedebiliriz.

Cihaz açılışında ise okuduğumuz bu degeri önce float'a dönüştürüp sonra 10' a bölersek 452.3 degerini elde ederiz.

Bu da denemek isteyenlere C kodu.

#include <stdio.h>
#include <stdlib.h>  // atoi icin gerekli.

float dataFloatTyte = (float)156.2654554;
int result;
char buf[16];

int main (void)
{

printf("Ham float degeri = %f", dataFloatTyte);
printf("\n------------------------------------\n");
sprintf(buf, "%.1f", dataFloatTyte * 10);
printf("sprintf sonucu = %s", buf);
printf("\n------------------------------------\n");
result = atoi(buf);
printf("atoi sonucu = %d", result);

// dataFloatTyte = dataFloatTyte >> 1; // error. Float türde bu işleme izin yok.

getchar();

}


EDIT : Yazım hatası için yapılmıştır.  * 20 hatalı olmuş, *100 olarak düzeltildi.

Esen kalın.

Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: mehmet - 28 Temmuz 2016, 13:59:41
100 ile demek istediniz sanırım?
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: JKramer - 28 Temmuz 2016, 14:01:02
Float da olsa hafızada byte byte tutulmuyor mu? Float sayı kaç byte ise doğrudan alınabilir, parçalayıp toplamaya gerek yok.
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: yamak - 28 Temmuz 2016, 14:39:05
Alıntı yapılan: kimlenbu - 28 Temmuz 2016, 10:21:50
Selamlar @mufitsozen hocam, "tehlikenin farkında mısınız" durumuna değinmeniz iyi oldu, kim bilir hafızada hangi bölgeyi değiştirecek, debug edene kadar insanın gözleri kör olur böyle bir durumda. Ben "index" 0,1,2,3 diye kendim belirttiğim için bir sorunla karşılaşmadım ama atıyorum döngü içinde kazara şu şekilde bir kullanım olursa dediğiniz tehlike ortaya çıkıyor

for (x=0;x<5;x++)
{
BYTE(degisken,x)=0;
}
Macro'yu sonunda ';' ile yazarsak en azından derleyicinin hata vermesini sağlayıp @mufitsozen hocanın bahsettiği tehlikeyi önleyebiliriz.
#define BYTE(var,index) *(((unsigned char*)&var)+index);
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: F493 - 28 Temmuz 2016, 14:41:21
Alıntı yapılan: JKramer - 28 Temmuz 2016, 14:01:02
Float da olsa hafızada byte byte tutulmuyor mu? Float sayı kaç byte ise doğrudan alınabilir, parçalayıp toplamaya gerek yok.

Ben float'ın özel bir yöntem ile memoride tutulduğunu biliyorum byte byte değil de.  https://en.wikipedia.org/wiki/Floating_point
Merakımdan soruyorum.

  Örneğin val diye bir değişken olsun ve 142.4568; şeklinde bir değeri tutsun.   

Ben bu değişkenden 142.45 degerini 142.45 olarak byte lara ayırmak istiyorum ve bu byte ları elde ettikten sonra yine 142.45 degerine tekrar geri dönmek istiyorum.

Bunu gösterirseniz bende boşuna uğraşmamış olacagım. :-).  Uygulamlı örnek ile gösterirseniz bende denemek isterim.
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: yamak - 28 Temmuz 2016, 14:55:11
Alıntı yapılan: F493 - 28 Temmuz 2016, 14:41:21
Ben float'ın özel bir yöntem ile memoride tutulduğunu biliyorum byte byte değil de.  https://en.wikipedia.org/wiki/Floating_point
Merakımdan soruyorum.

  Örneğin val diye bir değişken olsun ve 142.4568; şeklinde bir değeri tutsun.   

Ben bu değişkenden 142.45 degerini 142.45 olarak byte lara ayırmak istiyorum ve bu byte ları elde ettikten sonra yine 142.45 degerine tekrar geri dönmek istiyorum.

Bunu gösterirseniz bende boşuna uğraşmamış olacagım. :-).  Uygulamlı örnek ile gösterirseniz bende denemek isterim.
Hocam float aslında bi yorumlanış şekli.Bellekteki datalar IEEE 754 göre hesaplanıp floating sayıya dönüştürülüyo.Yani data'yı herhangi bir şeye dönüştürdüğünüzde değişen bişey olmuyo.Ekrana bastırılacağı zaman float belleğin o bölgesindeki data IEEE754 e göre hesaplanıyo.Tabi sizin bahsettiğiniz şey sprintf ile ascii'ye çevirme.Bu durumun benim anlattığımla alakası yok.Örneğin:
142.45 sayısı bellekte 0x430E7333 olarak tutuluyo.
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: F493 - 28 Temmuz 2016, 15:13:21

Atasına inersek bit olarak tutulduğunu da buluruz sanırım. Sonuçta byte olarak tutulduğu kesin ama o byte ları bir araya getirdiğinizde anlamlı reel sayısı bulamayız başka verilerede ihtiyaç var. O nedenle bu byte lar onu ifade eden byte lar değil. O nedenle byte olarak tutulmuyor yani gerçek değer diyorum. O zaman bende sorarım NOKTA derede.   



Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: mehmet - 28 Temmuz 2016, 15:14:45
http://www.h-schmidt.net/FloatConverter/IEEE754.html (http://www.h-schmidt.net/FloatConverter/IEEE754.html)
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: JKramer - 28 Temmuz 2016, 15:39:53
Alıntı yapılan: F493 - 28 Temmuz 2016, 15:13:21
Atasına inersek bit olarak tutulduğunu da buluruz sanırım. Sonuçta byte olarak tutulduğu kesin ama o byte ları bir araya getirdiğinizde anlamlı reel sayısı bulamayız başka verilerede ihtiyaç var. O nedenle bu byte lar onu ifade eden byte lar değil. O nedenle byte olarak tutulmuyor yani gerçek değer diyorum. O zaman bende sorarım NOKTA derede.
Anlamlı reel sayı dediğiniz şeyi sizin hesaplamanıza gerek yok. yamak'ın dediği gibi, 142.45 sayısı bellekte 0x430E7333 olarak tutuluyormuş.  Siz float değişkenin adresinden bu 4 byte'ı sırayla alıp eeprom'a yazacaksınız. Daha sonra eeprom'dan sırayla alıp istediğiniz float değişkenin adresine yazacaksınız.
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: yamak - 28 Temmuz 2016, 15:43:18
Alıntı yapılan: F493 - 28 Temmuz 2016, 15:13:21
Atasına inersek bit olarak tutulduğunu da buluruz sanırım. Sonuçta byte olarak tutulduğu kesin ama o byte ları bir araya getirdiğinizde anlamlı reel sayısı bulamayız başka verilerede ihtiyaç var. O nedenle bu byte lar onu ifade eden byte lar değil. O nedenle byte olarak tutulmuyor yani gerçek değer diyorum. O zaman bende sorarım NOKTA derede.   
Hocam dedim ya;Başka veri dediğin IEEE 754 standartı.Yani 0x430E7333 datasını hangi makinada kullanırsanız kullanın IEEE 754'e göre sonuç 142.45 çıkar.
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: F493 - 28 Temmuz 2016, 16:00:04
Selam,

    Dediğiniz doğru ve kayıt işlemlerinde EEproma kaydedecegim değer  25.5'i geçmeyen değer olunca 1 byte olarak hafızada saklıyorum o nedenle bu yöntem işe yaramıyor. Yada 2 byte'lık bir değişken ise yine noktadan sonrası önemli oluyor ve bahsettiğim işlemleri yapmak kaçınılmaz oluyor.  Ama eeprom alanını 4 byte olarak ayırırsanız bu kullanılır. Yani 4 byte'ı her halükarda işleme sokmak gerekiyor eğer noktadan sonra basamak sayısı önemli ise. O zaman en başta önerilen yöntemlerde sorun kalmıyor. Ancak, hep 4 byte kayıt - okuma  işlemi yapılırsa. En başta sorduğum sorunun cevabını buldum.
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: mufitsozen - 28 Temmuz 2016, 19:35:21
Alıntı yapılan: kimlenbu - 28 Temmuz 2016, 10:21:50
Selamlar @mufitsozen hocam, "tehlikenin farkında mısınız" durumuna değinmeniz iyi oldu, kim bilir hafızada hangi bölgeyi değiştirecek, debug edene kadar insanın gözleri kör olur böyle bir durumda. Ben "index" 0,1,2,3 diye kendim belirttiğim için bir sorunla karşılaşmadım ama atıyorum döngü içinde kazara şu şekilde bir kullanım olursa dediğiniz tehlike ortaya çıkıyor

for (x=0;x<5;x++)
{
BYTE(degisken,x)=0;
}

---@mir_as82 yorumununu okuduktan sonra bu yazdigimi silmeye karar verdim
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: mir_as82 - 29 Temmuz 2016, 08:16:20
Ama bu soruda sanki union u kontrollü kullanmak daha güzel bir çözüm gibi.(yani index in 3 ü aşması durumu için).
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: ehliseyf - 29 Temmuz 2016, 13:32:27
Alıntı yapılan: mir_as82 - 29 Temmuz 2016, 08:16:20
Ama bu soruda sanki union u kontrollü kullanmak daha güzel bir çözüm gibi.(yani index in 3 ü aşması durumu için).
Hocam Micro C için union nasıl kullanılır. Daha iyi olacaksa ben onu kullanmayı öğrenmek isterim.
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: mir_as82 - 29 Temmuz 2016, 15:50:01
https://ozcanfatih.wordpress.com/2016/02/01/c-dilinde-union-yapisi-ve/

Arkadaşın birinin verdiği linkte mevcut anlatımı
Başlık: Ynt: Float değişkeni Byte'lara bölme
Gönderen: MCansız - 20 Mart 2017, 23:50:31
örnek olarak;




struct    bytex
             {
              unsigned int bit_0 : 1;        // Byte 1, Bit 0
              unsigned int bit_1 : 1;        // Byte 1, Bit 1
              unsigned int bit_2 : 1;        // Byte 1, Bit 2
              unsigned int bit_3 : 1;        // Byte 1, Bit 3
              unsigned int bit_4 : 1;        // Byte 1, Bit 4
              unsigned int bit_5 : 1;        // Byte 1, Bit 5
              unsigned int bit_6 : 1;        // Byte 1, Bit 6
              unsigned int bit_7 : 1;        // Byte 1, Bit 7
              unsigned int bit_8 : 1;        // Byte 0, Bit 0
              unsigned int bit_9 : 1;        // Byte 0, Bit 1
              unsigned int bit_10: 1;        // Byte 0, Bit 2
              unsigned int bit_11: 1;        // Byte 0, Bit 3
              unsigned int bit_12: 1;        // Byte 0, Bit 4
              unsigned int bit_13: 1;        // Byte 0, Bit 5
              unsigned int bit_14: 1;        // Byte 0, Bit 6
              unsigned int bit_15: 1;        // Byte 0, Bit 7
           };

union
{
struct  bytex byte;
char low_higt[2];
int all;
}gpiox;




kullanımı


gpiox altında all isminde int tipi değişkenimiz var bu değişkenin
gpiox.low_higt[0]=> low nibble (ilk 8 bit)
gpiox.low_higt[1]=> high nibble (son 8 bit)   olur.
gpiox.byte.bit_15  all değişkenini 15. bitini gösterir ve değiştirebilirsiniz.


örnek:

gpiox.low_higt[0]=0x1F;
gpiox.low_higt[1]=0x2A;

değerleri verilirse
gpiox.all=0x2A1F   olur