Hi-tech'de diyelim portb'nin bitlerini kontrol etmek için RB0=1 yazıyoruz.
ASM ile bsf portb,0 yaparız.
Fakat bizim tanımladığımız bir 8 bitlik değişkenin bitlerine Hi-Tech'de nasıl erişebiliriz?
ilgili_yazmac|=0b00000001; //0. bit mantık 1 yapıldı.
ilgili_yazmac&=0b11111110;//0. bit mantık 0 yapıldı.
union{
unsigned char Temp;
struct{
unsigned char Bit0:1;
unsigned char Bit1:1;
unsigned char Bit2:1;
unsigned char Bit3:1;
unsigned char Bit4:1;
unsigned char Bit5:1;
unsigned char Bit6:1;
unsigned char Bit7:1;
}Bit;
}Byte;
Byte.Temp=0x55;
RB0=Byte.Bit.Bit2;
RB1=Byte.Bit.Bit3;
hocam teşekkürler
tek komutla yapma şansımız sanırım yok
struct ve union yapıları komut değildir.
Byte.Temp=0x55;
RB0=Byte.Bit.Bit2;
bunlar tek işlemdir, çarp böl topla çıkar kaydır gibi durumlar yoktur
#define bit0 0x1
#define bit1 0x2
#define bit2 0x4
#define bit3 0x8
#define bit4 0x10
#define bit5 0x20
#define bit6 0x40
#define bit7 0x80
#define bit8 0x100
#define bit9 0x200
#define bit10 0x400
#define bit11 0x800
#define bit12 0x1000
#define bit13 0x2000
#define bit14 0x4000
#define bit15 0x8000
#define bit16 0x10000
#define bit17 0x20000
#define bit18 0x40000
#define bit19 0x80000
#define bit20 0x100000
#define bit21 0x200000
#define bit22 0x400000
#define bit23 0x800000
#define bit24 0x1000000
#define bit25 0x2000000
#define bit26 0x4000000
#define bit27 0x8000000
#define bit28 0x10000000
#define bit29 0x20000000
#define bit30 0x40000000
#define bit31 0x80000000
#define PORTB (*((unsigned char*) 0xF81))
#define PORTB0 (PORTB & bit0)
kullanımı
PORTB0 = 1;
Ben bu tip yapı kullanıyorum okunabilirlik ve bellek tasarrufu sağlıyor. Ancak bi ve işleemlik gecikmeye sebeb olur ki hızlı işlemciler içinde sorun değildir... Belki birazda derleme süresi uzatır. O da problem değil...
edit:
Kendi tanımladığımız değişkenler içinde aynı mantık...
int value;
value & bit0 = 1;
Hitech bilmem fakat;
Bit0=1
Bit1=2
Bit2=4
Bit3=8
Bit4=16
Bit5=32
Bit6=64
Bit7=128
Eşitliklerini define direktifi ile bir kere tanımlarsanız daha sonra herhangi bir 8 bit değişkenin mesela A değişkeninin 4 nolu bitini set etmek için
A|=Bit4
Tersine o biti silmek icin
A&='Bit4 demeniz yeterli.
peki,
bir baytı bit bit ayırdık (C olarak en doğrusu tatlisukurnazi arkadaşımızınki)
peki 1 bayt, 2 bayt, 4 bayt uzunluğundaki değişkenleri bir çatı altında nasıl toplarız.? (union/struct olarak)
sebep hitech, Pic C18, Keil C51 de çalışan union/struct tanımlaması Keil ARM de su koydu. Eğer bayt bayt union/struct tanımlarsam sorun yok ama araya long, int türü değişken koyarsam alakasız değerler geri dönüyor. (hex içeriğine baktım sağında solundaki değerler değil yani kayma yok alakasız değerler geri dönüyor)
@mp3dragon
union{
unsigned long Ltemp;
struct{
unsigned int Lint;
unsigned int Hint;
}Int;
struct{
unsigned char Temp0;
unsigned char Temp1;
unsigned char Temp2;
unsigned char Temp3;
}Byte;
struct{
unsigned char Bit0:1;
unsigned char Bit1:1;
unsigned char Bit2:1;
unsigned char Bit3:1;
unsigned char Bit4:1;
unsigned char Bit5:1;
unsigned char Bit6:1;
unsigned char Bit7:1;
unsigned char Bit8:1;
unsigned char Bit9:1;
unsigned char Bit10:1;
unsigned char Bit11:1;
unsigned char Bit12:1;
unsigned char Bit13:1;
unsigned char Bit14:1;
unsigned char Bit15:1;
unsigned char Bit16:1;
unsigned char Bit17:1;
unsigned char Bit18:1;
unsigned char Bit19:1;
unsigned char Bit20:1;
unsigned char Bit21:1;
unsigned char Bit22:1;
unsigned char Bit23:1;
unsigned char Bit24:1;
unsigned char Bit25:1;
unsigned char Bit26:1;
unsigned char Bit27:1;
unsigned char Bit28:1;
unsigned char Bit29:1;
unsigned char Bit30:1;
unsigned char Bit31:1;
}Bit;
}Long;
Long.Bit.Bit31=1;
Long.Ltemp=0xFFFFFFFF;
Long.Int.Hint=0xFFFF;
Long.Byte.Temp0=0xFF;
vs. olabilir.
Arkadaşlar şu olayı yapamadım. Hangi yönteni uygulicam bilemedim. O zaman bana şunu yapabilirmisniz. Benim bilgim az. Yapamadım.
unsigned char deger=0x7C; // 0b01111100 diyelim
unsigned char sonuc;
// Ben istiyorum ki, eğer deger değişkeninin 0. biti 1 ise sonuc değişkeninin 0.biti 1 olsun değilse 0 olsun. Sonra bir sola kayıp, işlem devam etsin. Bunu 7 defa tekrarlayıp her defasında sonucu 'sonuc değişkeninin 0. bitine yazıcam.
//Bu konuda yardımcı olabilirseniz sevinirim.
eğer değeri sola kaydırırsan "0" biti daima "0" değeri alır eğer sağa kaydırırsan bir önceki bit değeri "0" bitine yerleşir.
unsigned char deger;
unsigned char sonuc;
unsigned char i;
for (i=0;i<8;i++){
if(değer && 0x01){
sonuc=0x01;
}
else{
sonuc=0x00;
}
deger = deger >>1;
}
tabi arada yapmak istediğin işlemi tam anlayamadığım 7 defa tekrarlarsan en son 7. bitin değerini sonuca yazarsın. Araya işlem koymazsan tabii.
Bir dakika şimdi!
11111101 değerini sola kaydırınca 11111011 olmuyormu?
senin dediğine göre sağa kaydirinca oluyor. Yanlışmı anadım?
şöyle yapsak demek istediğime gelirmi:
sonu=sonu<<1;
yapmakl istediğim açıkçası şu:
deger içeriğini sonuca aktarmak.
Alıntı yapılan: "bilgehansahin84"Bir dakika şimdi!
11111101 değerini sola kaydırınca 11111011 olmuyormu?
senin dediğine göre sağa kaydirinca oluyor. Yanlışmı anadım?
şöyle yapsak demek istediğime gelirmi:
sonu=sonu<<1;
Hocam C'de "CARRY FLAG" diye bişey yok en azından Carry üzerinden kaydır diye bir komut yok.
Bu durumda C'de << kulanımı sonrası sizin yukarıda beklediğiniz durum oluşmaz.
11111101 << 1
11111010 olur, yani soldan düşen bit kaybolur, sağdan ise 0 değeri girer.
Durumu kontrol etmek için Hi-tech'de bir deneme yaptım.Oluşturulan assembly kodu şu şekilde:
a<<=1;
03B 1003 BCF 0x3, 0
03C 0DA2 RLF 0x22, F
Yani derleyici kaydırma işlemi yapmadan önce Carry bitini sıfırlıyor.
Alıntı yapılan: "tatlisukurnazi"Alıntı yapılan: "bilgehansahin84"Bir dakika şimdi!
11111101 değerini sola kaydırınca 11111011 olmuyormu?
senin dediğine göre sağa kaydirinca oluyor. Yanlışmı anadım?
şöyle yapsak demek istediğime gelirmi:
sonu=sonu<<1;
Hocam C'de "CARRY FLAG" diye bişey yok en azından Carry üzerinden kaydır diye bir komut yok.
Bu durumda C'de << kulanımı sonrası sizin yukarıda beklediğiniz durum oluşmaz.
11111101 << 1
11111010 olur, yani soldan düşen bit kaybolur, sağdan ise 0 değeri girer.
Hi-Tech C de CARRY flag kullanılabiliyor, ben bir çok programımda kullandım.
gidenkomut>>=1;
if(CARRY==1)TRISB2=1; //giriş
işte programımdan bir alıntı. Problemsiz çalışıyor.
Çözümü yok demedim hocam, gerekirse kaydırmayla ilgili kısım asm olarak da yazılabilir.
Kasdettiğim Carry ile kaydır diye birşeyin C de olmadığı.
Derleyici yazdığınız kodu yorumlarken << yada >> görünce Caryy'siz kaydırma komutu varsa onu kullanır, eğer yoksa önce Carry bitini temizler.
Ha gönül isterdiki; atıyorum "<c<" gibi bir kaydırma komutuda C'de olsun ama malesef yok, sebep ansi standartları...
gidenkomut>>=1;
if(CARRY==1)TRISB2=1; //giriş
Bunun sorunsuz çalışması için derleyicinin CARRY'i temizlememesi gerekmiyor mu? Görülen o ki temizliyor.O zaman nasıl olacak bu iş?
Derleyici Carry bitini otomatik olarak temizliyorsa yukarıdaki kodun çalışmaması gerekiyor öyle değil mi?
Yada Hi-tech ayarlarında bununla ilgili bir opsiyon mu var gözden kaçan?
Arkadaşlar karıştırdığınız bir nokta var;
Porta atılan, C'deki değer kayma sonrası değişkenden düşen bit, yani o caryy'e gitmiş zero flag'a gitmiş uzayda kaybolmuş C'için(bizim için demiyorum dikkat edin) önemli değil.
Derleyici giren değerin sıfır olmasını sağlamak zorunda, bunun için carry'siz kaydırma komutu yada carry'i temizleyip ondan sonra kaydırma komutu gibi bir kaç alternatiften biri seçilebilir.
Ha pic'de çalışan bu kod başka mcu da çalışmayabilir, zira carry üzerinde kaydırma komutu olmayan mcu da olabilir, bu durumda derleyici düşen biti Carry'e atıcam diye bir kasıntıya asla girmeyecektir, o da ayrı bir konu..
Allah'a aşkına bu kodda nerde yanlışlık yapıyorum arkadaşlar?
Amaç: 'veri' değilkeninin içerisindeki verileri 'yedek' değişkeninin içerisine atmak.
for (tekrar=0;tekrar<=7;tekrar++)
{
veri=DATAM[tekrar]; // 'veri' değişkenine bir diziden veriler alınıyor.
yedek1=veri&&0B00000001; // ilk bit 1 mi?
if (yedek1==0x01)
{ // evet ise
RB0=1; // yedek değişkeninin 0. bitini bir yap.
DelayMs(100); //eğer yedek bir önceki işlemden '111001110' ise
// şimdi '111001111' oldu.
else{
RB0=0 ; // hayır ise
DelayMs(100); //
yedek=yedek&&0B00000000; // son biti (0. biti) '0' yap.
}
yedek=yedek<<1;
}
Alıntı yapılan: "bilgehansahin84"yedek=yedek&&0B00000000; // son biti (0. biti) '0' yap.
}
}
yedek 0 olmuş. son biti değil hepsi.
Hocam haklısın. Hemen düzelttim çalışıyor şimdi. Fakat bir o sorun yokmuş, '&&' yerine '&' ve '||' yerinede '|' kullanmam gerekiyormuş. Şimdi hatasız çalışıyor program.
Peki arkadaşlar word tipinde bir veri tanımlasak ve bu veriyi 16 kez sağa veya sola kaydırsak , bu işlem sırasında carry nasıl bir görev üstlenecek veya kaydırma komutu düzgün bir şekilde çalışacakmı?