Bitwise işlemleri

Bitwise işlemleri

Konuyu okuyanların bit ve byte terimlerini bilmesi şarttır.

Bu dökümanı okuyanların aşağıdaki konularda bilgili olduğunu varsayıyorum:

  1. Binary sayılar,
  2. AND, OR gibi matematiksel işlemler,
  3. Pic programlama dillerinden C tabanlı bir dil

Bu dökümanda ne anlatılıyor:

  1. Bir sayının herhangi bir bitini, diğer bitlerin değerini koruyarak değiştirmek. Bu işlemi hazır fonksiyon kullanarak değil de matematiksel ve mantıksal işlemler ile yapmak.
  2. Herhangi bir sayının, herhangi bir bit’inin 0 mı 1 mi olduğunu öğrenmek.
  3. Mikrodenetleyicinin farklı portlarında atamalar, sorgulamalar, eşitlemeler vs. yapmak.

Bitwise oparatörleri şunlardır:
>> ROR sağa kaydır
<< ROL sola kaydır
~ NOT oparatörü
| OR opararörü
& AND oparatörü
^ XOR oparatörü

a=0b10100000>>1  bir kere sağa kaydırmak demek o sayıyı ikiye bölmek demektir.
Basit bir göz kararıyla sayıyı 1 kere sağa kaydırırsak sayının 0b01010000 olduğunu hemen anlarız.
Sayıyı 2 ye bölerek nasıl bulabiliriz?
0b10100000= (0+0+0+0+0+32+0+128)=160 eder. 160/2=80 eder.
80 ise 2 lik tabanda:  (64+16 dır). Yani a’nın değeri 0b01010000 olur.

a=0b00000101<<1 bir kere sola kaydırmak demek o sayıyı ikiyle carpmak demektir.
Basit bir göz kararıyla sayıyı 1 kere sola kaydırırsak sayının 0b00001010 olduğunu hemen anlarız.
Sayıyı 2 ile çarparak nasıl bulabiliriz?
0b00000101= (1+0+4+0+0+0+0+0)=5 eder. 5*2=10 eder.
10 ise 2 lik tabanda:  (8+2 dır). Yani a’nın değeri 0b00001010 olur.

kısaca;
a=x<<y dediğimizde a değişkeninin değeri, x sayısının y kere sola kaydırılmışı olur. a=1<<5; //a nın değeri 00100000
Aklınıza takılmış olabilir neden, 5. biti değilde 6. biti 1 oldu diye. Açıklayayım.
1<<0 ifadesi bu sayıya eşittir: 0b00000001
Yani 0. bitten başladığı için 5. değil 6. bite denk geldi.
peki a=5<<3 deseydik ne olacaktı?
4 sayısı 2 lik tabanda 0b101 demektir, 3 kere sola kaydırmak sonuna 3 sıfır eklemek demektir.
yani 0b101000 olur, 8 bite tamamlamak için 6 bitlik olan bu sayının başına 2 adet 0 ekleyecek olursak
a=0b00101000 olur

6 sayısını 2 kere sağa kaydıralım:
a=6>>2;
6 demek 0b00000110 demektir.
1 kere kaydırsak: 0b00000011 olur.
1 kere daha kaydırırsak: a=0b00000001 olur

Kaydırma olayını anlamışsınızdır diye düşünüyorum.

OR işlemi:
Or demek “veya” demektir. Matematikte toplama işlemine denk gelir. İşleme giren 2 değerden birisinin 1 olması sonucu 1 yapmaya yeterlidir.
0 or 0 = 0 eder
0 or 1 = 1 eder
1 or 0 = 1 eder
1 or 1 = 1 eder (2 lik tabandaki en büyük sayı 1 olduğundan 1 + 1 = 1 eder)

or işlemi c dilinde | ifadesi ile temsil edilir. Bu karakter AltGr+Tire kısayolu ile oluşturulur.
a=0b01010101 | 0b10101010 demek a = 0b11111111 demektir

Dipnot: AltGr+çifttırnak : “<” işaretini, AltGr+1: “>” işaretini oluşturur. “^” işaretini shift+3 yapıp boşluk bırakarak oluşturabilirsiniz. “~” işareti “tilde” demektir. Tildeyi oluşturmak için ctrl+alt+ü kısayolunu yazdıktan sonra boşluk bırakarak oluşturabiliriz. “Alt” tuşu ile beraber 1,2,6 ya sırasıyla basarak ta yapabilirsiniz. Ancak laptop kullanıyorsanız “Fn” tuşu ile klavyenin orta kısmında bulunan numaralara basmanız gerekir. PC’de de aynı tek fark “Fn” tuşu… Bir not daha düşelim, bir karakterin ascii kodunu bulmak için ascii kod tablosuna bakabilirsiniz ancak bunun pratik bir yöntemi daha var. C veya C++ dilinde printf(“%d”,(int)’~‘); komutunu yazarsanız ‘~’ kısmına yazdığınız karakterin ascii kodunu ekrandan okursunuz.

AND işlemi:
And demek “ve” demektir. Matematikte çarpma işlemine denk gelir. İşleme giren 2 değerin de 1 olduğu durumda sonuç 1 olur bunun dışında sonuç 0 dır.
0 and 0 = 0 eder
0 and 1 = 0 eder
1 and 0 = 0 eder
1 and 1= 1 eder
a=0b10111001 and 0b10000001 demek a=10000001 demektir

XOR ve XNOR kapılarının kullanımı uzun bir konu olduğundan daha önce anlattığım dökümandan öğrenebilirsiniz: http://gokhanbeken.com/?p=848

PORTB = ((~(1<<0)) & LATB); //portb nin 0. bitini 0 yapar. PORTB=0b11111111; ise yeni değeri 0b11111110 olur
PORTB = ((~(1<<1)) & LATB); //portb nin 1. bitini 0 yapar.
PORTB = ((~(1<<2)) & LATB); //portb nin 2. bitini 0 yapar.
PORTB = ((~(1<<3)) & LATB); //portb nin 3. bitini 0 yapar.
PORTB = ((~(1<<4)) & LATB); //portb nin 4. bitini 0 yapar.
PORTB = ((~(1<<5)) & LATB); //portb nin 5. bitini 0 yapar.
PORTB = ((~(1<<6)) & LATB); //portb nin 6. bitini 0 yapar.
PORTB = ((~(1<<7)) & LATB); //portb nin 7. bitini 0 yapar.

 

PORTB = (1<<0) | LATB; //portb nin 0. bitini 1 yapar. PORTB=0b00000000 ise yeni değeri 0b00000001 olur
PORTB = (1<<1) | LATB; //portb nin 1. bitini 1 yapar.
PORTB = (1<<2) | LATB; //portb nin 2. bitini 1 yapar.
PORTB = (1<<3) | LATB; //portb nin 3. bitini 1 yapar.
PORTB = (1<<4) | LATB; //portb nin 4. bitini 1 yapar.
PORTB = (1<<5) | LATB; //portb nin 5. bitini 1 yapar.
PORTB = (1<<6) | LATB; //portb nin 6. bitini 1 yapar.
PORTB = (1<<7) | LATB; //portb nin 7. bitini 1 yapar.

BİT TEST İŞLEMİ

Kullandığımız dilin hazır fonksiyonlarını kullanarak sorun olmadan işlemimizi gerçekleştirebiliriz. Bu bizi tatmin etmemeli. Çünkü elekronik devreler için program yazan insanlar sürekli farklı dillerde program yazmaya alışkındırlar. Bir dilde yazdığımız kodu başka dilde yazma ihtiyacımız çok yüksektir. Bu yüzden mümkün olduğu kadar az hazır fonksiyon kullanırız. Kendi kütüphanelerimizi yazarız ve kullandığımız dil en taşınabilir dil olan C olduğu için c tabanlı bütün dillere adapte edebiliriz. Aşağıdaki kodlar hazır fonksiyonlar yardımı ile oluşturuldu. PORTDbits.RD0 kısmı c18 programlama dilinin bize sağladığı hazır yemeklerden birisidir. Biz bunu kendimiz yaparsak, kodlarımız daha taşınabilir olur ve sorgulama işlemini sadece PORT lar için değil herhangi bir sayının felanca bitinin 1 mi 0 mı olduğunu öğrenebiliriz.

if(PORTDbits.RD0) {PORTB = (1<<0) | LATB;} else{PORTB = ((~(1<<0)) & LATB);} //eğer portd nin 0. biti 1 ise portb nin 0. bitini 1 yap, yoksa, 0 yap
if(PORTDbits.RD1) {PORTB = (1<<1) | LATB;} else{PORTB = ((~(1<<1)) & LATB);} //eğer portd nin 1. biti 1 ise portb nin 1. bitini 1 yap, yoksa, 0 yap
if(PORTDbits.RD2) {PORTB = (1<<2) | LATB;} else{PORTB = ((~(1<<2)) & LATB);} //eğer portd nin 2. biti 1 ise portb nin 2. bitini 1 yap, yoksa, 0 yap
if(PORTDbits.RD3) {PORTB = (1<<3) | LATB;} else{PORTB = ((~(1<<3)) & LATB);} //eğer portd nin 3. biti 1 ise portb nin 3. bitini 1 yap, yoksa, 0 yap
if(PORTDbits.RD4) {PORTB = (1<<4) | LATB;} else{PORTB = ((~(1<<4)) & LATB);} //eğer portd nin 4. biti 1 ise portb nin 4. bitini 1 yap, yoksa, 0 yap
if(PORTDbits.RD5) {PORTB = (1<<5) | LATB;} else{PORTB = ((~(1<<5)) & LATB);} //eğer portd nin 5. biti 1 ise portb nin 5. bitini 1 yap, yoksa, 0 yap
if(PORTDbits.RD6) {PORTB = (1<<6) | LATB;} else{PORTB = ((~(1<<6)) & LATB);} //eğer portd nin 6. biti 1 ise portb nin 6. bitini 1 yap, yoksa, 0 yap
if(PORTDbits.RD7) {PORTB = (1<<7) | LATB;} else{PORTB = ((~(1<<7)) & LATB);} //eğer portd nin 7. biti 1 ise portb nin 7. bitini 1 yap, yoksa, 0 yap

Aşağıda ise hazır fonksiyon değil kendi bit işlemlerim ile aynı işlemi yapıyoruz. Örnek: 00100110 sayısının 5. bitinin 1 olup olmadığını anlamak için 00100000 sayısı ile ve işlemine tabi tutarız. Eğer sonuç 0 değilse test olumludur.

if((1<<0) & PORTD) {PORTB = (1<<0) | LATB;} else{PORTB = ((~(1<<0)) & LATB);} //eğer portd nin 0. biti 1 ise portb nin 0. bitini 1 yap, yoksa, 0 yap
if((1<<1) & PORTD) {PORTB = (1<<1) | LATB;} else{PORTB = ((~(1<<1)) & LATB);} //eğer portd nin 1. biti 1 ise portb nin 1. bitini 1 yap, yoksa, 0 yap
if((1<<2) & PORTD) {PORTB = (1<<2) | LATB;} else{PORTB = ((~(1<<2)) & LATB);} //eğer portd nin 2. biti 1 ise portb nin 2. bitini 1 yap, yoksa, 0 yap
if((1<<3) & PORTD) {PORTB = (1<<3) | LATB;} else{PORTB = ((~(1<<3)) & LATB);} //eğer portd nin 3. biti 1 ise portb nin 3. bitini 1 yap, yoksa, 0 yap
if((1<<4) & PORTD) {PORTB = (1<<4) | LATB;} else{PORTB = ((~(1<<4)) & LATB);} //eğer portd nin 4. biti 1 ise portb nin 4. bitini 1 yap, yoksa, 0 yap
if((1<<5) & PORTD) {PORTB = (1<<5) | LATB;} else{PORTB = ((~(1<<5)) & LATB);} //eğer portd nin 5. biti 1 ise portb nin 5. bitini 1 yap, yoksa, 0 yap
if((1<<6) & PORTD) {PORTB = (1<<6) | LATB;} else{PORTB = ((~(1<<6)) & LATB);} //eğer portd nin 6. biti 1 ise portb nin 6. bitini 1 yap, yoksa, 0 yap
if((1<<7) & PORTD) {PORTB = (1<<7) | LATB;} else{PORTB = ((~(1<<7)) & LATB);} //eğer portd nin 7. biti 1 ise portb nin 7. bitini 1 yap, yoksa, 0 yap

Yukardakilerin açılımı böyledir. İkisi aynı işi yapıyor ancak anlaşılır olması açısından aşağıdaki gibi kullanabiliriz.

if(((1<<0) & PORTD) != 0) {PORTB = (1<<0) | LATB;} else{PORTB = ((~(1<<0)) & LATB);} //eğer portd nin 0. biti 1 ise portb nin 0. bitini 1 yap, yoksa, 0 yap
if(((1<<1) & PORTD) != 0) {PORTB = (1<<1) | LATB;} else{PORTB = ((~(1<<1)) & LATB);} //eğer portd nin 1. biti 1 ise portb nin 1. bitini 1 yap, yoksa, 0 yap
if(((1<<2) & PORTD) != 0) {PORTB = (1<<2) | LATB;} else{PORTB = ((~(1<<2)) & LATB);} //eğer portd nin 2. biti 1 ise portb nin 2. bitini 1 yap, yoksa, 0 yap
if(((1<<3) & PORTD) != 0) {PORTB = (1<<3) | LATB;} else{PORTB = ((~(1<<3)) & LATB);} //eğer portd nin 3. biti 1 ise portb nin 3. bitini 1 yap, yoksa, 0 yap
if(((1<<4) & PORTD) != 0) {PORTB = (1<<4) | LATB;} else{PORTB = ((~(1<<4)) & LATB);} //eğer portd nin 4. biti 1 ise portb nin 4. bitini 1 yap, yoksa, 0 yap
if(((1<<5) & PORTD) != 0) {PORTB = (1<<5) | LATB;} else{PORTB = ((~(1<<5)) & LATB);} //eğer portd nin 5. biti 1 ise portb nin 5. bitini 1 yap, yoksa, 0 yap
if(((1<<6) & PORTD) != 0) {PORTB = (1<<6) | LATB;} else{PORTB = ((~(1<<6)) & LATB);} //eğer portd nin 6. biti 1 ise portb nin 6. bitini 1 yap, yoksa, 0 yap
if(((1<<7) & PORTD) != 0) {PORTB = (1<<7) | LATB;} else{PORTB = ((~(1<<7)) & LATB);} //eğer portd nin 7. biti 1 ise portb nin 7. bitini 1 yap, yoksa, 0 yap

Aşağıda ise çıkış olarak kullandığımız portb yi, yine çıkış olarak kullandığımız portc ye atıyoruz. Komple değil istediğimiz pinleri taşıyoruz. Bir ayrıyı belirteyim: TRISB=0x00; dır, TRISC=0xFF; tir.
Bu kodlarda dikkat etmemiz gereken, if bloğunda diğerleri gibi PORTB ile değil de LATB ile sorgulamamızdır.
PORTB yi çıkış olarak kullandığımızdan ordan okuma yapmak için LATB yi kullanmamız gerekir yoksa yalnış sonuç üretir. Eğer PORTB yi giriş olarak kullansaydık PORTB diye sorgulayabilirdik.

if(((1<<0) & LATB) != 0) {PORTC = (1<<0) | LATB;} else{PORTC = ((~(1<<0)) & LATB);} //eğer portb nin 0. biti 1 ise portc nin 0. bitini 1 yap, yoksa, 0 yap
if(((1<<1) & LATB) != 0) {PORTC = (1<<1) | LATB;} else{PORTC = ((~(1<<1)) & LATB);} //eğer portb nin 1. biti 1 ise portc nin 1. bitini 1 yap, yoksa, 0 yap
if(((1<<2) & LATB) != 0) {PORTC = (1<<2) | LATB;} else{PORTC = ((~(1<<2)) & LATB);} //eğer portb nin 2. biti 1 ise portc nin 2. bitini 1 yap, yoksa, 0 yap
if(((1<<3) & LATB) != 0) {PORTC = (1<<3) | LATB;} else{PORTC = ((~(1<<3)) & LATB);} //eğer portb nin 3. biti 1 ise portc nin 3. bitini 1 yap, yoksa, 0 yap
if(((1<<4) & LATB) != 0) {PORTC = (1<<4) | LATB;} else{PORTC = ((~(1<<4)) & LATB);} //eğer portb nin 4. biti 1 ise portc nin 4. bitini 1 yap, yoksa, 0 yap
if(((1<<5) & LATB) != 0) {PORTC = (1<<5) | LATB;} else{PORTC = ((~(1<<5)) & LATB);} //eğer portb nin 5. biti 1 ise portc nin 5. bitini 1 yap, yoksa, 0 yap
if(((1<<6) & LATB) != 0) {PORTC = (1<<6) | LATB;} else{PORTC = ((~(1<<6)) & LATB);} //eğer portb nin 6. biti 1 ise portc nin 6. bitini 1 yap, yoksa, 0 yap
if(((1<<7) & LATB) != 0) {PORTC = (1<<7) | LATB;} else{PORTC = ((~(1<<7)) & LATB);} //eğer portb nin 7. biti 1 ise portc nin 7. bitini 1 yap, yoksa, 0 yap

One thought on “Bitwise işlemleri

  1. Bu yöntem ise if yerine Conditional Operator kullanma yöntemidir:

    PORTB = ((((1< <0) & PORTD) != 0) ? (PORTB = (1<<0) | LATB): (PORTB = ((~(1<<0)) & LATB))); //eğer portd nin 0. biti 1 ise portb nin 0. bitini 1 yap, yoksa, 0 yap
    PORTB = ((((1<<1) & PORTD) != 0) ? (PORTB = (1<<1) | LATB): (PORTB = ((~(1<<1)) & LATB))); //eğer portd nin 1. biti 1 ise portb nin 1. bitini 1 yap, yoksa, 0 yap
    PORTB = ((((1<<2) & PORTD) != 0) ? (PORTB = (1<<2) | LATB): (PORTB = ((~(1<<2)) & LATB))); //eğer portd nin 2. biti 1 ise portb nin 2. bitini 1 yap, yoksa, 0 yap
    PORTB = ((((1<<3) & PORTD) != 0) ? (PORTB = (1<<3) | LATB): (PORTB = ((~(1<<3)) & LATB))); //eğer portd nin 3. biti 1 ise portb nin 3. bitini 1 yap, yoksa, 0 yap
    PORTB = ((((1<<4) & PORTD) != 0) ? (PORTB = (1<<4) | LATB): (PORTB = ((~(1<<4)) & LATB))); //eğer portd nin 4. biti 1 ise portb nin 4. bitini 1 yap, yoksa, 0 yap
    PORTB = ((((1<<5) & PORTD) != 0) ? (PORTB = (1<<5) | LATB): (PORTB = ((~(1<<5)) & LATB))); //eğer portd nin 5. biti 1 ise portb nin 5. bitini 1 yap, yoksa, 0 yap
    PORTB = ((((1<<6) & PORTD) != 0) ? (PORTB = (1<<6) | LATB): (PORTB = ((~(1<<6)) & LATB))); //eğer portd nin 6. biti 1 ise portb nin 6. bitini 1 yap, yoksa, 0 yap
    PORTB = ((((1<<7) & PORTD) != 0) ? (PORTB = (1<<7) | LATB): (PORTB = ((~(1<<7)) & LATB))); //eğer portd nin 7. biti 1 ise portb nin 7. bitini 1 yap, yoksa, 0 yap
    

Bir Cevap Yazın