i2c istenilen register adresini okumak

Başlatan pikcimametusta, 23 Kasım 2016, 17:29:59

pikcimametusta

Arkadaşlar göndermek istedigim söyle birşey fakat slayer ilk ack bitinden sonra register içerigini gönderiyormuş bunu nasıl yapabilirim?(Yeni pic ögreniyorum)
START+SLAYERİN-7BITLIK-ADRESİ+1(READ İCİN)+ACK(BUNU SLAYER GONDERDİ)+
SLAYERİN-OKUNACAK-REGİSTERİ(MASTER GONDERDİ)+ACK(SLAYER GONDERDİ)+
SLAYERİN-REGİSTER-İCERİGİ(SLAYER GONDERDİ)+NACK(MASTER GONDERDİ İLETİSİMİ SONLANDIRMAK İCİN)+STOP

Cemre.

http://embedded-lab.com/blog/lab-14-inter-integrated-circuit-i2c-communication/

Read operation başlığı altında random read kısmını okuyarak başlangıç yapabilirsiniz. Tam olarak yapılan iletişim de orada grafik olarak gösterilmiş. Sorunuzun doğrudan cevabını veriyor yani. Anlaşılamayan bir yer olursa tekrar birlikte değerlendirmeye çalışırız.

@muhittin_kaplan hocam da bu konuda çalışıyordu, bilgiler tazeyken bizi aydınlatır sanıyorum  :)

muhittin_kaplan

ben STM ile çalışıyorum ama I2C I2C dir (başa beladır).


cihazımız 7bit adrese sahip ve adresi b1110111x

eğer son bit 1 olursa "o adresli" sensore yazma yapılacağı
eğer son bit 0 olursa "o adresli" sensorden okuma yapılacağı bildiriliyor. Buradan yola çıkarak 0xEE yada 0xEF oluyor. (Bu deger sensöre göre değişir)
aşağıdada işlem mevcut.

//unsigned short int uw2;
	I2C_Start();		  	// Initial Start bit sequence
	I2C_Addr(address);	 	// Address I2C Device. (Base address is Write Address)
	I2C_Write(cmd);		// Transfer Command to I2C Device (Register to be Read)
	I2C_Start(); 			// Repeated start bit sequence
	I2C_Addr(address+1);	// Address I2C Device. (Base address + 1 is Read Address)
	uw = I2C_Read(1) << 8;	// Read MSB  without Acknowledge
	uw |= I2C_Read(0); 	// Read LSB	 with Acknowledge
	I2C_Stop();			// Stop I2C transfer
	return( uw );
[code]

skara1214

i2c de read yaparken ack mı yoksa now ack mı yapacağımızı nasıl ayarlıyoruz buradan?
Herkes ölür ama herkes gerçekten yaşamaz

pikcimametusta

#4
Alıntı yapılan: skara1214 - 24 Kasım 2016, 14:21:10
i2c de read yaparken ack mı yoksa now ack mı yapacağımızı nasıl ayarlıyoruz buradan?
Hocam senin cevap aşagıda.İki pici i2c ile haberleştirmeye çalısıyorum sabahtan beri bir türlü slave nin adresini gönderemedim...
//Function : I2C_Send_ACK sends ACK bit sequence
void I2C_Send_ACK(void)
{
	ACKDT = 0;			// 0 means ACK
	ACKEN = 1;			// Send ACKDT value
	while(!SSPIF);		// Wait for it to complete
	SSPIF = 0;			// Clear the flag bit
}


//Function : I2C_Send_NACK sends NACK bit sequence
void I2C_Send_NACK(void)
{
	ACKDT = 1;			// 1 means NACK
	ACKEN = 1;			// Send ACKDT value
	while(!SSPIF);		// Wait for it to complete
	SSPIF = 0;			// Clear the flag bit
}

skara1214

yok hocam picten bahsetmiyorum. ARM de hazır kodllarla nasıl yapıyoruz onu merak ediyorum
Herkes ölür ama herkes gerçekten yaşamaz

muhittin_kaplan

#6
void I2C_Start (void) {
if ( I2C1->CR1 & ( 1 << 10 ) ) {
		I2C1->CR1 &= ~(1 << 10 );
	}
  I2C1->CR1 |= 0x0100; //start genneration when bus free
  while (!(I2C_sr() & 0x0001));
}


void I2C_Addr (unsigned char adr) {

  I2C1->DR = adr;
  while (!(I2C_sr() & 0x0002));	//Addr sent
}


void I2C_Write (unsigned char c) {

  I2C1->DR = c;
  while (!(I2C_sr() & 0x00000004));     /* Wait until BTF bit set             */
}


unsigned char I2C_Read (int ack) {

  /* Enable/disable Master acknowledge                                        */
  if (ack) I2C1->CR1 |=  0x0400;
  else     I2C1->CR1 &= ~0x0400;

  while (!(I2C_sr() & 0x00000040));     /* Wait until RxNE bit set            */
  return (I2C1->DR);
}


void I2C_Stop (void) {

  I2C1->CR1 |= 0x0200;
  while (I2C_sr() & 0x00020000);        /* Wait until BUSY bit reset          */
}



skara1214

Herkes ölür ama herkes gerçekten yaşamaz

JOKERAS

I2C protokolü basit,kararlı güvenli ve bence çok güzel bir protokol.

I2C Haberleşmenin püf noktaları Start,Ack-Nack ve Stoptur.
I2C Zaman temelli değil,komut temelli çalışan bir cihazdır.
I2C protokolü,Komutanın(ların) Er veya Erleri  ile olan diyaloguna çok benzer.

I2C'de bir veya daha fazla Master olabilir, birden fazla Slave Device ve Adres olabilir.
Device Adresi 7-Bittir.
Device Adresi dendiğinde Slave cihazın üretim aşamasında belirlenmiş olan fiziksel adresidir.
İnternal adres ise,Slave Cihazın iç Adres uzayıdır.


Master tarafından I2C yolunun Data Hattı sıfıra çekilir,sonra peşinden Clock hattına
bir saat darbesinin düşen kenarı geldiğinde I2C yolundaki Tüm Slave'ler bundan etkilenir
ve dinlemeye koyulurlar.

Master önce ilgili Slave Device'ın Fiziksel adresini yollar...

Data --> 0b11111010 .Son 7-Bit Slave'in Fizikzel Device Adresidir.
İlk Bit Okumamı yazmamı yapılacağını belirler.
Data hattından gönderilen her bit,Colck hattının Clock Peryodunun Düşen kenarında
Kabul görür.
Master Data bitlerini gönderdikten sonra Data (SDA) Hattını İddle'a alır.
SDA hattındaki Pull-up direnci SDA Hattını High yapar. 
Slave'in Vereceği Cevabı bekler.Eğerki Slave Device SDA hattını Sıfıra çekmişse,Master
bu sefer Slave Cihaza bir Clock daha yollayarak Slave'in ACK cevabını onaylar.
Bu durum Her bayt gönderdikten sonra tekrar edilir.
Buraya kadar sadece Slave Device'ın fiziksel Adresini yolladık,
Master "Evet, x Adresli Slave Device,seninle muhabbet ederim" dedi.
Bunu duyan diğer Slave Device'lar Mastere küstü:)

---------------------------------------------------------
Master şimdi Slave Device'ın İçsel Adresini Yolluyor,Slave Device Artık kölemiz oldu,
istediğimizi yapar,yaptırırız.

Master ilgili Device'ın İç adresini yolluyor,bu aslında bir Pointerı set etmekten bir
farkı yok!

Örnek vermek gerekirse...
Slave Device'ın 16 Bitlik bir uzaya sahip olduğunu varsayarsak.

uint16_t *ptr = (uint16 *) 0x1ABC;
Burada ptr göstericisi Bellek uzayında 0x1ABC adresini gösteriyor.

Data --> 0x0001 1010 ACK 1011 1100 ACK.
Şimdi bu datayı Slave'in Adres pointerine Önce High,Sonra Low baytı gönderilerek
Slave Pointeri tıpkı ptr göstericisi gibi bir adresi gösterir.
Byte byte gönderme Slave cihazın donanısal yapısındandır, 8-Bit registerleri olduğundan
parça parça gönderilir.Eğerki 16-Bit Registere sahip olsaydı bir hamlede yollardık.
Her bir byte gönderme sonunda Master,Slave'den Ack Cevabı bekler.

Slave Artık set oldu,okumamı yazmamı yapacağımızı Device'ın fiziksel adresini
gönderirken söylemiştik.Yazma yaptığımızı varsayalım.

--------------------------------------------------------------
Şimdi Yazılacak olan Dataları gönderiyoruz...

Data --> 'M', 'U',  'S',  'T',  'A',  'F',  'A'.

Slave'in Adres pointer'ine yazdığımız Adresten başlayarak bu veriyi
Byte Byte yazar.Master Her byte sonunda Slave'den Ack bekler,eğer Slave'den Ack gelmişse
Master,Slave'e bir Clock gönderip onaylar.
Master tarafından Gönderilen her onay Clock'u, Slave'in Adres pointerini bir atttırır.

Veriyi yazdık.
---------------------------------------------------------------
Şimdi Slave'le işimizin bittiğini söylememiz gerekiyor.Nack.
Master her Byte gönderme sonunda ne yapıyordu?
Data hattını İddle'a alıp Slave'in Ack cevabını bekliyordu.
Slave SDA hattını sıfıra çekince Master bir Clock ile Slave'in Ack Cevabını onaylıyordu.

Hah işte,şimdi Master SDA hattını İdle yapmadan Clock Gönderiyor.
Master Slave'e "Yeter artık seninle işim bitti,seni tanımıyorum!" diyerek daha biraz önce
muhabbet ettiği Slave'i tanımamazlıktan gelir.Terbiyesiz:)
Bu NoAck oluyor:)

Master SDA hattında bulunan Slave'lerin tümüne "Hiç birinizle işim olmaz artık,hepinizin taaaa..."
diyerek SDA Hattını High yaparak Stop yapar.Clock'un önemi yok.

Master canı istediği zaman Slave'leri kullanır,istediği zaman kaale bile almaz.Kralın oğlu mubarek:)

Olay bu kadar.



skara1214

Herkes ölür ama herkes gerçekten yaşamaz

mehmet

#10
Çok güzeldi...

İki hat üzerinden birbirinde bağımsız farklı
cihazlara erişmek çok hoş.
Mesela; DS1307, 24L02, PCF8574, MCP23017 ve sht11
ile aynı veri yolu üzerinden haberleşilebilir.
Kötü tarafı çok cihaz ve hız düşük.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

JOKERAS

Alıntı yapılan: skara1214 - 25 Kasım 2016, 14:32:33
mükembel anlatım elinize sağlık
Alıntı yapılan: mehmet - 25 Kasım 2016, 15:44:40
Çok güzeldi...

İki hat üzerinden birbirinde bağımsız farklı
cihazlara erişmek çok hoş.
Mesela; DS1307, 24L02, PCF8574, MCP23017 ve sht11
ile aynı veri yolu üzerinden haberleşilebilir.
Kötü tarafı çok cihaz ve hız düşük.

Teveccühleriniz için Teşekkürler.

Aslında kısa anlatım yaptım,daha farklı atraksyonları var, ama temel olarak bu şekilde.

@mehmet  usta ,aynen öyle, bir hat üzerinden bir çok cihazla haberleşmek ne güzel bir duygu:)
İnsana haz veriyor.

Şöyle bir özelliğide var.
Slave Device adresi aynı olan cihazlarda da kullanlılabiliniyor.
Mesela I2C hattına Aynı Familyadan 5 adet Eeprom bağlanırsa
Her Device'ın adresi aynı olmasına rağmen onları da kontrol edebiliyor.

Evet hız konusunda yavaş,half duplex,ama genelde güvenli kısa yollu sistemlerin haberleşmesinde kullanılıyor.
Çok Güvenli.Bir çok cihaz hala bu protokol ve dolayısı ile  I2C cihazları kullanıyorlar.
SPI hızlı ama Spı cihazlar hem pahalı,hemde her SPI Cihaz için ekstra hat gerekli.

Gelin hep beraber "I2C sevenler Derneği" kuralım:)










Cemre.

Alıntı yapılan: JOKERAS - 25 Kasım 2016, 16:25:25
...
Slave Device adresi aynı olan cihazlarda da kullanlılabiliniyor.
Mesela I2C hattına Aynı Familyadan 5 adet Eeprom bağlanırsa
Her Device'ın adresi aynı olmasına rağmen onları da kontrol edebiliyor.
...

Bu kısmı biraz detaylandırır mısınız hocam? Adres pinleri olan ve adres değişikliğine izin veren slave'lerden mi bahsediyorsunuz? Adres çakışması varsa bus'ta karmaşa çıkmayacak mı?

mehmet

Örnek 24C01 olsun. Üç adet adres biti var
pin olarak.
Kendi adresi de 0b1010xxxA şeklinde;
A -> 1/0 olarak yazma ve okuma kısmını seçiyor.
xxx ler bit olarak 0b000 - 0b111 arasında 8 aygıt
bağlanabileceği anlamına geliyor. Yani;
0b1010000A
...
0b1010111A adres aralığı okunup yazılabilir bu
durumda.

Yani donanım iç adresi aynı olan aynı cins
sekiz e2prom aynı hatta olabilir...
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

JOKERAS

#14
Evet Mehmet usta,Aynen öyle.

Son 4-Bit Familya Adresi,sonraki 3-Bit Device Adresi.
I2C hattına Aynı Aileden 8'er adet cihaz bağlanabiliyor.
8 Adet RTC, 8 Adet Eeprom, 8 Adet Sıcaklık Sensörü vs.

İlgili cihaz ailelerinin Device adresini A0 A1 A2 pinlerinin bağlantı kombinasyonu belirliyor.
Bir ara İnternette görmüştüm, Adres pinlerini  8 farklı şekilde içsel olarak İmalat esnasında
bağlayıp, xChip Numarasnın sonuna 0, 1, 2,...7 gibi numara koyarak Adres numaralarını
bu şekilde halletmişler.Bu sayede Pin sayısını düşürmüşler. +/- Sda-Scl.

Elin Hollandalı'sı yıllar evvel bunu düşünmüş,yapmış.Eferin Kerataya:)
Akıl işi.

Haa şöyle bir durum da varmış,onuda hatırlatayım.
"I2C" logosu ve İsmi Tescil edilmiş,dolayısı ile "I2C" Sembolünü ismini kullanmak Telif hakkına tabiymiş.
Bizler gibi ufak 3-5 proje yapanlar için sorun teşkil etmeyebilir belki,ama Seri üretim
yapanlar Telif hakkı ödemeden bu isim ve Logoyu kullanamıyorlarmış.