25A512 Gerçekte İletişim Problemi

Başlatan Mucit23, 20 Ocak 2012, 21:23:41

Mucit23

Merhaba arkadaşlar.
25A512 eepromu ile çalışıyorum. Fakat gerçekte birkaç sıkıntı ile karşılaştım sebebini bir türlü bulamadım. Yazılımsal olarak Ete hocamında yardımlarıyla Hallettim. Birkaç sıkıntı vardı yazılımda onlarıda çözdüm. Simülasyonda eepromu çalıştırabildim. Yani Ne yazdıysam onu okuyabiliyorum fakat gerçekte eeprom hiçbirşekilde verdiğim komutlara cevap vermiyor.
Eepromun datasheedi aşağıda
http://ww1.microchip.com/downloads/en/DeviceDoc/22237C.pdf
Herşeyi datasheede göre yaptım. Yani Datasheedin dışında birşey yapmadım. Gerçekte neden böyle bir sorunla karşılaşıyorum çözemedim bir türlü.
Yazdığım program aşağıdaki gibi
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=%00000001
TRISB=%00000000
TRISC=%01000000
TRISD=%00000000
TRISE=%00000000

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

ADCON0=0
ADCON1=7  'tamamı digital

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
Declare Shift_DelayUs 50
;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 OKUNAN   As Byte
Dim SONUC    As Byte
Dim WREN     As %00000110
Dim EEWRT   As %00000010
Dim EERAD    As %00000011
GoSub EE_INIT
Cls
DelayMS 200
Print At 1,1,"LUTFEN BEKLEYiNiZ"
Print At 2,1,"KAYDEDiliYOR..."
DelayMS 100
ADRS=15:ADDR=$E1

BASLA:

GoSub E_WRITE
DelayMS 10
GoSub E_READ

Print At 3,1,"YAZILAN=$",Hex2 ADDR
Print At 4,1,"OKUNAN=$",Hex2 CHAR
DELAYMS 500 
CS=0
  OKUNAN=0
  SHOut DO,SCK,1,[%00000101]
  SHIn DI,SCK,0,[OKUNAN\8]
  Print At 5,1,"STATUS=$",Hex2 OKUNAN
CS=1
DELAYMS 500
GoTo BASLA

E_WRITE:
CS=0
  SHOut DO,SCK,1,[WREN]  ;Write enable
CS=1
DelayMS 1
CS=0
  SHOut DO,SCK,1,[EEWRT,ADRS\16,ADDR]
CS=1
Return

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

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

Include "FONT.inc"
End


Dediğim gibi bu program simülasyonda çalışıyor.
Sorun neden kaynaklanabilir. Daha önce bu eepromla çalışan veya fikir yürütebilecek olan varmı?

Mucit23

Konu güncel arkadaşlar. Sorun hala devam ediyor:(

Maxim

belki bekleme sürelerini uzatman gerekir
belkide shout ile shin arasında biraz bekleme gerekir ?

Mucit23

Hocam Yazma ve okuma için Datasheet de yazma ve okumayla ilgili açıklayıcı resimler var.
Yazma işlemi bu şekilde.

gif image hosting

Okuma işlemide bu şekilde

jpg image hosting

Resimlerden anladığım kadarıyla Tüm işlemler 32 clock palsinde bitiyor.(page wirte ve page read hariç) Yani Shiftout komutu ile Shitin komutu arasında bir bekleme yapılmaması gerekiyor. Yazma ve okuma işlemi seri bir şekilde oluyor. Ama araya bir delay koyma işinide denerim birazdan.

Yanlız logıc analyser ile picin data çıkışına baktığımda her bir veri göndermede yaklaşık 30 ile 36 us arası bir bekleme var. Bu SHout komutundan kaynaklanan birşey. Veri göndermeden kastım şöyle
Veri gönderirken aşağıdaki aşağıdaki gibi yazma komutunu, 16 bitlik adres bilgisini ve 8 bitlik datayı peş peşe gönderiyorum.
SHOUT DO,SCK,1,[EEWRT,ADRS\16,ADDR]

Veri gönderilirken her bir veri paketi arasında 30 ile 36us arası bir bekleme yaşanıyor. Sorun bundan kaynaklanabilirmi?

ete

#4
Mucit,
Data sheet'i yine dikkatlice okudum. Özellikle Yazma konusuna konsantre oldum zira sorunun orada olduğunu düşünüyorum.
Yazılanlara bakılırsa Bir yazma emrinden sonra dahaili yazma peryodu sona ermeden CS ucunu HIGH'a çekersen yazma işi iptal olabiliyormuş Daha doğrusu iptal oluyormuş. bu kısmı yanlış anlamışım. Tam tersi hemen veri tamamlandıktan sonra CS HIGH yapılacakmış. AMa gecikme ondan sonra verilecekmiş.

Yazma işinin bitip bitmediğini de test etmek mümkün. İki şey deneyebilirsin.
Birinci deneme:
E_WRITE:
CS=0
  SHOut DO,SCK,1,[WREN]  ;Write enable
CS=1
DelayMS 1
CS=0
  SHOut DO,SCK,1,[EEWRT,ADRS\16,ADDR]
CS=1
  DelayMS 6
Return

Gördüğün gibi yazma alt programına yazma işinin tamamlanabilmesi için yeterli zamanı , CS pinini High yaptıktan sonra veriyoruz.
Büyük ihtimalle bu sorunu çözecek ama bir ikinci denemeyide yapmakta yarar var. Buda Status registerin ilk biti (bit0) yazma işleminin sona erip ermediği konusunda bilgi içermektedir. Bu bit 1 ise yazma devam ediyor, bu bit sıfır ise yazma sona erdi anlamına geliyor.
O halde yazma emrini verdikten sonra sürekli status registerinin sıfırıncı bitine bakarak yazma işi sona ermiş ise orada bekleyip daha sonra oradan ayrılabiliriz.
İşte gerekli kod;
E_WRITE:
CS=0
  SHOut DO,SCK,1,[WREN]  ;Write enable
CS=1
DelayMS 1
CS=0
  SHOut DO,SCK,1,[EEWRT,ADRS\16,ADDR]
CS=1
TEKRAR:
  SHOut DO,SCK,1,[%00000101]
  SHIn DI,SCK,0,[OKUNAN]
  IF OKUNAN.0=1 then TEKRAR
Return


Bu denemeleri yapıp sonucu bildirirsin artık.

Ete

Edit:  Figure 2.2 ye bakarsan yazma işleminin sonunda bir Twc zamanı kadar beklenmesi gerektiği gösteriliyor ki bu dahili yazma süresi =5ms olarak verilmiş.
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

Mucit23

Hocam malesef değişen birşey olmadı. Artık deneyebileceğim birşey kalmadı. Level shifter devresi çalışıyor. Yani Eepromun besleme ayaklarında 2,7 volt civarı var. Ben artık shout ve Shın komutlarından şüpheleniyorum. Gerçi simülasyonda eeprom çalışıyor. Belki seri iletşim kısmını kendim yaparsam bi faydası olur diye düşünüyorum. Yani yukarıda figure 2.1 ve 2.2 deki gibi kesintisiz bir şekilde iletişim olsa bir faydası olurmu. Benim aklıma artık bundan başka birşey gelmiyor. Elimde birde 23A256 Var ama iletişim yapısı aynı

Elimde Birde 24LC256 var ama 24LC256 ile 24C256 arasında pek bir fark yok galiba. Şu I2C eepromlarda birde Page Read denemek istiyorum. Özellikle Page Read'ı, Yazmada pek hıza ihtiyacım yok ama okumada hıza çok ihtiyacım var. Bu iş sırasıyla nasıl yapılması gerekiyor. Okuma komutu ve başlangıç adresi verildikten sonra sıra sıra okuma yaptım ama hiçbirşey okuyamadım. Bu yöntemide denemek isterim. Fikri olan varmı

Mucit23

Arkadaşlar bu akşam yine I2C eepromlarla page read üzerine bir deneme yapmak istiyorum. Fakat page read işini tam olarak anlayamadım. Daha önce deneyen vardır belki. Kontrol bilgisi ve ve Başlangıc adresi belirtildikten sonra okuma işlemini nasıl yapmam gerekiyor.
24LC256 kullanacağım.
Byte Write Ve page write işlemini anlatan şema aşağıdaki gibi verilmiş.

gif image hosting

Sıralı okuma işlemide bu şekilde

hosting images

  Sıralı okuma işleminin gerçekleşebilmesi için anladığım kadarıyla veri paketleri arasına stop biti gönderilmemesi gerekiyor. Yani yukarıdaki resimlerden ben onu anladım.
   Birde şu var. Daha önce bir çok defa 24C-32,64 gibi eepromlar kullandım. (Gerçi şimdiye kadar hiç sıralı okumayı denemedim.) Bilindiği gibi Eepromların çoğu kendi içerisinde sayfalardan oluşuyor. Bu sayfaların boyutu eepromun kapasitesine göre değişiyor. Genel olarak eepromlarda sayfa değiştirme işlemlerini kendisi ayarlıyor. Ama sıralı okuma işleminde böyle bir durum varmı bilmiyorum. Çünkü bazı eepromların datasheedinde sankide en fazla şukart byte veri okuyabilirsiniz gibi bir ibare okumuştum.

24LC256 nın datasheedinde şöyle bir açıklama mevcut.

Alıntı Yap8.3 Sequential Read
Sequential reads are initiated in the same way as a
random read except that after the 24XX256 transmits
the first data byte, the master issues an acknowledge
as opposed to the Stop condition used in a random
read. This acknowledge directs the 24XX256 to
transmit the next sequentially addressed 8-bit word
(Figure 8-3). Following the final byte transmitted to the
master, the master will NOT generate an acknowledge,
but will generate a Stop condition. To provide sequential
reads, the 24XX256 contains an internal Address
Pointer which is incremented by one at the completion
of each operation. This Address Pointer allows the
entire memory contents to be serially read during one
operation. The internal Address Pointer will
automatically roll over from address 7FFF to address
0000 if the master acknowledges the byte received
from the array address 7FFF.

Ne demek istediğini pek anlayamadım. Adres pointeri felan bişeylerden bahsediyor.
Her neyse Ben yukarıdaki resimlere göre daha önce bir iki deneme yaptım ama başarılı olamadım.
Protonun Busın, ve Busout gibi I2C iletişim komutlarıyla bunu yapabilirmiyim ? Yapılabiliyorsa işlem sırası nasıl olmalı. ;Bu konuda biraz yardıma ihtiyacım var.

Page Read işleminde her seferinde kontrol ve adres bilgisi gönderilmeyeceği için hızda önemli gözle görülür bir fark oluşuru mu?

FEHMİ_ASM

#7
Mucit23 hocam merhaba.

   Henüz sıralı okuma üzerine bir algoritma oluşturmadım. Ancak işine yarayabilirse, sıralı okuma (16Byte) için aşağıdaki örneği sıralı okumaya uyarlayabilirsin. Zannediyorum (-ki öyle olması gerekir) okuma için sadece donanım adres bilgisini gönderirken okuma yapacağını bildirmen (A1 olması lazım) yeterli.

Write_24C1:           //Her yeni bir sayfa yazma-okuması için buradan başla
    Delay10KTCYx(100);   ;Gereksiz (?)

     IdleI2C();        
     StartI2C ();

     IdleI2C();
     WriteI2C (0xA0);  //Donanım..
     while (SSPCON2bits.ACKSTAT);
   
     IdleI2C();
     WriteI2C (AdrH_24C1);  //Adres..Hıgh
     while (SSPCON2bits.ACKSTAT);

     IdleI2C();
     WriteI2C (AdrL_24C1);  //Adres..Low
     while (SSPCON2bits.ACKSTAT);

//-------------------------------------
    while ((0 != AdrL_24C1 % 16) | (T_Adr_24C1 != Adr_24C1))
   {  
Write_24C1_Devam:              //En fazla 16byte lık bir sayfa yazılana kadar bu döngüyü tekrarla
     IdleI2C();
     Wrt_24C1 = Buff16_24C1[Buff16_24C1_Index]; 
     Buff16_24C1_Index = Buff16_24C1_Index + 1;

     WriteI2C (Write_24C1);   //<<<<<<<<<<<<<<<<<<<Data..
     while (SSPCON2bits.ACKSTAT);
      
     Adr_24C1 = Adr_24C1++;  //Bir sonraki adres okuması için sayacı arttır
    }
//-------------------------------------

         IdleI2C();     //Sayfa yazıldı, I2C sayfa yazmasını sonlandırarak (varsa) yeni bi sayfa yazmasına geri dön
         StopI2C ();
         IdleI2C();

     IdleI2C();
     StopI2C ();
     while (SSPCON2bits.ACKSTAT);
     IdleI2C();


    Sıralı yazma ile normal yazma arasındaki zaman farkını biliyorsunuz sanırım. Sıralı okuma ile tek tek okumaya göre avantajı daha çok zaman olarak değil de, komut karmaşasını ortadan kaldırmak. Öyle ki okuma zaten çok kısa sürüyor. Bizi her defasında donanım adresi, kontrol byte'ları göndermekten kurtarıyor. Sonuçta hem sade bir prg oluşuyor hem de zamandan tasarruf ediliyor

Not : Proton bilmiyorum. Kod örnekleri C18 içindir.


Mucit23

Hocam akşam bi deniyeyim. Aklımda bir iki yöntem var. Onları deneyeceğim. Datasheette belirtilmemiş. ( Ben bulamadım) Ard arda en fazla kaç byte bilgi okuyabilirim. Mesela 1024 byte veriyi tek seferde okuyabilirmiyim. Aralıksız olmak şartıyla.
Gerçi şimdi düşündümde aralıksız tam olarak olmuyor. 1 byte veri okuyacam. O veriyi işleyecem. Sonra gelip tekrar 1 byte veri okuyacam. Verdiğiniz kodlar iyide MSSP kullanıldığı için Pekde bişey anlaşılmıyor açıkçası.