Forum: Mikrocontroller und Digitale Elektronik Mehrere Bytes mit TWI (AVR<->AVR)


von zoltan (Gast)


Lesenswert?

Hallo,

ich versuche ohne Erfolg mehrere Bytes zwischen zwei Atmega8 zu
übertragen. Bei nur einem Byte hingegen klappt es hervorragend.
Ich benutze den (leicht modifizierten) Software Master Lib von Peter
Fleury
(http://homepage.sunrise.ch/mysunrise/pfleury/group__pfleury__ic2master.html)
, und einen Hardware Slave (ebenfalls Atmega8).

Nach meinem Verständniss müsste der Master nach dem Senden des ersten
Byte darauf warten, bis der Slave die Interrupt-Routine beendet hat und
die SCL wieder freigegeben hat. Danach würde er den zweiten Byte senden
usw..

Aber so wie ich mir das denke funktioniert das ganze leider nicht, und
ich komme einfach nicht darauf, woran das liegen könnte. Ich habe schon
allerhand ausprobiert, aber ohne Erfolg.

Vielleicht fällt jemanden was auf?



////Auszug aus MASTER:
i2c_start_wait((SLAVE1<<1)+I2C_WRITE);
i2c_write(temp);
i2c_write(temp+1); // 2x byte ohne Slave neu adressieren zu müssen ???
i2c_stop();


////Auszug aus SLAVE:
SIGNAL(SIG_2WIRE_SERIAL)
{
  switch (TWSR)
  {
    //****************************************
    // Slave status (receiver mode)

    case(0x60):{
      TWCR=(1<<TWEN)|(1<<TWINT)|(1<<TWEA)|(1<<TWIE);
      break;
    }

    case(0x80):{
      soll_position=TWDR;

                  if(k==0){ temp1=soll_position;}
      if(k==1){
        temp2=soll_position;
        k=-1;
      }
      k++;

      TWCR=(1<<TWEN)|(1<<TWINT)|(1<<TWEA)|(1<<TWIE);
      break;
    }

    case(0xA0):{
      //i2c_val2=TWDR;  // nicht zweimal lesen!!
      TWCR=(1<<TWEN)|(1<<TWINT)|(1<<TWEA)|(1<<TWIE);
      break;
    }
  }
}



Danke und Gruß
Zoltan

von Andreas Hesse (Gast)


Lesenswert?

Hallo,

verwendest Du Duden Hardware TWI des Mega8?
Die TWI-Bibliothek i2cmaster brauchst Du (glaub ich jedenfalls) nur,
wenn Du keinen Hardware TWI verwendest.
Ich habe diese Bilbliothek mal erfolgreich auf einem 2313 verwendet
(ohne Hardawre TWI).

Gruss
Andreas

von thkais (Gast)


Lesenswert?

Der Slave legt den SCL nur an Masse, wenn er einen Wait-State anfordert,
ansonsten wird der SCL ausschließlich vom Master gesteuert.

@Andreas: Die Bitbezeichnungen lassen eindeutig auf den Hardware-TWI
schließen.

Könnte es sein, daß der Slave kein ACK sendet und der Master daraufhin
abbricht? Üblicherweise ist es so, daß der Slave beim Adressieren ein
ACK sendet und bei allen Datenbytes ebenfalls, nur beim letzten
Datenbyte wird kein ACK gesendet, um dem Master mitzuteilen, daß keine
Daten mehr vorhanden sind bzw. der Slave keine mehr empfangen möchte.
Das würde zum Fehlerbild "nur ein Byte wird übertragen" passen.

Wenn ich irgendeine Ahnung von C hätte, könnte ich evtl. mehr
helfen....

von Andreas Hesse (Gast)


Lesenswert?

Hallo,

der master verwendet also einen Software TWI und der Slave einen
HardwareTWI?

Ich habe mal meinen Code durchgeschaut:
Ich starte da mit I2C_Start(Adresse) nicht mit
i2c_start_wait(Adresse).

Es könnte sein, das wie thkais schon bemerkt hat, kein ACK vom Slave
kommt. Für solche Fälle habe ich die Masterbibliothek abgeändert:
In der i2c_ack_wait - Schleife wird ein Zähler verwendet. Wenn der
Zähler 0 geworden ist (Timeout), dann wird ein Fehler generiert.

Gruss
Andreas

von zoltan (Gast)


Lesenswert?

Der Master ist in Software und der Slave arbeitet mit dem Hardware TWI
des AVR.

"Könnte es sein, daß der Slave kein ACK sendet und der Master
daraufhin abbricht?" Doch, der Slave sendet einen Ack.

Nach langem Probieren läuft das ganze jetzt. Allerdings nur sehr
unstabil. Es werden auch manchmal falsche Werte übertragen, obwohl ich
die Übertragungngsgeschwindigkeit auf ungf. 30kHz reduziert habe.(4,7 K
Pullup, 20cm Draht)
Das Programm hängt sich ab und zu einfach auf. Könntest Du mir aus dem
Grund deine geänderte Bibliothek schicken, Andreas?

Was mir noch auf dem Oszi auffällt, dass die Flanken zwischen Clock-
und Datenleitung doch sehr nah aneinender liegen. Ich hätte mir
gedacht, dass es ählich dem Datenblatt aussieht, nämlich dass die
Daten-Flanken sich eher zwischen den Clock-Pulsen ändern, und nicht
gleich dahinter.

Gruß
Zoltan

von Andreas Hesse (Gast)


Lesenswert?

Hallo,

ich habe diese Änderung nur in der Assemblerversion durchgeführt (->
http://de.geocities.com/andi_hesse/Download/I2cdisp.zip und darin die
Datei I2Cdispr.asm).
Der Code sollte dem aus der P. Fleury Datei ähnlich sein (Atmel
Application Note).

Du sprachst die Pull-Up Widerstände an. Ich habe noch für jeden
Baustein 330Ohm Widerstände in der SCL und SDA-Leitung.Lt Atmel ist das
wohl nicht notwendig, man kann alle PINs direkt verbinden. Aber in
vielen Applilkationen habe ich diese Widerstände gesehen, und habe es
auch immer so aufgebaut.

Gruss
Andreas

von zoltan (Gast)


Lesenswert?

Dein Link funktioniert leider nicht.

von zoltan (Gast)


Lesenswert?

Doch, jetzt hab ichs.

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.