I2C EEPROM bit vuruşu: İyi yazar, ancak yalnızca ilk bit ayarlanmadıysa


9

Şu anda SDA ve SCL hatlarını sürmek için bit beceriyor kullanarak bir I2C EEPROM projesi üzerinde çalışıyorum.

Okuma fonksiyonum iyi çalışıyor ancak her "1" ile bir bayt yazdığımda, daima FF'yi geri okuyorum; bayt daha önce başka bir şeyle programlanmış olsa bile. Başta "0" mükemmel. Benim okuma rutinim değil; kapsamda görebildiğim gibi FF döndürüyor.

Bunun neden olabileceğine dair öneriler arıyorum. Soruna neden olabilecek özlediğim bir şey var mı? [Kodu gönderemiyorum - şirket gizli ... :(]

Baktığım her dalga formu tam olarak teknik özellikleri karşılar. EEPROM'u ayırıyorum. Benim pull up 2.2k kadar spec içinde. Bu prototipte yaklaşık 500 Hz hızında çalışıyorum. Çip, baytlarımın her birine ACK gönderiyor, böylece onları tanıyor. Ama işe yaramıyor ...

Bir Microchip 24LC256 kullanıyorum .

Bir bayt için basitleştirilmiş yazma algoritması:

wait
SDA low
SCL low
wait
for each bit
    if bit is set:   SDA high
    if bit is unset: SDA low
    wait
    SCL high
    wait
    wait
    SCL low
    wait
wait
SDA high 
SCL high
wait
wait
check ACK status
SDA low
SCL low
wait
return ACK status

Bir bayt için basitleştirilmiş okuma algoritması:

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high
    wait
    wait
    SCL low
    wait
    check and store received bit
    wait
do a NACK or ACK depending on if it is the last byte

1
@Justin - Bence herhangi bir adrese 0x7F değerini yazmak işe yarıyor ama herhangi bir adrese 0x80 yazmak işe yaramaz diyor.
Rocketmagnet

1
Böyle I2C'den nefret etmemi sağlayan şeyler.
Rocketmagnet

1
Çılgın bir önsezim var. Her bit kodu için, yanlışlıkla sağa kaydırma işlemiyle işaret genişletiyor musunuz? Eğer öndeyseniz, 7 vardiya işleminden sonra nihayetinde sizi bir 0xFF ile bırakacaktır.
vicatcu

3
Buradaki ironi, "şirket gizli" kodudur. Onlar için değerlidir. Buradaki herkes işe yarayan kodu paylaşıyor. Bu şirketin kodunu diğerlerinden ayıran şey, çalışmadığıdır.
gbarry

2
Bir şirketin neden bu kadar umutsuzca I2C bit beceriyor kodunu gizli tutması gerektiğini hayal etmek zor. İnternette çok fazla şey var.
Rocketmagnet

Yanıtlar:


4

Verileri saat tekrar düştükten sonra okuyorsunuz. Bunu saati yüksek yapmak ve düşük yapmak arasında yapmanız gerekecek. Saat azaldıktan sonra, kölenin veri hattını yüksekte değil değiştirmesine izin verilir.

resim açıklamasını buraya girin

Yani okumak şöyle olmalı:

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high                      <--------
    wait
    check and store received bit  <--------
    wait
    SCL low                       <--------
    wait
    wait
do a NACK or ACK depending on if it is the last byte

İyi bir noktaya değindin; Bunu düzeltirim. Ancak, verilerim kapsamımda hala hepsi (FF) olarak görünüyor, bu yüzden okumam sorun olamaz ... :(
Thomas O

3

Sonunda sorun, yanlışlıkla zamanlama nedeniyle bazı koşullar altında yanlışlıkla bir DURDURMA koşulu göndermek olduğu ortaya çıktı. Kapsamı kullanmaktan vazgeçtim ve mantık analizörünü çıkardım ve orada olmaması gereken STOP'u vurguladığı için 15 dakika içinde sorunu çözebildim. En yararlı cevaba dayanarak kime verileceğini seçeceğim. Tüm çözümler için teşekkür ederim.


Sevindim "yazma zamanlaması doğrulamak" ile

3
Size bunun dalga formuna bakarak çözüleceğini söyledim.
Rocketmagnet

@Rocketmagnet Her zaman dalga formuna bakıyordum, ama daha önce hiç fark etmemiştim.
Thomas O

Evet, ama göstermedi bize bize defalarca bunun için soran rağmen, dalga biçimini. Bu sorunu günler önce çözmüş olabilirdiniz.
Rocketmagnet

@Rocket - Kabul ediyorum. Keşke o sırada kameram olsaydı. Kullandığım Tek DPO'nun disket sürücüsü vardı, ancak disketi yoktu. Yapabilirsem bir resim yayınlardım.
Thomas O

2

Tamam, kapsamınız PIC'ye gelen 1. baytın kötü olduğunu kanıtlıyor, bu yüzden PIC okuma işlevi değil.

Yazma zamanlamasının alıcı uçta doğru olduğunu doğruladınız mı?

Bu aşağıdaki iki modda da başarısız oluyor mu?

- Byte mode sequential
- Page mode Sequential

Spesifikasyon "En Önemli Bit (MSB) 'b7' 'nin ilk kez gönderildiğini gösterir. Bu aynı zamanda b7 = 1 olduğunda tüm baytın FF olarak tekrar okunduğu zaman da rastlantısaldır. Yani ya yazılı değildir ve sadece b7 = 1 olduğunda silinir (hata durumu) ya da önceki içeriğe bakılmaksızın FF olarak kötü okunur. Her yazma yazma öncesi bir bayt genişliğinde silme olduğundan, yine de kötü bir yazma veya kötü okuma olabilir veya 1. baytın zamanlaması farklı olabilir.

Öneri: Normal çalışmayı sağlamak için yazma / okuma sırasında PTC sinyalini doğrulayın. resim açıklamasını buraya girin

PTC kullanarak bir E / W döngüsünün uzunluğunu zamanlamak için harici bir saat kullanma seçeneği vardır. Bunu kullanmaya çalıştın mı?

tE / W çevrim süresi

  • dahili osilatör 7ms tip
  • harici saat 4 ~ 10 ms min ~ maks

Bu kriterleri aşıyor mu?


1

Kulağa birkaç şey olabilir gibi geliyor:

  1. Otobüste başka ne var? Sıfırlanan veya başlatılmayan başka bir cihazla veri yolu çekişmesi olabilir mi?
  2. G / Ç piminin yönünü doğru şekilde değiştiriyor musunuz? Çıkış durumunda iyi çalışıyorsa, pimin yönünü giriş için değiştirmeyi yanlışlıkla unutmuş olabilirsiniz ve her zaman okunur 0xFF. Pim siz okurken siz otobüsü yönlendiren bir çıkış olarak bırakılabilir.
  3. Pimin kendisinde ve / veya G / Ç hatlarında dahili pull-up'larınız var mı? Mikrodenetleyiciler genellikle sabit bir değer değil, bir dizi direnç verir. Mikro üzerindeki pull-up'ları devre dışı bırakmak ve sadece ayrı bileşenlerden daha hassas bir pull-up direnci elde edebileceğiniz için otobüsteki ayrı olanları kullanmak isteyebilirsiniz.
  4. Saat polaritesi - Saat / veri arasında sağ kenarda / fazda ölçüm yaptığınızdan emin misiniz? Kapsamda size neyin harika göründüğünü görüyor olabilirsiniz, ancak aşama çizginin dışındaysa, tüm EEPROM'unuz 0xFFs (ve büyük olasılıkla geçersiz bir komut / durumla aynı olacaktır) görecektir .

1. Sadece EEPROM ve MCU. 2. Evet, inanıyorum ki, EEPROM SDA / SCL'yi düşük tutabilir. 3. EEPROM'un bitişiğindeki kartta% 2.2k% 5 pull-up bulunmaktadır.
Thomas O

# 2 için, EEPROM'un veri yolunu düşük tutana emin misiniz? EEPROM'un veri sayfasında tüm 0xFFs'leri döndüreceği koşullar var mı ? Yukarıdaki düzenlemelerime de bakın.
Joel B

4.. EEPROM benim istekleri "ACK" ve bazı kelimelerle çalışır, ama hepsi değil.
Thomas O

0

Bunu yukarıda bir yorum olarak gönderdim, ancak cevaba olan güvenim zihnimin derin girintilerinde sessizce büyüyor, bu yüzden bir cevaba yükseltiyorum.

Bu kesinlikle bazı değişkenlerin imzası ile ilgili düşük seviye bir yazılım hatası olduğunu çılgın bir önsezi var. Her bit kodu için, yanlışlıkla sağa kaydırma işlemiyle işaret genişletiyor musunuz? Eğer öndeyseniz, 7 vardiya işleminden sonra nihayetinde sizi bir 0xFF ile bırakacaktır.

Steven bir yorumda bunu ima etti, ancak yazma operasyonlarınızın bir osilloscope üzerindeki kutsallığına tanık oldunuz mu yoksa sadece iyi görünen geri okumaların yarısına dayanarak çalıştıklarını mı düşünüyorsunuz? 0xAA değerinin yazma işlemine bakmayı denemediyseniz, bu denemek için iyi bir şey olabilir.

İç döngünüzün gerçek kodunu ve ilişkili değişken bildirimlerini sağlayabilirseniz, bir hatayı tespit edebiliriz.


Yazılarım iyi; Bunu kapsamda görebiliyorum. Başka bir tuhaflık: Önde gelen MSB ile adresler iyi. Yalnızca veri sorunlara neden olur! Kodu yakında yayınlamayı düşünüyorum.
Thomas O

1
Bu yanıtı desteklemek için: bu C kodu ise, tüm 'char' bildirimlerini 'unsigned char' olarak değiştirin ve tekrar deneyin.
Wouter van Ooijen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.