Fieses I2c Ack-Bit

OP #2585903
Lesenswert?

Hab hier nen 24C04 an nem PIC18 im Master-Mode.
Device-ID 0xA0 wird an den I2C Teilnehmer gesendet, Ack kommt brav 
zurück, ich seh's auch aufm Oszi. Gegenprobe: Falsche ID  - kein Ack. 
Hardware ist soweit also ok. Sprut schreibt was von 3mA entsprechend 
1,8k für die Pull-Ups, was ich allerdings nicht nachvollziehen kann. 
Aber egal... mit 2,2k und mit 10k gehts, lediglich die Rise-Zeiten sind 
unterschiedlich.

Das war'S dann aber  auch schon. Für das nächste Byte (Adresse für das 
darauffolgende zu schreibende/lesende Byte) kommt kein Ack mehr.

Ich popel jetzt seit über 10h dran rum, langsam gehen mir die Ideen aus. 
Als Software verwende ich die I2C Libs von Microchip. Habs zwischendurch 
mal mit nem manuellen Umschalten probiert (PORT RC4 auf dem SDA liegt, 
auf Eingang geschaltet) weil ich dachte, daß vielleicht das MSSP-Modul 
des PIC den BUS hoch hält, hat aber nichts gebracht.

Hab das Gleiche vor laaanger Zeit mal mit nem 8051 fast auf Anhieb 
hinbekommen - und jetzt so ne Pleite...
Ham die Biester irgendwas spezielles das ich vergessen hab?
OP #2586014
Lesenswert?

>Möglicherweise generierst Du eine STOP- oder RESTART-Condition nach dem
>schreiben der Device-Adresse..?
Hmmm. Eigentlich nicht.


#define send 2
#define receive 1
    SSPADD = 0x13;  //  schön langsam... //0A
    select = send;
    //select = receive;

    if (select == send) //send
     {

    DeviceSelect = 0b10100000;   //1010 + 00 + block number + read 
/write
    PIR2bits.BCLIF = 0;

    // 1.
    OpenI2C (MASTER,SLEW_OFF);
    StartI2C();

    //2.
    I2CError = putcI2C(DeviceSelect);  //
    //2a.
    EEAckError = EEAckPolling(DeviceSelect);

    //3.
    I2CError2 = putcI2C(0x30); //beliebigeAdresse
    //3a.
    EEAckPollingError2 = EEAckPolling(DeviceSelect);


    //4.
    I2CError3 = WriteI2C(0xAA);  //Inhalt
     //4a.
    EEAckPollingError3 = EEAckPolling(DeviceSelect);



    StopI2C();
    CloseI2C();
  }
#2586030
Lesenswert?

Das Oszi-Bild hat leider eine etwas schlechte Auflösung, aber die 
folgende Stelle könnte ein Problem sein:

Nach dem ersten Ack gehen CLK und SDA ungefähr gleichzeitig von 
Low=>High. SDA darf aber nur dann den Pegel wechseln, wen SCL auf LOW 
ist, ansonsten wird dies als STOP- oder START-Condition interpretiert. 
Baue mal nach dieser SDA-Flanke etwas Verzögerung bis zur steigenden SCL 
Flanke ein...

http://www.google.ch/url?sa=t&rct=j&q=i2c%20bus%20manual%20nxp&source=web&cd=2&ved=0CDYQFjAB&url=http%3A%2F%2Fwww.nxp.com%2Fdocuments%2Fuser_manual%2FUM10204.pdf&ei=pOJZT6eNLcbP4QTe_5zHDw&usg=AFQjCNG5emVs3tU5RbGVKjblTMFgLLHdqg&cad=rja
OP #2586047
Lesenswert?

Hmmm. Könnte das ne Erklärung dafür sein, daß wenn ich den Baudratenwert 
SSPADD = 0x13; kleiner mach (schnellerer Takt), der Fehler EEAckError 
kurioserweise weggeht? Ich hab nämlich laut der Rückgabewerte zwei 
unterschiedliche Typen Fehler:
Bus Collision Error in EEAckpolling und return NACK statt ACK in 
writeI2C.

Weiß jetzt nur noch nicht genau wie ich den an der Stelle langsamer 
mache...
#2586054
Lesenswert?

>Weiß jetzt nur noch nicht genau wie ich den an der Stelle langsamer
>mache...
=> Nur so zum ausprobieren: 100pF an die SCL-Leitung
=> Als definitive Lösung: Die I2C-Libs fixen oder selber was machen.

Frage: Verwendest Du eine Hardware I2C-Bus Schnittstelle auf dem Chip 
oder ist es eine SW-Emulation des I2C-Buses?
OP #2586069
Lesenswert?

Ist n alter 18F252 und für den Wiedereinstieg zum üben mit nem 24C04. 
Später soll dern Slave werden aber der Weg ist noch lang. Ich benutze 
die Lib für den HW-I2C.

Das mit dem Kondensator könnte natürlich sein... den hab ich 
weggelassen. Irgendwo sah ich mal nen Plan damit und hab mich noch über 
die zusätzliche kapazitive Last gewundert...
#2586080
Lesenswert?

Joachim ... schrieb:
> Das mit dem Kondensator könnte natürlich sein... den hab ich
> weggelassen. Irgendwo sah ich mal nen Plan damit und hab mich noch über
> die zusätzliche kapazitive Last gewundert...

Wenn das HW-I2C so einen schweren Bug hat, daß man Kondensatoren 
braucht, dann sollte man besser SW-I2C machen.
Kondensatoren haben am I2C nichts zu suchen!


Peter
OP #2586498
Lesenswert?

Sooo... schreiben funktioniert nun, aber lesen geht noch nicht.

Beide Routinen, Lesen und Schreiben sind nahezu gleich, trotzdem verhält 
sich das vom I2C-Device zurückkommende ACK-bit unterschiedlich. Beim 
Beschreiben des EEproms kommen alle Ack-bits fehlerfrei, beim Empfangen 
nur das des ersten Bytes (Packet aus Deviceaddr + Addr high + Addr low + 
Deviceaddr + Speicherzelle).
Wie kann das sein, wenn's beim Lesen und Schreiben die gleichen Routinen 
sind? Ich hab dieses Phänomen in gleicher Form mit mehreren 
unterschiedlichen EEproms. Als ob dem Device zum Lesen noch irgendwas 
fehlt...


// Atmel 24C256 = 0b1010000X;   //1010 + 0 + address number2 + read 
/write
//I2C-Test write one single Byte and read it
#define memAddressInDevice 64
#define valInDevice 11
#define send 2
#define receive 1

    //SSPADD = 0x0A;// ca 300kHz
    SSPADD = 0x28;// ca 95kHz

    select = send;
    // Atmel 24C256:
    if (Taster == 1) select = receive;  //pull-up

    if (select == send) //send
     {

    DeviceSelect = 0b10100000;   //1010 + 00 + block number + read 
/write
    PIR2bits.BCLIF = 0;

    // 1.
    OpenI2C (MASTER,SLEW_OFF);
    StartI2C();

    //2.
    I2CError = WriteI2C(DeviceSelect);  // Ziel-Device

    //3.
    I2CError2 = WriteI2C(memAddressInDevice);  // willkürliche Adresse
    //3.a
    I2CError3 = WriteI2C(memAddressInDevice);  // willkürliche Adresse2

    //4.
    I2CError4 = WriteI2C(valInDevice);     // schreibe Inhalt

    StopI2C();
    CloseI2C();
  }


    // Atmel 24C256: Random Read
    if (select == receive) //receive, random address read
   {
    DeviceSelect = 0b10100001;   //1010 + 00 + block number + read 
/write

    // 1.
    OpenI2C (MASTER,SLEW_OFF);
    StartI2C();

    //2.
    I2CError = WriteI2C(DeviceSelect);

    //3.
    I2CError2 = WriteI2C(memAddressInDevice);  // willkürliche Adresse
    //3.a
    I2CError3 = WriteI2C(memAddressInDevice);  // willkürliche Adresse2

    //4.
    I2CError4 = WriteI2C(DeviceSelect);

    //4.
    var = ReadI2C();

    StopI2C();
    CloseI2C();
  }
OP #2589604
Lesenswert?

Yep hab's mittlerweile hinbekommen, die Abfolgesequenz als solches war 
nicht vollständig und zum Teil auch falsch.

Aber jetzt hab ich n neues, wirklich bizarres Phänomen: Ich hab zwei 
18F8F252, einer als Master u. einer als Slave. Der Slave zieht die 
Taktleitung beim zuschalten des I2C-Moduls, jedoch nicht immer, auf 
Masse. Auffällig ist, wenn ich auf dem Steckbrett den Draht rausziehe 
hab ich n EMV-Problem und der Transistoren am Port macht komische 
Sachen... obwohl der Port auf Eingang geschaltet ist. Als ob er 
elektrostatische Ladung aufnimmt. Wenn ich kurz mit Masse an den Eingang 
drüberwische ist der Spuk wieder weg. Hab schon im errata geschaut, 
diesbezüglich gabs aber nichts.

Hab das mit zwei 18F252 ausprobiert, beide haben das gleiche Verhalten.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren