avatar_sonmoikan

I2C Eeprom Sorunu Hakkında

Başlatan sonmoikan, 11 Kasım 2014, 09:33:51

sonmoikan

Erol Hocam,  i2c kullanımında bir sorun yaşıyorum.
Yapmış olduğum kodda 24LC01B ye yazma ve okumada bir sorun olmuyor.
Fakat 24LC ve 24C serisi Eepromlara kayıt veya yazmada sorun yaşıyorum. Ya kaydetmiyor yada yanlış okuyor.
24LC serisinde ne yazarsam yazıyım hep, Byte ise 255, Word ise 65535 olarak okuyor.

Bu sorun hakkında yardımlarınızı bekliyorum.
ABDULLAH

ete

Eprom kullanırken dikkat edilecek en önemli nokta epromun hafıza kapasitesidir.
Bir eprom 256 adet 8bitlik lık bir hafızaya sahip ise adresleme yalınza 0-255 arasında yapılmalıdır.
Bir başka eprom da şayet 256 adet den fazla byte kapasite var ise adresleme byte cinsinden yapılamaz.
Örnek vereyim 32K lık bir eprom (32768 kbit veya başka bir deyişle 4096 byte adresi demektir) da adreslemeyi 0-255 arası yapamazsınız. 0-4095 arasında yapmanız gerekir. Kapasite bunu gerektiriyor. Bu durumda adres 16 bitlik olmalıdır.
Sen ne yapmışsın küçük hafızlaı epromda da 8 bitlik adres, büyük hafızalıda da 8 bitlik adres kullanmışsın.
Çalışmayan epromlarda adres değişkenini WORD olarak değiştir ve adres verirken;
I2CWRITE DPIN,CPIN,KONT,ADRS.BYTE1,ADRS.BYTE0,[E_yaz]
şeklinde verirsen çalıştıklarını göreceksin.
ADres Highbyte önce ve sonra Adres Lowbyte veriliyor.

Ete

sonmoikan

Teşekkür ederim Erol Hocam anladım.
Sizde olmasanız ne yapardık bilmiyorum.
ABDULLAH

Dtmf

Iyı aksamlar ete hocam elımde bır kac tane 24c32 eeprom var bunlarla ılgılı daha once calısmam hıc olmadı sımdı kullanmak ıstedım bı kac yerde kullanacagım.24c32 ıle ılgılı bıraz arastırma yaptım asagıdakı basıt kısa bır deneme programı yazdım.hocam vaktınızı harcıyorum duzeltmem gereken yerler varmı sızın bılgınıze tecrubenıze sundum.dogrumu anladım bılmıyorum her adres 16 bıt,A0 A1 VE A2 pınlerı fazaladan eklenecek eeprom entegrelerın adreslemesınde kullanılıyor.
hocam bıde cozemedıgım 1.toplamda kac adresleme yapabılırım 2.bır yazınızda 8x256 24lc02 ıcın toplamda max adres 256 olamsına ragmen blok secılerek 2048 byte kullanılmakta yazmıssınız.
Device=16F877A
Xtal=4
All_Digital TRUE
TRISA=0:PORTA=0
TRISB=0:PORTB=0
TRISC=0:PORTC=0
TRISD=0:PORTD=0
Declare LCD_Type         0   ' Standart 2x16 LCD
Declare LCD_DTPin  PORTB.4	' DATA girişi PORTB'nin B0 ucundan başlayacak
Declare LCD_ENPin  PORTB.0   ' Enable (EN) pini E2
Declare LCD_RSPin  PORTB.1   ' Register Select (RS) pini B4
Declare LCD_Interface    4   ' 4 bit LCD arayüzü
Declare LCD_Lines  4;      2	' 2 satırlık LCD
Dim VERI As Byte
Dim ADRS As Word ;ADRESSS WORD TIPI
Dim OKU As Word

Dim AL1 As Byte
Dim AL2 As Byte
Symbol DPIN=PORTD.1
Symbol CLK=PORTD.0
ADRS=0
;============================
BASLA:
Print At 1,1,"24C32 EEPROM OKUMA "
        BusOut $A0,ADRS,[4]
        DelayMS 25   ;EEPROMA YAZMAN ICIN SURE
        BusIn $A0,ADRS,[OKU] ;OKUNACAK DEGER BAYT DEGERINDE  255 DENDUSUK  DEGISKEN BAYT OLARAK TANIMLANIR WORDSE WORD OLARAK TANIMLANIR
        
       AL1=OKU.HighByte 
       AL2=OKU.LowByte 
        Print At 2,1,"HIGH BYTE:",Dec AL1
        Print At 3,1,"LOW BYTE:",Dec AL2
        Print At 4,1,"HAM:",Dec OKU
        DelayMS 200
GoTo BASLA	

ete

Her şey data sheet lerde yazıyor. Bende oraya bakıp öğreniyorum neler olduğunu.
4x8=32 Kbit yada 4 KByte lık bir eprom. Bu durumda 4*1024=4.096 adet adres kullanabilirsin anlamına geliyor.
Kısaca 4096 adet 8bitlik hafıza bu alet. Adres değeri 16 bitlik olduğu için bu epromda 16 bitlik adres kullanmak gerekiyor.
A0-A1 ve A2 pinlerine verilecek lojik değer ile birden fazla eprom Max 7 adet daha (7+1=8) aynı data ve clok hattınabağlanabilir.
Eprom seçme işi A0-A1 ve A2 pinleri yardımı ile olur. Örnek vermek gerekirse;
Control=%1010 000x  birinci epromu adresler  (Tek eprom kullanma şekli)
Control=%1010 001x  ikinci epromu adresler   (İki eprom kullanma şekli)
Control=%1010 010x  üçüncü epromu adresler
control=%1010 011x  dördüncü epromu adresler
Control=%1010 100x  beşinci epromu adresler
Control=%1010 101x  altıncı epromu adresler
Control=%1010 110x  yedinci epromu adresler
Control=%1010 111x  sekizinci epromu adresler (sekiz eprom kullanma şekli)
Tek eprom kullanılacağı zaman A0-A1 ve A2 bacaklarının GND ye bağlanması gerekir.

Ete


Dtmf

Ete hocam tesekkur ederim dediginiz gibi ben zaten a0 a1... bacaklari gnd bagladim calistirdim eepromu
Aklima takilan bi kac yer vardi sizde aydinlattiniz acabami sorusu kalkti sagolun hocam selametle.

Dtmf

hocam for dongusu ıle 10 adet adrese 50 verısını yazdırıp sonra busın komutu ıle 10 adres ıcınden harhangı bır adresten bırını okumak ıstıyorum ama bırturlu olamdı nerede hata yapıyorum ardımcı olurmusunuz

Device=16F877A
Xtal=20
All_Digital TRUE
TRISA=0:PORTA=0
TRISB=0:PORTB=0
TRISC=0:PORTC=0
TRISD=0:PORTD=0
Declare LCD_Type         0   ' Standart 2x16 LCD
Declare LCD_DTPin  PORTB.4	' DATA girişi PORTB'nin B0 ucundan başlayacak
Declare LCD_ENPin  PORTB.0   ' Enable (EN) pini E2
Declare LCD_RSPin  PORTB.1   ' Register Select (RS) pini B4
Declare LCD_Interface    4   ' 4 bit LCD arayüzü
Declare LCD_Lines  4;      2	' 2 satırlık LCD
Dim VERI As Word
Dim ADRS As Word ;ADRESSS WORD TIPI
Dim OKU As Word
Dim X As Byte
Dim ADS As Word

Dim AL1 As Byte
Dim AL2 As Byte
Symbol DPIN=PORTD.1
Symbol CLK=PORTD.0
;============================
BASLA:
Print At 1,1,"24C32 EEPROM OKUMA "
VERI=50
ADRS=1

For X=0 To 10
BusOut $A0,ADRS,[VERI.HighByte,VERI.LowByte]
DelayMS 250   ;EEPROMA YAZMAN ICIN SURE
ADRS=ADRS+1
Print At 2,1,Dec VERI
Print At 3,1,Dec X
Next 

Cls
DelayMS 500
ADS=2
        
        BusIn $A0,ADS,[OKU] ;OKUNACAK DEGER BAYT DEGERINDE  255 DENDUSUK  DEGISKEN BAYT OLARAK TANIMLANIR WORDSE WORD OLARAK TANIMLANIR
       AL1=OKU.HighByte 
       AL2=OKU.LowByte 
        Print At 2,1,"HIGH BYTE:",Dec AL1
        Print At 3,1,"LOW BYTE:",Dec AL2
        Print At 4,1,"HAM:",Dec OKU
        DelayMS 2000
GoTo BASLA	

ete

#7
Sen öyle yapma. 0 dan başlayarak 10 adrese 50+Adres verisini yazdır. Veri Byte olsun.
Böylece 0. nolu adrese 50, 1 nolu adrese 51, 2 nolu adrese 52 ... 9 nolu adrese ise 59 bilgisini yazdır.

Sonra bunları sırası ile oku bakalım yazdıklarını okuyabilecekmisin.
Daha byte işini çözmemiş iken neden Word yazdırmak peşindesin?. Byte yazıp byte oku bakalım sonra adım adım diğerlerine geçersin.

Yazdırma işini ben yapayım. Okuma işinide sen yap bakalım.
VERI=50'veri byte cinsinden olacak
ADRS=0

For X=0 To 10
VERI=VERI+X
BusOut $A0,(ADRS+X),[VERI]
Print At 2,1,Dec X,"-",dec VERI
DelayMS 250  ;EEPROMA YAZMAN ICIN SURE
Next 
Ete

Dtmf

ete hocam dedıgınız gıbı yazma programın yazma kısmını ekledım ısıs de denıyorum verı ekranda 51.52.53.. dıye gıdıyor fakat adres 51.53.56.60 dıye gıdıyor okumayıda byte yazma yaptım dıye yıne byte tıpı degıskenle okuma patım ekranda 65 yazıyor sureklı
Device=16F877A
Xtal=20
All_Digital TRUE
TRISA=0:PORTA=0
TRISB=0:PORTB=0
TRISC=0:PORTC=0
TRISD=0:PORTD=0
Declare LCD_Type        0  ' Standart 2x16 LCD
Declare LCD_DTPin  PORTB.4 ' DATA girişi PORTB'nin B0 ucundan başlayacak
Declare LCD_ENPin  PORTB.1  ' Enable (EN) pini E2
Declare LCD_RSPin  PORTB.0  ' Register Select (RS) pini B4
Declare LCD_Interface    4  ' 4 bit LCD arayüzü
Declare LCD_Lines  4;      2 ' 2 satırlık LCD
Dim VERI As Byte
Dim ADRS As Word ;ADRESSS WORD TIPI
Dim OKU As Byte
Dim X As Byte
Symbol SDA=PORTC.6
Symbol SCL=PORTC.7
;============================
BASLA:
Print At 1,1,"24C32 EPROM OKUMA "
VERI=50
ADRS=0
        For X=0 To 10  ;0-10 ADRESE YAZ
        VERI=VERI+X
        I2COut SDA,SCL,$A0,(ADRS+X),[VERI]
        DelayMS 250
        Print At 2,1,Dec X,"-",Dec VERI
        DelayMS 500
        Next
        
ADRS=0 ;BUSIN ADRS=0 DAN BASLAYARAK OKUYACAK

        For X=0 To 10      ;0-10 ADRES OKU
        I2CIn SDA,SCL,$A0,ADRS,[OKU] 
        DelayMS 250
        Print At 4,1,"OKU:",Dec OKU
        Next
        DelayMS 500
 Cls

        
GoTo BASLA

Dtmf

ete hocam asagıdakı program daha once yapmıstım guzel calısıyor 24lc02 ıcınsımdı ısı de sımule edıyorum gayette guzel calısıyor ama 24lc32 ıcın adrresı word yapmama ragmen tık yok
Device=16F877A
Xtal=20
All_Digital TRUE
TRISA=0:PORTA=0
TRISB=0:PORTB=0
TRISC=0:PORTC=0
TRISD=0:PORTD=0
Declare LCD_Type         0   ' Standart 2x16 LCD
Declare LCD_DTPin  PORTB.4	' DATA girişi PORTB'nin B0 ucundan başlayacak
Declare LCD_ENPin  PORTB.1   ' Enable (EN) pini E2
Declare LCD_RSPin  PORTB.0   ' Register Select (RS) pini B4
Declare LCD_Interface    4   ' 4 bit LCD arayüzü
Declare LCD_Lines  4;      2	' 2 satırlık LCD
Dim VERI As Byte
Dim X As Byte
Dim ADRS As Byte
Dim SAY As Byte
VERI=$55
Dim CONT As Byte
Dim OKU As Byte
CONT=$A0
Symbol DPIN=PORTD.1
Symbol CLK=PORTD.0
Dim SATIR As Byte
Dim ADR As Byte
ADR=0
;============================
BASLA:
Print At 1,1,"24LC01 OKUMA "
        For OKU=0 To 10
        ADR=ADR+1
        I2COut DPIN,CLK,$A0,ADR,[OKU]
        DelayMS 10
        Print At 2,SATIR,"OKU:",Dec OKU
        DelayMS 200
        Next
        
ADR=0        
For X=0 To 10
 ADR=ADR+1
I2CIn DPIN,CLK,$A0,ADR,[SAY]
DelayMS 10
Print At 3,1,"YAZ:",Dec SAY
DelayMS 500
Next
Cls


GoTo BASLA	

Dtmf

ete hocam bu sekılde yaptım oldu 24lc32  ye byte olarak yazdırıp okudum.word olarak yazmaya calısıyorum karmakarısık sayılar cıkıyor.
Device=16F877A
Xtal=20
All_Digital TRUE
TRISA=0:PORTA=0
TRISB=0:PORTB=0
TRISC=0:PORTC=0
TRISD=3:PORTD=0
Declare LCD_Type         0   ' Standart 2x16 LCD
Declare LCD_DTPin  PORTB.4	' DATA girişi PORTB'nin B0 ucundan başlayacak
Declare LCD_ENPin  PORTB.1   ' Enable (EN) pini E2
Declare LCD_RSPin  PORTB.0   ' Register Select (RS) pini B4
Declare LCD_Interface    4   ' 4 bit LCD arayüzü
Declare LCD_Lines  4;      2	' 2 satırlık LCD
Dim VERI As Byte
Dim VERI1 As Byte

Dim ADRS As Word ;ADRESSS WORD TIPI
Dim ADRS1 As Word ;ADRESSS WORD TIPI
Dim OKU As Word
Dim X As Word
Dim AL1 As Byte
Dim AL2 As Byte
Symbol DPIN=PORTD.1
Symbol CLK=PORTD.0
ADRS=0
;============================
BASLA:
For X=0 To 20
Print At 1,1,"24C32 EEPROM OKUMA "
        ADRS=ADRS+1
        VERI=VERI+2
        
        I2COut DPIN,CLK,$A0,ADRS,[VERI]
        DelayMS 25   ;EEPROMA YAZMAN ICIN SURE
        GoSub EKRAN
Next
DelayMS 500
ADRS=0
Cls

         For X=0 To 20
        DelayMS 25   
        I2CIn DPIN,CLK,$A0,ADRS,[OKU] ;OKUNACAK DEGER BAYT DEGERINDE  255 DENDUSUK  DEGISKEN BAYT OLARAK TANIMLANIR WORDSE WORD OLARAK TANIMLANIR
        DelayMS 25
        ADRS=ADRS+1
        GoSub EKRAN
        DelayMS 200
        Next
        
DelayMS 500
Cls
ADRS=0
VERI=0
GoTo BASLA 
EKRAN:
 AL1=OKU.HighByte 
        Print At 2,1,"VERI",Dec VERI
        Print At 3,1,"ADRS:",Dec ADRS
        Print At 4,1,"OKU:",Dec AL1
        DelayMS 500
Return

Dtmf

#11
ete hocam word boyutlu verıyı soyle yaptım ıkı adet al1 ve al2 adlı ıkı adet byte boyutlu degıskenı
 I2C SDA.SCL....[AL1 VE AL2]
olarak gonderdım kaydettım sonra okurken yıne ıkı OKU1 VE OKU2 adlı ıkı adet byteboyutlu degıskenle
For X=0 To 9
        DelayMS 500  
        I2CIn DPIN,CLK,$A0,ADRS,[OKU1] ;OKUNACAK DEGER BAYT DEGERINDE  255 DENDUSUK  DEGISKEN BAYT OLARAK TANIMLANIR WORDSE WORD OLARAK TANIMLANIR
        DelayMS 50  
        I2CIn DPIN,CLK,$A0,ADRS,[OKU2] ;OKUNACAK DEGER BAYT DEGERINDE  255 DENDUSUK  DEGISKEN BAYT OLARAK TANIMLANIR WORDSE WORD OLARAK TANIMLANIR
        DelayMS 50
         GoSub EKRAN
        ADRS=ADRS+1
        DelayMS 200
        Next


1014

ete

Kullandığın epromlar 8 bitliktir. Bir hafıza hücresine ancak ve ancak BYTE kayıt edilebilir. WORD için 2 adet ardışık hafıza kullanılır. Önce daima büyük byte (HIGH_Byte) ardından küçük byte (LOW_BYte) kayıt edilir. Okurken de bu sıraya dikkat edilirse hiç sorun kalmaz. Ama okurken önce LOW byte'ı okursan yerler değişir ve sayı yazıldığı gibi okunmaz işler karışır. Öyle yaptığın gibi iki ayrı parça halinde yazıp okumak da gerekmiyor aslında. Ama öğreniyorsun bu şekilde yap sen. SOnunda mantığını çalıştırıp doğru yolu bulursun.

Yazdıklarına çok dikkat et. KOmut formatlarına ne verip ne almak istediklerine çok dikkat et. Aksi halde kod seni uğraştırır.

Örnek vereyim; Biriki mesaj öncesi şunları yazmışsın ve sorun olarak da sürekli 65 veriyor diyorsun. Bak yazarken ne yazmışsın (önerime uygun olarak)
 For X=0 To 10  ;0-10 ADRESE YAZ
        VERI=VERI+X
        I2COut SDA,SCL,$A0,(ADRS+X),[VERI]
        DelayMS 250
        Print At 2,1,Dec X,"-",Dec VERI
        DelayMS 500
        Next
Burada (ADRS+X) ifadesinin amacı nedir? döngü değişkeni olan X her çevrimde değeri bir artarak döngüyü tamamlıyor. Bunu ADRS değişkenine ekleyerek eprom yazma adresinide her seferinde artırımış oluyoruz.
Burada sorun yok. değerleri ilgli adreslere yazdırıyor. Bu örneği zaten ben vermiştim. Okuma kısmınıda sen yaz demeiştim. Peki sen ne yazmışsın?
 For X=0 To 10      ;0-10 ADRES OKU
        I2CIn SDA,SCL,$A0,ADRS,[OKU] 
        DelayMS 250
        Print At 4,1,"OKU:",Dec OKU
        Next
Okuma komutundaki adrese bir bak bakalım oraya direk ADRS yazmışsın. Peki ADRS hiç değişirmi bu şekilde yazarsan? değişmez elbette. Onu değiştirecek bir şey eklememişsin. Bu durumda 11 defa aynı adresten okuma yapmış olursun oda tek bir sayıdır 11 defa okusanda hiç o sayı değişmeyecektir.
BU nedenle yazdıklarına dikkat et diyorum. SÜrekli başka kodlara atıf yapıp bu doğru çalışıyor bunda tık yok demek yerine mantığını çalıştırıp oradan tık çıkartmalısın. Örnek kodları yol gösterici olarak kullanabilirsin ortam değişebilir. Her ortamın kendine göre şartları vardır onlarda değişir bunları değerlendir.

Ete



Dtmf

ete hocam ben 0.adrese word boyutunda bır degısken yazabılırmıyım bunu anlayım bı.tamam byte olarak yazıp okuyabıldım word de sıkıntı yasıyorum su an.yazmıssınız hıghbyte low byte olarak yazıp okursan sorun cıkmaz asagıdakı programda sızındedıgınız gıbı yaptım ama sonuc alamadım

Device=16F877A
Xtal=20
All_Digital TRUE
TRISA=0:PORTA=0
TRISB=0:PORTB=0
TRISC=0:PORTC=0
TRISD=0:PORTD=0
Declare LCD_Type         0   ' Standart 2x16 LCD
Declare LCD_DTPin  PORTB.4	' DATA girişi PORTB'nin B0 ucundan başlayacak
Declare LCD_ENPin  PORTB.1   ' Enable (EN) pini E2
Declare LCD_RSPin  PORTB.0   ' Register Select (RS) pini B4
Declare LCD_Interface    4   ' 4 bit LCD arayüzü
Declare LCD_Lines  4;      2	' 2 satırlık LCD
Dim VERI As Word
Dim VERI1 As Byte

Dim YAZ As Word
Dim OKU As Word

Dim AL1 As Byte
Dim AL2 As Byte
 
Dim ADRS As Word ;ADRESSS WORD TIPI
Dim SAY As Byte
Symbol DPIN=PORTD.1
Symbol CLK=PORTD.0
ADRS=0
YAZ=1453
;============================
BASLA:
DelayMS 500
Print At 1,1,"24C32 EEPROM OKUMA "

For SAY=0 To 9       
ADRS=ADRS+1
YAZ=YAZ+1
DelayMS 20
I2COut DPIN,CLK,$A0,ADRS,[YAZ.HighByte,YAZ.LowByte]
DelayMS 25
GoSub EKRAN
Next

DelayMS 500
ADRS=0 ;okumayı ADRES 0 DAN BASLAMASI ICIN SIFIRLADIM
OKU=0

For SAY=0 To 9
ADRS=ADRS+1
I2CIn DPIN,CLK,$A0,ADRS,[OKU.HighByte,OKU.LowByte]
DelayMS 25
GoSub EKRAN
Next

DelayMS 500
ADRS=0
YAZ=1453
Cls
GoTo BASLA 
;=========================================================
EKRAN:
Print At 2,1,"YAZ:",Dec YAZ
Print At 3,1,"OKU H/L:",Dec OKU.HighByte,OKU.LowByte
DelayMS 500
Return

Dtmf

hocam bakın asagıdakı ornekte zamanlamaları uzuntutarak once yazdırdım 1000ms sonra okudum word yazıp okuyabılıyorum anlamadıgım bunu for next dongusuıle yazdırıp sonrada for next dongusu ıle ıstedıgım adresı neden okuyamıyorum cok garıp
Device=16F877A
Xtal=20
All_Digital TRUE
TRISA=0:PORTA=0
TRISB=0:PORTB=0
TRISC=0:PORTC=0
TRISD=0:PORTD=0
Declare LCD_Type         0   ' Standart 2x16 LCD
Declare LCD_DTPin  PORTB.4	' DATA girişi PORTB'nin B0 ucundan başlayacak
Declare LCD_ENPin  PORTB.1   ' Enable (EN) pini E2
Declare LCD_RSPin  PORTB.0   ' Register Select (RS) pini B4
Declare LCD_Interface    4   ' 4 bit LCD arayüzü
Declare LCD_Lines  4;      2	' 2 satırlık LCD

Dim ADRS As Word ;ADRESSS WORD TIPI

Dim YAZ As Word
Dim OKU As Word

Symbol DPIN=PORTD.1
Symbol CLK=PORTD.0
ADRS=0
YAZ=1453
;============================
BASLA:
DelayMS 500
Print At 1,1,"24C32 EEPROM OKUMA "
Inc YAZ
I2COut DPIN,CLK,$A0,ADRS,[YAZ]
DelayMS 500
GoSub EKRAN
DelayMS 500
I2CIn DPIN,CLK,$A0,ADRS,[OKU]
GoSub EKRAN
DelayMS 400
ADRS=ADRS+1


GoTo BASLA 
;=========================================================
EKRAN:
Print At 2,1,"YAZ:",Dec YAZ
Print At 3,1,"OKU:",Dec OKU
Print At 4,1,"ADRS:",Dec ADRS
DelayMS 500
Return

Powered by EzPortal