Forum: Mikrocontroller und Digitale Elektronik TWI Slave Interupt hängt bei vielen Zeilen Code, sonst nich


von Christian (Gast)


Lesenswert?

Hallo,
ich habe ein etwas komisches Problem, und bin auf der Suche nach ein
paar Stichworten um auf den richtigen Weg zu kommen..

Ich habe ein Master, der macht nix Spektakuläres:


i2c_start(Dev24C02+I2C_WRITE);
  warte(10);
  i2c_write(0xFF);
  warte(10);
  i2c_write(0x00);
  warte(10);
  i2c_write(0xFF);
  warte(10);
  i2c_write(0x00);
  warte(10);
  i2c_write(0xFF);
  warte(10);
  i2c_write(0x00);
  warte(10);
  i2c_write(0xFF);
  warte(10);
  i2c_write(0x00);
  warte(10);
  i2c_stop();
  warte(10);
.....

Das läuft als Schleife durch und erzeugt eine bunte Folge von
Lichtlein. Wenn ich im Slave als DebugCode nur:


SIGNAL (SIG_2WIRE_SERIAL){

  // TWI Interrupt ausgeloest

     PORTB = TWDR;
  PORTA = TWSR;


   TWCR |=
(1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(0<<TWSTO)|(0<<TWSTA)|(0<<TWWC) 
;
// Enable TWI again
}


habe, dann klappt es wunderbar, er läuft jahrelang durch ohne ein
Problem..

Sobald ich aber ein paar Ifs einbaue, bleibt er hängen. Und zwar erst
bei mehreren, eine geht noch..

So ungefähr:


SIGNAL (SIG_2WIRE_SERIAL){

  // TWI Interrupt ausgeloest

     PORTB = TWDR;
  PORTA = TWSR;

    if((TWSR & 0b11111000) == 0xC8)
   {
  PORTA = 0xFF;
   }
       if((TWSR & 0b11111000) == 0xC8)
   {
  PORTA = 0xFF;
   }
       if((TWSR & 0b11111000) == 0xC8)
   {
  PORTA = 0xFF;
   }
       if((TWSR & 0b11111000) == 0xC8)
   {
  PORTA = 0xFF;
   }
       if((TWSR & 0b11111000) == 0xC8)
   {
  PORTA = 0xFF;
   }



   TWCR |=
(1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(0<<TWSTO)|(0<<TWSTA)|(0<<TWWC) 
;
// Enable TWI again
}


Hat jemand eine Idee woran es liegen könnte.. (Die Befehle im Master
sind haben sehr lange Pausen, eigentlich dürfte es daran nicht liegen -
also das er schon sendet während der Slave noch ifft)

Aber es muss ja irgendwas mit der Zeit sein..

bin für Tips dankbar, hab zwar das Datenblatt schon gelesen, aber
nichts zeitkritisches gefunden..

Christian

von Christian (Gast)


Lesenswert?

So, jetzt bin ich verwirrt...

Wenn ich die Zeile:

   TWCR |=
(1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(0<<TWSTO)|(0<<TWSTA)|(0<<TWWC) 
;
// Enable TWI again

Vor die Ifs packe, dann klappt es..
Ich dachte diese Zeile sei erst für die nächste Operation nötig, damit
ich z.B. das nächste Byte empfangen kann.
Warum schadet es denn, wenn der Interupt zu lange wartet, sprich 10 Ifs
prüft, bevor er das TWCR setzt..

Na ja, ich kann ja jetzt erstmal weiter machen, aber es ist schon eine
sehr schwer zu findende Fehlerquelle, wenn jemand mal das gleiche
Problem hat, siehe oben.

Obwohl, woran es lag wüsste ich schon gerne, hab ich wieder mal was im
Datasheet überlesen..

von Peter D. (peda)


Lesenswert?

Ich vermute mal, Dein Master ist in Software und nicht richtig
implementiert.

Die Wartezeiten sind völlig nutzlos, da der Master so nicht mitkriegt,
wann der Slave wieder bereit ist.

Richtig ist es, wenn der Master bei jedem Bit auf der SCL-Leitung
horcht, bis die wieder High ist.


Peter

von Christian (Gast)


Lesenswert?

Ja,
mein Master in in Software, und zwar von Peter Pfleury..

Ob der richtig implementier ist, weiß ich nicht so recht.
Ich suche mir jetzt mal einen Hardware TWI in C, hoffe ich finde das
was, und probiere damit nochmal rum..

Christian

von Peter D. (peda)


Lesenswert?

Es geht auch in Software. Einfach hinter jedes SCL = 1 eine Schleife,
bis SCL wirklich 1 ist.

Die Peter Pfleury ist warscheinlich für EEPROMs und den PCF8574, da
braucht man sowas nicht.

Das Warten auf SCL ist nur notwendig, wenn der Slave ein µC ist, da der
ja gerade mit was anderem beschäftigt sein kann.


Peter

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.