Haberler:

Foruma Resim Yükleme ve Boyut Sınırlaması ( ! )  https://bit.ly/2GMFb8H

Ana Menü

Adres neden 4'er artıyor?

Başlatan strom, 18 Temmuz 2014, 17:32:37

strom

Herkese iyi günler. Elimde;
struct __attribute__((__packed__))  BMP180
{
   
   struct __attribute__((__packed__))
   {
      int16_t   AC1;
      int16_t AC2;
      int16_t AC3;
      uint16_t AC4;
      uint16_t AC5;
      uint16_t AC6;
      int16_t B1;
      int16_t B2;
      int16_t MB;
      int16_t MC;
      int16_t MD;
   }Calibration;
   
}BMPData;

şeklinde bir struct var. Struct'ın içeriğini I2C'den gelen verilerle doldurmak istiyorum. Şu şekil yaptığımda doğru çalışıyor:
   I2C_Read(I2C1, BMP180_ADDRESS, 0xAA, (uint8_t*) &BMPData.Calibration.AC1, 2, BIG_ENDIAN);
   I2C_Read(I2C1, BMP180_ADDRESS, 0xAC, (uint8_t*) &BMPData.Calibration.AC2, 2, BIG_ENDIAN);
   I2C_Read(I2C1, BMP180_ADDRESS, 0xAE, (uint8_t*) &BMPData.Calibration.AC3, 2, BIG_ENDIAN);
   I2C_Read(I2C1, BMP180_ADDRESS, 0xB0, (uint8_t*) &BMPData.Calibration.AC4, 2, BIG_ENDIAN);
   I2C_Read(I2C1, BMP180_ADDRESS, 0xB2, (uint8_t*) &BMPData.Calibration.AC5, 2, BIG_ENDIAN);
   I2C_Read(I2C1, BMP180_ADDRESS, 0xB4, (uint8_t*) &BMPData.Calibration.AC6, 2, BIG_ENDIAN);
   I2C_Read(I2C1, BMP180_ADDRESS, 0xB6, (uint8_t*) &BMPData.Calibration.B1, 2, BIG_ENDIAN);
   I2C_Read(I2C1, BMP180_ADDRESS, 0xB8, (uint8_t*) &BMPData.Calibration.B2, 2, BIG_ENDIAN);
   I2C_Read(I2C1, BMP180_ADDRESS, 0xBA, (uint8_t*) &BMPData.Calibration.MB, 2, BIG_ENDIAN);
   I2C_Read(I2C1, BMP180_ADDRESS, 0xBC, (uint8_t*) &BMPData.Calibration.MC, 2, BIG_ENDIAN);
   I2C_Read(I2C1, BMP180_ADDRESS, 0xBE, (uint8_t*) &BMPData.Calibration.MD, 2, BIG_ENDIAN);
Burda;
&BMPData.Calibration.AC1'in adresi 0x2000002C
&BMPData.Calibration.AC2'in adresi 0x2000002E
&BMPData.Calibration.AC2'ün adresi 0x20000030
........
bu sıralama ile gidiyor. Ancak bu struct'ı şu şekilde yerleştirmeye çalıştığımda sorun çıkıyor;
   for(int i = 0; i < 11; i++)
      I2C_Read(I2C1, BMP180_ADDRESS, (0xAA + i*2), (uint8_t*) (&BMPData.Calibration.AC1 + i*2), 2, BIG_ENDIAN);

Burdaki sorun şu; i'nin değeri 0'ken (0xAA + i*2)'ın değeri 0xAA, (&BMPData.Calibration.AC1 + i*2)'nın değeri 0x2000002C. Ancak i'nin değeri 1 olduğunda (0xAA + i*2)'nın değeri 0xAC (bu doğru),  (&BMPData.Calibration.AC1 + i*2)'nın değeri 0x2000002E olması gerekirken 0x20000030 oluyor. i'nin her 1 artımına adres değeri 2 artması gerekirken 4'er artıyor. Bunun sebebi nedir?

kimlenbu

BMPData.Calibration.AC1 adresini uint32_t tipindeki bir değişkene atıp denediğinizde de aynı sonuç çıkıyor mu ?

ercan_t

merhaba

(uint8_t*) (&BMPData.Calibration.AC1 + i*2)
bunun yerine

( ((uint8_t*) &BMPData.Calibration.AC1) + i*2)
bunu deneyin?

strom

@ercan_t hocam çalıştı. Neden böyle bir şey oluyor acaba?

z

#4
Bir pointera X gibi bir deger eklersen aslinda yapilan pointer ile erisilecek verinin veri boyutunun A katini eklemek demektir. (Byte ise A, short ise 2A, int ise 4A gibi)

Eger amacin pointerin tuttugu adresin matematik anlamda A kadar fazlasini bulmak ise, once pointer icerigini int'e zorlaman sonra buna A eklemen daha sonra da bu sonucu pointer degeri olmaya zorlamaktir.

Asaagida J short bir pointer olsun.

     j=(short*)&BMPData.Calibration.AC1+1;   // AC1 den sonraki degiskenin yani AC2 nin adresi olur.

     j=(short*)((int)(int*)(&BMPData.Calibration.AC1)+1); // AC1 adresinin sadece 1 fazlasi olur.

     j=(short*)((int)(int*)(&BMPData.Calibration.AC1)+2); // AC1 adresinin 2 fazlasi yani AC2 adresi olur.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

strom

@z hocam şimdi anladım olayı. Çok teşekkür ederim.