Forum: Mikrocontroller und Digitale Elektronik Fieses I2c Ack-Bit


von Joachim .. (joachim_01)


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?

von Peter S. (psavr)


Lesenswert?

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

Poste mal die Oszi-Bilder von SCL und SDA

von Joachim .. (joachim_01)


Angehängte Dateien:

Lesenswert?

Schade, daß das sich das Rigol im Single-Mode nicht im "großen Fenster" 
steuern läßt. So halt nur das kleine Bild.

Hab zwischendurch noch mit dem WC/Prot-Eingang dws 24C04 rumgespielt, 
ändert aber nichts.

Uups... "unterdrücktes Ack" muß natürlich "bestätigtes Ack" lauten, SDA 
= low.

von Joachim .. (joachim_01)


Lesenswert?

Der Zipfel entsteht da der Transistor ja nicht unendlich schnell 
schaltet. Macht aber nichts, der Zustand wird eh erst während der 
nächsten High-Periode von SCK geprüft. Da ist die Leitung low.

von Joachim .. (joachim_01)


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();
  }

von Peter S. (psavr)


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

von Joachim .. (joachim_01)


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...

von Peter S. (psavr)


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?

von Peter D. (peda)


Lesenswert?

Das I2C im Oszibild ist ja völlig daneben.
Dein 2.Paket hat 10 Takte, also einer zuviel.


Peter

von Joachim .. (joachim_01)


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...

von Peter D. (peda)


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

von Joachim .. (joachim_01)


Lesenswert?

Uhhh! Peter hat recht.
Da ist im Code irgendwas beim Testen durcheinander geraten.

Ich dank' euch für die Unterstützung.

von Joachim .. (joachim_01)


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();
  }

von Peter (Gast)


Lesenswert?

Beim Lesen muss der uC die ACK generieren. Ausnahme, beim letzten Byte 
gibt es kein ACK, um dem Device anzukündigen, dass nun Schluss ist mit 
lesen.

von Joachim .. (joachim_01)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.