byte değişkeni bit bazında manipüle edilebilir mi?

Başlatan papsukkal, 12 Şubat 2024, 01:45:32

papsukkal

Lcd ekrana basılması gereken yaklaşık 15 adet büyüklü küçüklü görüntüm var. Diyelim ki bir tuşa basım ve ekranda gerekli değişiklik yapılacak. Buraya kadar sorun yok. Tuş basılı kaldığı süre içerisinde bu değişiklik sürekli oluyor. İstediğim bunu bir defa yapması ve tuş bırakılana kadar tekrarlamaması. Bunu da bir değişkeni bayrak olarak belirleyip düzelttim. Burada da sıkıntı yok. Ama 15 adet görüntü için 15 adet değişken kullanmak yer israfı gibi geliyor. Bunun yerine 32 bit bir değişken tanımlayıp her bir bitini bir ekran için bayrak atamak istiyorum. Kod takibinin kolaylığı için her bite bir tanımlama yapıp işlemi pratikleştirmenin bir yolu var mı?

Şunun gibi:

Bayrak_ayar     bayrak değişkeninin 0. biti;
Bayrak_acilis   bayrak değişkeninin 1. biti;

Bayrak_ayar 1 ise ekranı güncelle, Bayrak_ayarı 0 yap;
Bayrak_acilis 1 ise ekranı güncelle, Bayrak_acilis 0 yap;



mehmet

Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr
https://creativecommons.org/licenses/by/4.0/deed.tr "CC BY"

kimlenbu

15byte için uğraşmaya değmez, ben olsam dizi tanımlar kullanırdım.

Dediğinizi yapmak isterseniz de uint16_t değişken tanımlayıp istediğiniz bite kaydırma işlemleri ile erişebilirsiniz.

uint16_t bayrak=0;

MSB'ye erişmek için

bayrak & 0x8000

LSB'ye erişmek için

bayrak & 0x0001

İstenilen bite erişmek için

bayrak & ( 0x0001<< bitnumarasi )

istenilen biti değiştirmek için

bayrak | (0x0001 << bitnumarasi)


mehmet

İki farklı metod ile yapmak mümkün:
Kod: C
#define _BV(n)                (1 << (n))
#define sbi(port, n)          (port) |= _BV(n)
#define cbi(port, n)          (port) &= ~_BV(n)
#define rbi(m, n)             ((m) &    _BV(n))
#define fbi(m, n)             ((m) ^=   _BV(n)))
#define bit_is_set(m,n)       (m & _BV(n))
#define bit_is_clear(m,n)     (!(m & _BV(n)))
#define pinToggle(PORT, n)    (PORT ^= _BV(n))

Kod: C
enum{
    bit00, bit01, ..., bit15
}goruntu;

Şart kontrolleri ile durumları takip edip
gerekli değişiklikleri yapabilirsiniz.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr
https://creativecommons.org/licenses/by/4.0/deed.tr "CC BY"

JOKERAS

struct bit alanları işinizi görebilir sanırım.

satilla

#5
Bir alternatifte ben vereyim.

union SensorUnion {
	struct {
		unsigned char sicaklik :1;
		unsigned char nem :1;
		unsigned char sicaklik2 :1;
		unsigned char isik :1;
		unsigned char darbe :1;
		unsigned char rotate :1;
		unsigned char bit6 :1;
		unsigned char bit7 :1;
	};
	unsigned char sensorTipi;
} sensorUnion;




MCansız

union ile yapabilirsiniz.

örnek:
#include <stdio.h>
#include <stdint.h>

typedef union 
{
  struct
  {
          uint8_t bit_0 : 1;
          uint8_t bit_1 : 1;
          uint8_t bit_2 : 1;
          uint8_t bit_3 : 1;
          uint8_t bit_4 : 1;
          uint8_t bit_5 : 1;
          uint8_t bit_6 : 1;
          uint8_t bit_7 : 1;
  }bits;
  
  uint8_t byte;

 
}my_uint8_t;

int main()
{
    my_uint8_t data;
    
    data.byte = 0xFF; 
    printf("data: %X \r\n",data.byte);
    
    data.bits.bit_0 = 0x00;
    data.bits.bit_1 = 0x00;
    data.bits.bit_2 = 0x00;
    data.bits.bit_3 = 0x00;
    data.bits.bit_4 = 0x00;
    data.bits.bit_5 = 0x00;
    data.bits.bit_6 = 0x00;
    data.bits.bit_7 = 0x00;
    
    printf("data: %X \r\n",data.byte);

    return 0;
}

papsukkal

Cevaplar için teşekkür ederim. Struct ve union benim istediğime daha yakın gibi. Ancak daha önce hiç struct ya da union oluşturmadim. Bu konuda bilgim yetersiz. Biraz bunun üzerine düşeyim. Takıldığım yer olunca buradan sorarım gene.

JOKERAS

Arkadaşlara ilaveten...
struct BitField {

    unsigned int M0 : 1;
    unsigned int M1 : 1;
    unsigned int M2 : 1;
    unsigned int M3 : 1;
    unsigned int M4 : 1;
    unsigned int M5 : 1;
    unsigned int M6 : 1;
    unsigned int M7 : 1;
    unsigned int M8 : 1;
    unsigned int M9 : 1;
    unsigned int M10 : 1;
    unsigned int M11 : 1;
    unsigned int M12 : 1;
    unsigned int M13 : 1;
    unsigned int M14 : 1;
    unsigned int M15 : 1;

};

struct BitField Bit;


while (1) {

        Size = sizeof (Bit); // Kapladığı alan.

        Bit.M1 ^= 1 ; // Nokta operatörü ile Erişim ve işlem.
        -
        -
        -
        -
        -

}

Bu şekilde de olabilir, işinize yarayabilir.


papsukkal

@JOKERAS bu yapının kullanımı nasıl olacak? Biraz detay verebilir misin?

JOKERAS

Yapı elemanlarına . ile erişip işlem yapacaksınız.

Örneğin Bit.M0 = 1 veya 0.





papsukkal

Biraz bakındım da aslinda 16 adet bit lazım bana diyelim. Yapı içerisinde 16 adet tanımlama yaptım diyelim. Bu aslında 16 adet int yada 16 adet uint8-t tipi değişken kullandığım anlamına mı geliyor? Tek tek değişken tanımlamak ile bu yapıyı kullanmam arasında işlemci yükü açısından bir far yok mu?

JOKERAS

#12
papsukkal , Tek tek değişken tanımlamanız ile bu yapı arasında 14Byte fark var.

Verdiğim Kodda

Size = sizeof(Bit) ; // 2 Byte döndürür.

Bu yapı türü ile tanımlanan değişkenin tüm bitlerine erişebiliyorsunuz.
Yapıda gördüğünüz 16 Adet "unsigned int" sizi yanıltmasın.
Bunun çalışma zamanında bir anlamı yok.Bu Yapı bildirimi için kullanılan bir yöntem.
Bu sayede parçalara ayrılmış oluyor.


: iki nokta üst üste operatörüne dikkat edin.Klasik tanımlamada bu olmaz.
Dikkat edin yap elemanlarının her birine "1" vererek kaç değer alacağını söyledik.
1 dediğimizde alacağı değer 1 ve 0 olur.İsterseniz bunu unsigned int sınırları içinde
Farklı değerlerlede hazırlayabilirsiniz.

Örneğin..

struct ByteBit {

    unsigned int M0 : 8; //8 bit içine yazılabilecek tüm değerleri yazabilirsiniz.
    unsigned int M1 : 1;  //Kalan bir bit Sadece 1  ve 0 değeri alabilir.
}

Edit:  M0 'ın alacağı max değer 1 Byte ile sınırlı.Sanırım Derleyici buna izin vermiyor..
Byte sınırı aşılmaması gerekiyor.

papsukkal

Çok teşekkür ederim. "Unsignet int" lere takılmıştım. Şimdi daha net.