istenilen bitleri değiştirme

Başlatan blacklogic, 14 Eylül 2013, 05:47:30

blacklogic

Merhaba elimde 16 bitlik bir veri var ve ben bu verinin 4-5-6-7. bitlerini değiştirmek istiyorum. Program içerisinde diğer bitler sürekli değişmekte olduğundan onları bozmamam lazım. Bu durumda nasıl bir uygulama yapmam gerekiyor ?
İyi çalışmalar

Ateş Erim

Benim aklıma şöyle birşey geliyor ama çok mu acemice bilemiyorum
Önce elinizdeki veriyi:
1111 1111 0000 1111 ile AND' leseniz, böylelikle 4, 5, 6, 7. Bitleri 0'a çekip diğerlerini bozmamış olursunuz;
İkinci aşama olarak ta, elde ettiğiniz yeni veriyi:
0000 0000 xxxx 0000 ile OR'lasanız (xxxx değiştirmek istediğiniz bitler) gene 4, 5, 6, 7. bitler haricindekileri bozmadan istediğiniz bitleri değiştirebilirmişsiniz gibime geliyor ama bilmem ki çok mu kulağı tersten göstermiş oldum  :-[

Ha bir de anlamışsınızdır C bilmiyorum ama AND-OR illa ki vardır C'de diye salladım  ;)

Kolay gelsin
Bu mektup icin hic agac kesmedim. Sadece elektronlari durtukledim.

Tagli

Diğer bitleri değiştiren nedir? Ana programın başka bir bölümü mü, kesme kodu mu yoksa donanım mı? Kodu eklersen daha rahat anlaşılır durum.
Gökçe Tağlıoğlu

izturk

şöyle olur sanırım

degisken_ismi = degisken_ismi & 0b1111111100001111;

4,5,6,7. bitleri sıfır yaptık. 16 bitlik değişkenin ilk değeriyle yukardaki yazdığımız değeri ve işlemine tabii tuttuk ve yeniden değişkene yükledik

blacklogic

Alıntı yapılan: Tagli - 14 Eylül 2013, 08:27:34
Diğer bitleri değiştiren nedir? Ana programın başka bir bölümü mü, kesme kodu mu yoksa donanım mı? Kodu eklersen daha rahat anlaşılır durum.

diğer bitlere de ben müdahale ediyorum aslında programın farklı yerlerinde yada etmem gerekecek diyelim.
Arm lcd yapmaya çalışıyorum
#define LCD GPIOA->ODR // A4 A5 A6 A7
void lcd(char ne, unsigned int veri2,unsigned int veri1)
{
unsigned int L=0, H=0;
	L = veri1 * 16;
	H = veri2 * 16;
	
	lcdNeYazilacak(ne);
	lcdEDegistir();
	LCD |=L;
	lcdNeYazilacak(ne);
	lcdEDegistir();
	LCD |=H;	
	
}


misal lcdye kod göndermek istediğimde 0x23 misal  lcd(k, 0x2, 0x3) şeklinde gönderiyorum. a9 pininden de sürekli bir led yak söndür yapacağım misal.


kodun tamamı

#include <stm32f10x.h>
#include "LCD.h"
// rs pini komut için 0 veri için 1 olmali
#define RS GPIOA->ODR // A1
#define E GPIOA->ODR // A3
#define RW GPIOA->ODR // A2
#define LCD GPIOA->ODR // A4 A5 A6 A7

void lcd(char ne, unsigned int veri2,unsigned int veri1)
{
unsigned int L=0, H=0;
	L = veri1 * 16;
	H = veri2 * 16;
	
	lcdNeYazilacak(ne);
	lcdEDegistir();
	LCD |=L;
	lcdNeYazilacak(ne);
	lcdEDegistir();
	LCD |=H;	
	
}


void lcdNeYazilacak(char ne)      // LCD'ye giden bilgimiz veri ya da komut olabilir.
{
  if(ne == 'k')                   // Komut ise;
    GPIOA->BRR = 0x2;                       // RS pini "0" yapilir.
  else if(ne == 'v')              // Veri ise;
    RS |= 0x2;                       // RS pini "1" yapilir.
}


void lcd_hazirla(void)
{

	delaylcd();
	lcd('k', 0x0, 0x2);           // "00000010" yani imleç en basa gidecek.
	delaylcd();
	lcd('k', 0x0, 0x3);           // "00000010" yani imleç en basa gidecek.
	delaylcd();
  lcd('k', 0x0, 0x1);           // "00000001" yani LCD temizlenecek.
	delaylcd();
	lcd('k', 0x2, 0x8);           // "00101000" yani 4 pin, 2 satir, 5x7 karakter kullanilacak.
	delaylcd();
	lcd('k', 0x0, 0x6);
	delaylcd();
	lcd('k', 0x0, 0xB);
	delaylcd();
	
	
}



void lcdEDegistir(void)           // E pini düsen kenar tetiklemeli.
{                                 // Bu yüzden gönderdigimiz bilginin LCD üzerinde
  E |= 0x4;                          // islem görmesi için E ucuna düsen kenar uyguluyoruz.
  GPIOA->BRR = 0x4;                          // Bunu da E'yi önce "1", sonra "0" yaparak hallediyoruz.
}


void delaylcd(void)
{
	unsigned long delay=0x00000872;		//8MHz'lik osilatör için 3ms'den biraz fazla geçikme.
	while(delay--);
}


Alıntı yapılan: izturk - 14 Eylül 2013, 09:01:46
şöyle olur sanırım

degisken_ismi = degisken_ismi & 0b1111111100001111;

4,5,6,7. bitleri sıfır yaptık. 16 bitlik değişkenin ilk değeriyle yukardaki yazdığımız değeri ve işlemine tabii tuttuk ve yeniden değişkene yükledik

Söylediğinizi deniyeceğim.

esensoy

#5
bitler 0 yapmak için yukarıda ki gibi, 1 yapmak için de;
var = var | 0000000011110000;

yapmalısınız,
Arada ki L değildir, veya işaretidir, AltGr ile büyük-küçük işaretine basınca çıkar,
En tehlikeli an "zafer" anıdır.

Okan AKÇA

veya işlemi ile rahatlıkla olur hatta kücük bir driver yazılarak  dahada pratikleştirilir.

blacklogic

dediğiniz gibi | işaretini kullandım ama çalıştıramadım lcdyi. ayrıca şu formül ne anlama gelir ?
bit_word_addr = bit_band_base + (byte_offset x 32) + (bit_number × 4)

Bayramsumbul

Merhabalar.. İstediğiniz Budur Her Halde?Makro Olarak Ta Yapılabilirdi Ama,Buyurun...
void BSF(int file,int bit)//BitSetFile
{
	file |=(1 << bit);
}
void BCF(int file,int bit)//Bit Clear File
{
	file &=!(1 << bit);
}
int BTF(int file,int bit)//Bit Test File 1 İse 1 Döner,0 İse Sıfır
{
	bit=1<<bit;
	if(bit&=file){return(1);}
	else{return(0);}
}
Bir Elektronik Meraklısının Serüveni...

Tagli

Henuz ARM konusunda deneyimim yok ancak STM32F0 belgelerini biraz incelemistim. Bildigim kadariyla, bu islemcilerde port bitlerini 1 ve 0 yapmak icin ayri register'lar var. Boylece diger bitlere (cikislara) dokunmadan sadece istenilen bacaklar 1 veya 0 yapilabiliyor. Mesela sifirlama register'inda, sifirlanacak bacaklara 1 yaziliyor, 0 yazilan bacaklar ile degismiyor.
Gökçe Tağlıoğlu

Bayramsumbul

#10
Evet Var Stm32F0'da.Bknz Datasheet'ten Alıntı;
Alıntı YapGPIO port bit set/reset register (GPIOx_BSRR) (x = A..D, F)
Address offset: 0x18
Reset value: 0x0000 0000
Alıntı Yap31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
BR15 BR14 BR13 BR12 BR11 BR10 BR9 BR8 BR7 BR6 BR5 BR4 BR3 BR2 BR1 BR0
w w w w w w w w w w w w w w w w
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
BS15 BS14 BS13 BS12 BS11 BS10 BS9 BS8 BS7 BS6 BS5 BS4 BS3 BS2 BS1 BS0
w w w w w w w w w w w w w w w w

Bits 31:16 BRy: Port x reset bit y (y = 0..15)
These bits are write-only. A read to these bits returns the value 0x0000.
0: No action on the corresponding ODRx bit
1: Resets the corresponding ODRx bit
Note: If both BSx and BRx are set, BSx has priority.
Bits 15:0 BSy: Port x set bit y (y= 0..15)
These bits are write-only. A read to these bits returns the value 0x0000.
0: No action on the corresponding ODRx bit
1: Sets the corresponding ODRx bit

mesaj birleştirme:: 14 Eylül 2013, 11:00:47

Şimdi Baktım Da Stm32f4'ünde Aynı Yazmacı Var "GPIOx->BSSR"
Bir Elektronik Meraklısının Serüveni...

blacklogic

Alıntı yapılan: Bayramsumbul - 14 Eylül 2013, 10:45:28
Merhabalar.. İstediğiniz Budur Her Halde?Makro Olarak Ta Yapılabilirdi Ama,Buyurun...
void BSF(int file,int bit)//BitSetFile
{
	file |=(1 << bit);
}
void BCF(int file,int bit)//Bit Clear File
{
	file &=!(1 << bit);
}
int BTF(int file,int bit)//Bit Test File 1 İse 1 Döner,0 İse Sıfır
{
	bit=1<<bit;
	if(bit&=file){return(1);}
	else{return(0);}
}


elinize sağlık

Bayramsumbul

Bu Arada Macro Hali.BTF'ye Yanaşmadım Macrolar'da Nasıl Return() Oluyor Emin Değilim..
#define	BSF(file,bit)	(file |=(1 << bit))
#define	BCF(file,bit)	(file &=!(1 << bit))
Bir Elektronik Meraklısının Serüveni...

rree

struct DegStrcATyp{
       char Byte0;
      };
struct DegStrcBTyp{
       int1 Bbit0;
       int1 Bbit1;
       int1 Bbit2;
       int1 Bbit3;
       int1 Bbit4;
       int1 Bbit5;
       int1 Bbit6;
       int1 Bbit7;
      
      };
union DegUnType {
      struct DegStrcATyp DegStrcA;
      struct DegStrcBTyp DegStrcB;
  };
union  DegUnType DegUn;
#define x8DegA0 DegUn.DegStrcA.Byte0
#define x1DegA0 DegUn.DegStrcB.Bbit0
#define x1DegA1 DegUn.DegStrcB.Bbit1
#define x1DegA2 DegUn.DegStrcB.Bbit2
#define x1DegA3 DegUn.DegStrcB.Bbit3
#define x1DegA4 DegUn.DegStrcB.Bbit4
#define x1DegA5 DegUn.DegStrcB.Bbit5
#define x1DegA6 DegUn.DegStrcB.Bbit6
#define x1DegA7 DegUn.DegStrcB.Bbit7


struct  ve union ile değşken ile bit cinsinden parçalara böl istediğini değiştir. örnekte byte cinsinden 16 bit rahatlıkla yapılabilir.