www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik I2C Data nicht gesendet


Autor: Stehpan-th67 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich Programmiere derzeit auf einem LPC2148.
Ich versuche derzeit I2C in Gang zu bekommen, doch leider funktioniert 
es nicht ganz.
Es läuft alles(Slave adressegesendet+ ACK erhalten). Aber sobald ich 
Daten senden will und in der ISR in I20DAT mien Daten lade undSi-Falg 
lösche, wird SDA auf LOw gezogen und nichts passiert, der Stautscode ist 
dann 0x10(also repeated start?). Auf SCL ist jedoch ein Clock mit 9 
Pulsen zu sehen.

Kann jemand helfen?

Gruß Stephan

Autor: Stehpan-th67 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich frage nochmal, vielleicht sieht es jemand, der ein ähnliches Problem 
hatte.
Es funtkioniert alles, bis ich Daten senden will, die Clockleitung macht 
auch das was sie tun soll, nur Sobald ich Daten senden will, wird SDA 
auf LOW gezogen, während auf SCL 9 Takte zu sehen sind.
Wie schon erwähnt steht im Statuscode dann der falsche Code von 0x10, wo 
eigentlich 0x28 (Daten gesendet+ ACK) stehen müsste oder 0x30 für Daten 
gesendet und NACK erhalten.

Wäre schön wenn mir jemand helfen könnte.

Gruß Stephan

Autor: space (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

wie sich Dein Beitrag liest, hast Du am Bus ein Speicheroszi
hängen, was sehr hilfreich bei der Fehlerdiagnose ist.
Letztens hatten wir ähnliche Probleme bei einem 8051-Derivat.
Wir haben ein Programmbeispiel von Atmel verwendet, das wir
noch reichlich umstricken mussten.
Hast Du einen Slave am Bus? Wie ist die Adresse? Wird sie
korrekt umgesetzt?
Die Slaves brauchen bei hohen Taktraten Pausen zwischen den
Befehlen. In Basic fällt das kaum auf, aber in Assembler sehr
wohl.
Vielleicht hilft's
Stefan

Autor: Stehpan-th67 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Slaveadresse ist 1001 dann Hardwaremäßig 000.
Wie meinst du korrekt umgesetzt? Also ein ACK bekomm ich.
Ich weiss dass da Pausen benötigt werden(so 10ms), aber wie kann ich die 
ein bauen. Mein Programm springt ja garnicht aus der ISR. Es Wird die 
Startcondition ausgelöst, dann ist der Statuscode 0x08, dann springt das 
Programm in die Behaldlung von 0x08, dann wird die Slaveadresse 
gesendet, dann ist der Satuscode 0x18, dann werden dort die Daten 
gesendet, und ich galube vor dem Daten senden müsste ich warten,oder?
void I2C_ISR(void) __irq
{  
  int temp1 = 0;
  temp1 = I20STAT;
  
  switch(temp1)
  {
    case 0x08:
    {  
      I20DAT = slaveaddr; //addr      
    }
    break;

    case 0x10:
    {
      I20DAT = slaveaddr;
    }
    break;

    case 0x18:
    {    
      I20DAT = 0xAA;//hier nur Beispielwert
    }
    break;

    case 0x20:
    {
      i2c_stop();  
    }
    break;

    case 0x28:
    {
      I20DAT = 0xAA;//hier nur Beispielwer
    }
    break;

    case 0x30:
    {
      i2c_stop();    
    }
    break;
         }
  I20CONCLR = (1 << SIC); // | (1 << STA);
  VICVectAddr = 0;
  
    
}


Autor: space (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

zuerst wird die Adresse des Slaves gesendet:
das erste gesendete Bit ist das MSB der Adresse.
Die Adresse ist 7 Bit lang und das 8. Bit definiert,
ob gelesen (1) oder gelesen (0) werden soll.
Beim Schreiben werden also nur gerade Werte übertragen.
Das lässt sich sehr gut auf dem Oszi ablesen.
Die Adresse 00h ist ein "General Call", also ein Befehl
an ALLE Slaves!
Noch zwei Tipps:
1. Zum Testen der Routine habe ich diese einmal durchlaufen
lassen und das Programm in einer Endlosschleife enden lassen.
Das Oszi habe ich auf "Single Shot" gestellt und bei richtiger
Einstellung der Zeitbasis kann man Takt und Daten sehr schön
sehen. PS: Ich habe ein Fluke 196.
2. Zum Testen, welche "Cases" durchlaufen werden habe ich
LEDs gesetzt.
Viel Erfolg
Stefan

PS: Da sich nicht jeder mit Deinem Controller auskennt wäre
es sinnvoll vor den "case"-Anweisungen diese mit aussagekräftigen
Kommentaren zu versehen. Das mag Dir sinnlos erscheinen, aber es
erhöht die Lesbarkeit Deines Programms. Das wirst Du aber erst
in ein paar Wochen feststellen, wenn Du diese Routine noch mal
nachvollziehen willst und erst wieder Handbücher wälzen darfst.

Autor: Stehpan-th67 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ich habe mal die cases kommentiert. Danke für den Tip, auf sowas wie 
kommentieren kommt man in der Hitze des Gefechts nicht...
Ich debugge des Ganze mit Hitop5, ich sehe also die cases sehr schön.
DAs Problem ist nur, das folgerder Fall eintritt, der Meiner Meinung 
nach garnicht möglich sein sollte: Beim Senden der Daten wird SDA auf 
LOW gezogen und es werden ja 9 TAkte erzeugt, es werden also nur Nullen 
übertregen, obwohl im Datenregister ein Wert != 0 steht. Beim löschen 
des SI(Interrupt) Flags wird scheinbar ein repeated Start ausgefürt, 
jedenfalls sagt das das Statusregister und auch auf dem Oszi ist eine 
Startcondition zu sehen.

void I2C_ISR(void) __irq
{
  int temp1 = 0;
  temp1 = I20STAT;

  switch(temp1)
  {
    case 0x08:  //Startcondition erzeugt
    {
      I20DAT = slaveaddr; //addr
    }
    break;

    case 0x10:  //Repeated Startcondition erzeugt

    {
      I20DAT = slaveaddr;
    }
    break;

    case 0x18:    //Slaveadresse+Writebit gesendet, ACK erhalten
    {
      I20DAT = 0xAA;//hier nur Beispielwert
    }
    break;

    case 0x20:   ////Slaveadresse+Writebit gesendet, NACK erhalten
    {
      i2c_stop();
    }
    break;

    case 0x28:   //DAten gesendet ACk erhalten
    {
      I20DAT = 0xAA;//hier nur Beispielwer
    }
    break;

    case 0x30:    //DAten gesendet NACk erhalten
    {
      i2c_stop();
    }
    break;
         }
  I20CONCLR = (1 << SIC); // | (1 << STA);
  VICVectAddr = 0;


}

Autor: space (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Tach,

dann überprüfe, ob I20DAT und slaveaddr korrekt initialisiert
und zugeordnet worden sind. Es wäre auch zu prüfen, ob die
Variablen und Register nicht versehendlich überschrieben
werden. Gib in der Interruptroutine, zu Tests, die Adresse
fest vor.
Mit Kommentaren ist die Routine wirklich besser lesbar :o)
Viel Erfolg
Stefan

PS: Im Anhang ist das Oszillogramm eines I²C-Schreibbefehls.
Das erste Paket ist die Adresse, danach kommen zwei Pakete
mit Daten.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Bits in ICONSET setzen sich nicht alle von selbst zurück, 
beispielsweise nicht STA. In den Tabellen 148+ des Manuals ist 
beschrieben, was im jeweiligen Zustand von der Software erwartet wird. 
Dazu gehört auch, diese Bits entsprechend zu setzen oder zu löschen.

Beispielcode findet man in der Application Note AN10369 von NXP.

PS: Seltsamerweise war vor ein paar Tagen ein anderer(?) Anwender mit 
gleichem Controller, gleichem Compiler und ähnlichem Problem unterwegs. 
Ist das grad ansteckend?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.