400kHZ I2C haberleşme

Başlatan erdtur, 08 Aralık 2013, 10:14:07

erdtur

Merhaba,

benim sorum, PicBasic Pro ile program yazarken I2C üzerinden, 400kHZ haberleşeme için gereken kod.

teşekkürler

ete

I2CWRITE. SDA, SCL, CIHAZKODU, ADRES, [veri1, veri2]

I2CREAD  SDA, SCL, CIHAZKODU, ADRES, [ Veri1, Veri2]

400 khz haberleşme hızı için işlemci frekansı 8 mhz nin üzerinde olmalıdır.
Komut kendisini otomatik ayarlar.

Ete

erdtur

Cevabınız için teşekkürler.

erdtur

Sayın ETE
mpu6050 ile 16F628A arasında I2c ile veri alış verişi yapmaya çalışıyorum.
628A besleme voltajı 3.3V ve osilatör INTRC_OSC_NOCLKOUT  10mHZ ayarlı.

Yalnız, aldığım MPU kartında SDA ve SCL hatlarında 2,2k pull up dirençleri var.
forumlarda 4,7k ile 10k arası olmalıdır diyor.

veri alamıyorum , pull up direnç değerleri doğrumudur? MPU6050 ile ilgili tecrübeniz oldumu.

PicBasic kodu şöyle,

; *** 16f628A DEVICE Fuses Definitions

@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _BODEN_OFF & _MCLRE_OFF & _LVP_OFF & _DATA_CP_OFF

DEFINE OSC 10 '  use for 4MHz


Include "MODEDEFS.BAS" ' Include serial modes

TRISA = %11111111
TRISB = %00000000
PORTA = %00000000
PORTB = %00000000

SO   Con 0             ' Define serial output pin 
DPIN Var PORTA.0       ' I2C data pin 
CPIN Var PORTA.1       ' I2C clock pin
B0   Var byte
B1   Var byte
B2   Var byte

     
   
      DEGER         VAR WORD
      ISARET_T       VAR BYTE
      ISARET_AX       VAR BYTE
      ISARET_AY       VAR BYTE
      ISARET_AZ       VAR BYTE
      ISARET_GX       VAR BYTE
      ISARET_GY       VAR BYTE
      ISARET_GZ       VAR BYTE
     
      ACCX      VAR WORD
      ACCY      VAR WORD
      ACCZ      VAR WORD
      ISI      VAR WORD
      GYRX      VAR WORD
      GYRY      VAR WORD
      GYRZ      VAR WORD
   

'AD0=0 ADDRESS B`1101000X`,$68
'AD0=1 ADDRESS B`1101001X`,$69
I2CWRITE DPIN,CPIN,$68,$1A,[%00000000]  ' 'RESITER 1A CONFIG (FILTER CONFIG)
pause 10
I2CWRITE DPIN,CPIN,$68,$1B,[%00000000]  ' 'RESITER 1B CONFIG (GYRO CONFIG)
pause 10
I2CWRITE DPIN,CPIN,$68,$1C,[%00000000]  ' 'RESITER 1C CONFIG (ACC CONFIG)
pause 10

Mainloop:


OKU:

I2CREAD DPIN, CPIN,$68,$3B,[DEGER]  '
IF DEGER.15 = 1 THEN
DEGER.15=0
DEGER=32767-DEGER
ACCX=DEGER+1
ISARET_AX=11
ELSE
ACCX=DEGER
ISARET_AX=10
ENDIF

IF DEGER.15 = 1 THEN
DEGER.15=0
DEGER=32767-DEGER
ACCY=DEGER+1
ISARET_AY=11
ELSE
ACCY=DEGER
ISARET_AY=10
ENDIF

I2CREAD DPIN, CPIN,$68,$3F,[DEGER]  '
IF DEGER.15 = 1 THEN
DEGER.15=0
DEGER=32767-DEGER
ACCZ=DEGER+1
ISARET_AZ=11
ELSE
ACCZ=DEGER
ISARET_AZ=10
ENDIF

I2CREAD DPIN, CPIN,$68,$41,[DEGER]  '
if deger < 45180 then : ISARET_T=10:ISI=(45180-DEGER)/34
IF DEGER > 45180 THEN :ISARET_T=11:ISI =(DEGER-45180)/34
IF DEGER = 45180 THEN :ISARET_T=12:ISI = 0

I2CREAD DPIN, CPIN,$68,$43,[DEGER]  '
IF DEGER.15 = 1 THEN
DEGER.15=0
DEGER=32767-DEGER
GYRX=DEGER+1
ISARET_GX=11
ELSE
GYRX=DEGER
ISARET_GX=10
ENDIF

I2CREAD DPIN, CPIN,$68,$45,[DEGER]  '
IF DEGER.15 = 1 THEN
DEGER.15=0
DEGER=32767-DEGER
GYRY=DEGER+1
ISARET_GY=11
ELSE
GYRY=DEGER
ISARET_GY=10
ENDIF

I2CREAD DPIN, CPIN,$68,$47,[DEGER]  '
IF DEGER.15 = 1 THEN
DEGER.15=0
DEGER=32767-DEGER
GYRZ=DEGER+1
ISARET_GZ=11
ELSE
GYRZ=DEGER
ISARET_GZ=10
ENDIF


Goto mainloop

burdan sonrası LCD ye gönderme


END






ete

2 tane kusur var.
Birincisi 16F628 de A portu ilk açılışta komparatör olarak açılır. Portu digital yapmak zorundasın. Bunun için  CMCON=7  komutunu programın  baş kısımlarına bir yere yaz.

ikincisi Device Adres genellikle 7 bit olarak verilir.  Buda pek çok kişinin kafasını karıştırır. 7 bit verilmesinin bir sebebi var elbette. İlk bit yazma işleminde sıfır, okuma işleminde 1 olmalıdır. Bu standart kaidedir. Bu nedenla ilk biti vermezler ve yalnızca geri kalan 7 biti verirler.  Basic ilk bitin ne zaman sıfır ne zaman 1 olacağını kendisi otomatik halleder. Şimdi gelelim yanlışlığa.  Gerçek device numarası %1101000x  şeklinde tanımlanmış. Burada yer alan x sözünü ettiğim ilk bit dir. Bunu çıksrtırsan 7 bitlik hali $68 dir. Ama sen onu 8 bit yazmak zorundasın yani %11010000 şeklinde. Peki bu sayının hex karşılığı nedir ?  Elbette $D0 dır.
O halde sen device adres olarak $68 değil $D0 kullanman gerekir.

Ete

erdtur

Sayın ETE ,

Bahsettiğiniz düzeltmeleri yaptım, ancak yine haberleşme olmadı.
İlk denememde 16f628'i 5Volt ile beslemiştim ve portları direkt MPU6050 nin SCL ve SDA portlarına bağlamıştım. Bundan dolayı MPU6050 nin portlarının bozulmuş olduğunu düşünüyorum. yenisini sipariş ettim. yenisi gelince son durumu bildireceğim.

Birde, MPU6050 den veri okumak için, aşağıdaki gibi bir protokol takip etmek gerekiyor. Acaba PicBasic de yazdığımız I2CREAD DPIN, CPIN,$68,$3B,[DEGER] komut satırı bu protokulu sağlıyormu?




 

ete

Hala $68 yazıyorsun o $D0 olacak.
Ayrıca dğer rakam nedir bilemiyorum. Normalde cihaz kodundan sonra register adresi gelir. Şayet $3B bir komut yani bir iş yaptırıyor ise adres sıfır verilmeli ve köşeli parantez içine $3B yazılmalıdır.
Ete

erdtur

$68 bu yazıdan alıntı yaptığım için öyle yanlışlık olmuş kusura bakmayın , denemelerinde $D0 olarak kullandım.

I2CREAD DPIN, CPIN,$D0,$3B,[DEGER]

Yukarıdaki ifadede,  $D0; MPU6050 nin I2C bus üzerindeki node adresi, $3B ise MPU6050 içerisindeki okumak istediğim verinin bulunduğu registerin adresi.

I2CREAD komutunun tam olarak nasıl çalıştığını bilmediğim için soruyorum, aşağıdaki gibi yapıyormu ?
Start şartlarını sağlıyor ,$D0 gönderiyor , ACK bekliyor , $3Bgönderiyor , ACK bekliyor ,start şartlarını sağlıyor, $D0 gönderiyor, ACK bekliyor ,Data bekliyor, ACK gönderiyor, Data bekliyor, NACK gönderiyor, Stop şartlarını sağlıyor ve gelen 16 bitlik veriyi DEGER Wordunun içine yazıyor.

eğer bu şekilde yapmıyorsa farlı şekildemi? okumak gerekir.

ete

Benzer şekilde davranıyor. Önce device adres ve register adresini yazıyor. Aralarda ACK leri alıyor ve sonra okumayı yapıyor. Okuma yaparken device adres D1 olarak uygulanıyor.
Standart I2C neyse onu uygular.
Ete

erdtur

400kHZ haberleşmesini sağladım.
problem chip'i sleep moddan çıkarmak gerekiyormuş.
onu yapınca veriler gelmeye başladı.

Gelen veriler mm/s2 cinsinden ivmeyi gösteriyor.
ben vibrasyon ölçmek istiyorum mm/s cinsinden.
ivmeden vibrasyon nasıl hesaplanabilir?   

ete

Vibrasyon hesabı diye bir şey duymadım. Vibrasyon titreşim demektir. Bunun hesabı nasıl olabilir gerçekten bilemiyorum.
Ete

Mucit23

ivme ölçerlerle endüstride titreşim ölçümü yapılıyor. Bildiğim kadarıyla Asenkron motorlarda rulman arızası vs gibi arızalar tespit ediliyor.

Örnek bir şema

Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

musa

Alıntı yapılan: erdtur - 16 Ocak 2014, 15:25:47
400kHZ haberleşmesini sağladım.
problem chip'i sleep moddan çıkarmak gerekiyormuş.
onu yapınca veriler gelmeye başladı.

Gelen veriler mm/s2 cinsinden ivmeyi gösteriyor.
ben vibrasyon ölçmek istiyorum mm/s cinsinden.
ivmeden vibrasyon nasıl hesaplanabilir?

sayın erdtur 6050 yi  uyku modundan nasıl uyandırdın kodu paylaşman mümkünmü teşekkürler

ete

Bu arada başlarda verilen kod ile açıklamalar arasında bir tutarsızlık olduğunu yeni fark ediyorum.
Arkadaş,
@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _BODEN_OFF & _MCLRE_OFF & _LVP_OFF & _DATA_CP_OFF

DEFINE OSC 10 '  use for 4MHz

şeklinde bir kod kulanmış. Sanırım oraya Define OSC 10 yazınca işlemcinin dahili OSC ile 10 Mhz de çalışacağını düşünüyor.
Bu yanlış. 16F628 ve 16F628A da dahili OSC 4 Mhz dir bu nedenle işlemciyi 10 Mhz de çalıştırmak için Rezonatör yada kristal kullanmak gerekir.

10 Mhz Kristal yada rezonatör kullanınca INTRC_OSC_NOCLKOUT komutu yerine HS_OSC yazılması gerekir.
Ama illaki dahili OSC kullanılacak ise o zamanda oraya Define OSC 4 yazmak gerekir.

Ete

erdtur

Merhaba Musa bey,

programınızda en üst bölüme aşağıdaki satırları eklerseniz çalışır. Tabi siz I2CWRITE komutunu kendi devrenize ve programınıza göre düzenleyin. 

I2CWRITE DPIN,CPIN,$D0,$6B,[%10000000]  ' 'RESITER 6B CONFIG (PWR MANAGEMENT)  MPU5060 bu satırda resetleniyor
pause 1000
I2CWRITE DPIN,CPIN,$D0,$6B,[%00100000]  ' 'RESITER 6B CONFIG (PWR MANAGEMENT)  MPU 5060 bu satırda çalışmaya başlıyor

Kolaygelsin
erdtur

Powered by EzPortal