avatar_Mucit23

I2C Eeprom Veri yazma sorunu

Başlatan Mucit23, 15 Kasım 2011, 21:38:28

Mucit23

Hocam Herhalde sizde bir çözümünü bulamadınız. Bende çok araştırdım dediğim şekilde olmuyor. Farklı yöntemlerle yapılabilir fakat oda hızı düşürmekten başka bir işe yaramıyor.
Ben Dahili SPI komutlarla işi çözmeye çalışacam.
Datasheed te şöyle bir resim var. Önceki mesajımdada vermiştim.
1 byte veri yazmak için Gerekli clock sayısını gösteriyor

gif image hosting

1 bytelık veri göndermek için aşağıdaki gibi komut gönderiyorum. Osiloskopla çıkan datalara bakıyorum düzgün.
SHOut DO,SCK,msbfirst_l,[KONT, ADRS\16, ADDR]
Buradaki kont Değişkeni INSTRUCTiON bilgisini, ADRS değişkeni eprom adresini ve ADDR değişkeni ise yazılan datayı temsil ediyor. osiloskopla baktığımda bu veriler arasında nerden baksan bi 30uS kadar bekleme oluşuyor. Yani yukarıdaki resimdeki gibi peşi peşine gönderilmiyor. İlk Başta Kontgönderiliyor, 20-30 uSbekleyip ADRS gönderiliyor yine 20-30 us bekleyip ADDR gönderiliyor. Bu durum neden böyle.
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

ete

#31
Bulamadım değil uğraşmadığım bir konu. I2C sisteminde acknowledge denilen bir olay vardır. Yollayan bir bilgiyi yollar alıcı aldığına dair onay verir. Shiftout komutları ile bu işi yaparsan bunları atlamış olursun.  Bu nedenle çokda önermiyorum ama başlangıç komutlarını I2C ile ver (kontrol ve adres bitlerini) daha sonra shiftout ile de data ları peşi sıra dizersin.

Bahsini ettiğin beklemeler ACK onayıdır. Verici data hattına bilgiyi verir ve verme bitince data hattını giriş yapar ve alıcı hattı LOW a çeker. Bunun  anlamı aldım demek oluyor. Verici hattın LOW olduğunu görür görmez tekrar hatto çıkış yapar ve ilave vereceklerini veriri. Epeyce bir protokol mevcut bu işte.

Ete

Mucit23

Anladım hocam. Ben bugün bir iki deneme yapacağım. Eğer basit bir veriyi yazıp okuyabilirsem düzgün bir şekilde okuyabilmem gerekiyor. Ondan sonra Resim dataları için çalışmalarıma başlıyacağım.
Eğer şu Page Write ve Page Read işlemi I2C eepromlarda gözle görülür bir fark yaratıcaksa bu eepromlarla uğraşmama gerek kalmayacak. Bunu denedikten sonra  I2C eepromlara tekrar bakıcam.
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

Mucit23

#33
Hocam biraz uğraştım durum pekte iyi görünmüyor. Moralim sıfır.
Veri yazıp okumak için aşağıdaki gibi bir program hazırladım. Biraz sini 9. dersinize bakarak hazırlamaya çalıştım. Aynı görünüyor. Sadece İNstruction komutları farklı. Onlarda Datasheedinde açıklanmış. Ben herşeyi datasheede göre yapmaya çalışıyorum ama yinede bir yerlerde hata yapıyorumki çalışmıyor.
İlk Deneme programım aşağıdaki gibi. Protonda denemelerimi yapıyorum. SPI komutları Pic basicle aynı.
Device 18F452

Config_Start
   OSC = HS ; HS osc
   OSCS = OFF ; Disabled
   PWRT = On ; Enabled
   BOR = OFF ; Disabled
   WDT = OFF ; Disabled
   STVR = OFF ; Disabled
   LVP = OFF ; Disabled
   Debug = OFF ; Disabled
Config_End

Xtal 20

TRISA=%00000000
TRISB=%00000000
TRISC=%01000000
TRISD=%00000000
TRISE=%00000000

PORTA=0:PORTB=0
PORTC=0:PORTD=0
    PORTE=0

PORTB.5=1                          'GLCD RESET=1
All_Digital= TRUE                  'ADC PORTLARININ TAMAMI DİJİTAL GİRİŞ VEYA ÇIKIŞ
LCD_DTPort = PORTD                 'GLCD DATA PORTLARI PORTD'YE BAĞLI
LCD_RSPin = PORTB.0                'GLCD RS PİNİ PORTB.0 BAĞLI
LCD_ENPin = PORTB.2                'GLCD ENABLE PİNİ PORTB.2 BAĞLI
LCD_RWPin = PORTB.1                'GLCD RW PİNİ PORTB.1 BAĞLI
LCD_CS1Pin = PORTB.4               'GLCD CS1 PİNİ PORTB.4 BAĞLI
LCD_CS2Pin = PORTB.3               'GLCD CS2 PİNİ PORTB.3 BAĞLI
LCD_Type =  Samsung                'GLCD TİPİ GRAFİK KS0108 128*64B WİNSTAR
Declare Internal_Font = On
Declare Font_Addr = 0
Declare GLCD_STROBE_DELAY = 5
;GLCD_EXTERNAL_PRINT = PPRINT

    Symbol CS =PORTC.0
    Symbol SCK=PORTC.2
    Symbol DO =PORTC.4
    Symbol DI =PORTC.6

Dim ADDR     As Word
Dim ADRS     As Word
Dim YPOS     As Byte
Dim XPOS     As Byte
Dim CHAR     As Byte
Dim KONT     As Byte
Dim RESIM    As Byte
Dim X        As Byte
Dim WREN     As Byte
Dim EEWRT    As Byte
Dim EERAD    As Byte
WREN=%00000110
EEWRT=%00000010
EERAD=%00000011
GoSub EE_INIT
Cls
Print At 1,1,"LUTFEN BEKLEYiNiZ"
Print At 2,1,"KAYDEDiliYOR..."
DelayMS 100
ADRS=0:ADDR=$FE:YPOS=$EE
BASLA:
GoSub E_WRITE:GoSub E_READ
Print At 3,1,"YAZILAN=$",Hex2 ADDR
Print At 4,1,"OKUNAN=$",Hex2 CHAR
Stop

E_WRITE:
CS=0
  SHOut DO,SCK,msbfirst_l,[WREN]  ;WRİTE ENABLE
CS=1
CS=0
  SHOut DO,SCK,msbfirst_l,[EEWRT,ADRS\16,ADDR]
CS=1
Return

E_READ:
CS=0
  SHOut DO,SCK,msbfirst_l,[EERAD,ADRS\16]
  SHIn  DO,SCK,msbpre_l,[CHAR]
CS=1
Return

EE_INIT:
CS=0:DO=1:SCK=1
CS=1:SCK=0
Return

Include "FONT.inc"
End

Yukarıdaki gibi bir program yazdım ama yazdığımı okuyamıyorum veya hiç yazamıyorum. Nerelerde hata yapabilirim. Eğer Vaktiniz varsa bi incelerseniz çok mutlu olurum. En azından karşılaşabileceğim olası sorunları belki siz bilirsiniz.
Eepromun datasheedi aşağıdaki gibi
http://ww1.microchip.com/downloads/en/DeviceDoc/22237C.pdf
:( :( :(
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

ete

#34
Alında kolay bir işi zor bir hale getirmişsin gibi görünüyor.
Nedenleri şunlar;

1. WREN ve WRDI komutları isteğe bağlı verilir. Yani bu komutu sen kullanarak yazma işini iptal eder veya açarsın.
    Dolayısıyla yazma işine bu şekilde başlamak gerekmiyor bu bir.

2. SPI (4 uçlu) epromlarda şayet data ayır bacaktan yazılıp bir başka bacaktan okunuyorsa bu bacakları dikkatli kullanman gerekir. Buna göre DO bacağından eproma bilgi verir, DI bacağındanise epromdan bilgi alırsın. Dahada genelleme yaparsak;
SHIFTOUT komutu DO bacağından çalışmalı SHIFTIN komutu ise DI bacağından çalışmalıdır.
Peki sen ne yapmışsın hepsini DO bacağından çalıştırmışsın burası epeyce bir yanlış.

3. Entegre bacaklarında ayrıca WP ve HOLD pinleride mevcut. Bu pinlerin okuma ve yazma esnasında HIGH da tutulmaları gerekir.

Şimdilik bulduklarım bunlar.

Ete


Mucit23

Anladım hocam  Hepsi Dikkatsizliğimden kaynaklanıyor .Hatalarımı düzeltip bir iki çalışma daha yapayım
Holt Bacağını Bir direnç ile besleme voltajına çekmiştim ama 3 Numara Yani WP bacağını şaseye çektim. Bunuda düzeltmem gerekiyor anladığım kadarıyla. PCB de düzenleme yapayım
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

ete

Baktımda İsis de direk senin eprom yok ama sanırım çok benzer olarak 25AA256 var SPI çalışıyor ve hemen hemen bacak isimleri de aynı gibi. Muhtemelen muadilidir. Bence isisde devre kur ve orada denemeler yap.
Sonra asıl devreye geçersin.

Ete

Mucit23

Bende bulamadım
dediğiniz gibi yapayım. Gerçek devrede herşey olağan gitmiyor malesef.
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

Mucit23

#38
Hocam Bendeki isiste 25AA512 de var. 25A512 ile aynıdır herhalde
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

ete

Onemli olan yontem gelistirmek. İstediginle yap farketmez.
Ete

Mucit23

#40
--------------------
Hocam hatalarımı düzelttim birkaç deneme daha yaptım. Biraz gelişme var. Hem simülasyonda hemde gerçekte devre çalışıyor görünüyor. Fakat hala iletişimde sıkıntı yaşıyorum. Okurken artık Hep FF değerini okuyorum. Yani 255 geliyor. Simülasyondada böyle gerçek ortamdada böyle ben şimdilik SPI modlarında şüpheleniyorum.
Device 18F452

Config_Start
   OSC = HS ; HS osc
   OSCS = OFF ; Disabled
   PWRT = On ; Enabled
   BOR = OFF ; Disabled
   WDT = OFF ; Disabled
   STVR = OFF ; Disabled
   LVP = OFF ; Disabled
   Debug = OFF ; Disabled
Config_End

Xtal 20

TRISA=%00000000
TRISB=%00000000
TRISC=%01000000
TRISD=%00000000
TRISE=%00000000

PORTA=0:PORTB=0
PORTC=0:PORTD=0
    PORTE=0

PORTB.5=1                          'GLCD RESET=1
All_Digital= TRUE                  'ADC PORTLARININ TAMAMI DİJİTAL GİRİŞ VEYA ÇIKIŞ
LCD_DTPort = PORTD                 'GLCD DATA PORTLARI PORTD'YE BAĞLI
LCD_RSPin = PORTB.0                'GLCD RS PİNİ PORTB.0 BAĞLI
LCD_ENPin = PORTB.2                'GLCD ENABLE PİNİ PORTB.2 BAĞLI
LCD_RWPin = PORTB.1                'GLCD RW PİNİ PORTB.1 BAĞLI
LCD_CS1Pin = PORTB.4               'GLCD CS1 PİNİ PORTB.4 BAĞLI
LCD_CS2Pin = PORTB.3               'GLCD CS2 PİNİ PORTB.3 BAĞLI
LCD_Type =  Samsung                'GLCD TİPİ GRAFİK KS0108 128*64B WİNSTAR
Declare Internal_Font = On
Declare Font_Addr = 0
Declare GLCD_STROBE_DELAY = 5
;GLCD_EXTERNAL_PRINT = PPRINT

    Symbol CS =PORTC.0
    Symbol SCK=PORTC.2
    Symbol DO =PORTC.4
    Symbol DI =PORTC.6

Dim ADDR     As Word
Dim ADRS     As Word
Dim YPOS     As Byte
Dim XPOS     As Byte
Dim CHAR     As Byte
Dim KONT     As Byte
Dim RESIM    As Byte
Dim X        As Byte
Dim EEWRT    As Byte
Dim EERAD    As Byte
EEWRT=%00000010
EERAD=%00000011
;GoSub EE_INIT
Cls
Print At 1,1,"LUTFEN BEKLEYiNiZ"
Print At 2,1,"KAYDEDiliYOR..."
DelayMS 100
ADRS=0:ADDR=$A0
BASLA:
GoSub E_WRITE:GoSub E_READ
Print At 3,1,"YAZILAN=$",Hex2 ADDR
Print At 4,1,"OKUNAN=$",Hex2 CHAR
Stop

E_WRITE:
CS=0
  SHOut DO,SCK,msbfirst_l,[EEWRT,ADRS\16,ADDR]
CS=1
Return

E_READ:
CS=0
  SHOut DO,SCK,msbfirst_l,[EERAD,ADRS\16]
  SHIn  DI,SCK,msbpre_l,[CHAR]
CS=1
Return

EE_INIT:
CS=0:DO=1:SCK=1
CS=1:SCK=0
Return

Include "FONT.inc"
End


Yazılımın Son hali böyle
SHOUT ve SHIN modları için help dosyasında böyle açıklama mevcut.

SHOUT Modları
LSBFIRST    0      Shift data out lowest bit first.   Clock idles low
LSBFIRST_L  0      Same as above
MSBFIRST    1      Shift data out highest bit first.  Clock idles low
MSBFIRST_L  1      Same as above
LSBFIRST_H  4      Shift data out lowest bit first.   Clock idles high
MSBFIRST_H  5      Shift data out highest bit first.  Clock idles high

SHIN modları
MSBPRE,  MSBPRE_L  0     Shift data in highest bit first.  Read data before sending clock. Clock idles low
LSBPRE,  LSBPRE_L  1     Shift data in lowest bit first.   Read data before sending clock. Clock idles low
MSBPOST, MSBPOST_L 2     Shift data in highest bit first.  Read data after sending clock. Clock idles low
LSBPOST, LSBPOST_L 3     Shift data in highest bit first.  Read data after sending clock. Clock idles low
MSBPRE_H           4     Shift data in highest bit first.  Read data before sending clock. Clock idles high
LSBPRE_H           5     Shift data in lowest bit first.   Read data before sending clock. Clock idles high
MSBPOST_H          6     Shift data in highest bit first.  Read data after sending clock. Clock idles high
LSBPOST_H          7     Shift data in lowest bit first.   Read data after sending clock. Clock idles high

Okuma modları birazdaha karmaşık görünüyor.
SHOUT komutunda Ben msbfirst_l Kullanmışım. Yani veri göndermeye en yüksek bitten başlıyor. Clock ucuda başta low konumunda bekleyecek.
SHIN de ise msbpre_l modunu kullandım. Buda yüksek bitten data alımına başlıyor. Yine clock lowda bekliyor.

Burada bi hata olabilirmi? Datasheede bakarak yaptım.
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

ete

Bir şema göremediğim için açıkçası eprom'un data giriş ve data çıkış pinlerini yanlış kullandığını düşünüyorum.
Biliyorsun entegrede iki data pini mevcut.
- SO : bu pin epromdan bir bilgi okur iken kullanacağın pindir  Yani SHin  komutu ile kullanacağın pin budur.
          Programında bu pinlere bağlı Pic pinlerine isism verdiğini biliyorum. Şayet aynı isimleri vermiş isen hesabın yanlış sanırım.

- SI : Bu pin eproma instruction , Adres ve  bilgi yazarken kullanacağın pindir. Yani SHOut ile kullanacağın pindir.

Bu açıklamaları yeniden gözden geçir ve tekrar dene bakalım.

Eproma bilgi yazılırken MSBFIRST , CLK LOW da kalır.  Epromdan bilgi okurken  aynı mantık olmalı. Aslında çokda farketmiyor. Zira hem yazma hem okumada CLK yükselen kenarda iken Data alınıyor veya veriliyor. Dolayısıyla CLK nerde kalırsa kalsın bir yükselen kenar meydana getirecektir. Aslında en doğrusu HIGH da kalması. Böylece LOW a inecek ve tekrar HIGH a yükselirken data CLK lanmış olacaktır.

Ete

Mucit23

Hocam şemada bir problem olduğunu düşünmüyorum çünkü Eepromun SO bacağını Ben pic tarafında DI yani Data girişi olarak tanımladım. Eepromun SI bacağı ise Picde DO yani data çıkışı olarak tanımlamışım.

jpeg image hosting
Sorun olmaması gerekiyor.
Birde şöyle birşey var.
Eepromadan gelen datayı picin algılaması için  bir transistör yardımıyla 5 volta yükseltiyorum. Tabi bu sırada gelen veri değilleniş olarak geliyor. Ama benim her seferinde 255 okumam heleki simülasyonda çünkü Gerçekte transistörün beyzine sinyal uygulanmadığı zaman DO çıkışı herzaman 1 konumunda oluyor. Ama simülasyonda neden böyle oluyor anlamadım. Çünkü Arada bir yükselteç devresi yok. Çözemedim bir türlü şu epromu
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

ete

Bir yerlerde hata yapıyorsun ama nerede. Şu anda pek konsantre olamıyorum çünki program yazıyorum.
Bitirince senin işle meşgul olacağım. Sana zahmet sen programla birlikte simulasyon dosyasını bana mail atıver.
Program Protonda yazıldı biliyorum ben çevirir kullanırım sorun değil.

Ete

Mucit23

Hocam Size gerçekten çok zahmet ediyorum Bu eepromu birçok işimde kullanmam gerekiyor. Benim için bir düğüm noktası niteliğinde Bu işle ilgilenirseniz gerçekten çok sevinirim.
Aşağıdaki linke devre şeması, yazılım dosyaları ve 25A512 nin datasheedini yükledim.

http://hotfile.com/dl/142360706/2a17fb7/25A512_EEPROM.rar.html

Verdiğim rahatsızlıktan dolayı tekrar tekrar özür diliyorum :(
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

Powered by EzPortal