Forum: Mikrocontroller und Digitale Elektronik TWI Interrupt wird nicht ausgelöst/Multimastersystem


von Thomas Frosch (Gast)


Angehängte Dateien:

Lesenswert?

Hi leute hab ein Problem mit meinem TWI Interrupt. Irgendwie reagiert es 
nicht. Habe jetzt einige Forenbeiträge durchgelesen und finde einfach 
keinen Fehler mehr. Vielleicht hab ich auch Tomaten auf den Augen! Könnt 
ihr eventuell noch einmal drüber schauen?

Soll ein Multimastersystem werden. Im moment ist noch nichts richtiges 
Implementiert um eine Kollision zu verhindern auch der Puffer ist noch 
nicht wirklich Anwendbar. Aber da ich schon jetzt nicht weiterkomme 
lassen wir dass mal außenvor. Im Moment lasse ich ein Programm auf einem 
Atmega8 und das selbe (natürlich bis auf die TWI Adressen) auf einem 
Atmega32 laufen.

Irgend eine Idee?

Danke schonmal im voraus

Ach ja nochwas?!? Wie hängt man hier mehrere Files an?

von Peter D. (peda)


Lesenswert?

Thomas Frosch schrieb:
> Soll ein Multimastersystem werden. Im moment ist noch nichts richtiges
> Implementiert um eine Kollision zu verhindern

Muß man nicht, das macht die Hardware selber. Der unterliegende Master 
wechselt automatisch in den Slave-Mode, d.h. er kann auch adressiert 
worden sein. Du mußt es nur in der Interrupthandler-Statemachine 
auswerten.


Allerdings habe die AVRs einen äußerst häßlichen Bug als Multimaster:

http://www.robotroom.com/Atmel-AVR-TWI-I2C-Multi-Master-Problem.html

Ob er wenigstens bei den XMegas gefixt wurde, weiß ich nicht.


Peter

von Thomas Frosch (Gast)


Lesenswert?

Hmm den Artikel habe ich bereits gelesen und auf das Problem wollte ich 
dann eingehen wenn es auftritt. Aber im Moment tritt ja nicht einmal das 
Interrupt auf?!?!

Erstmal Danke für die Antwort aber gibt es noch irgend eine Idee? Könnte 
auch sein dass ich die drähte falsch angeschlossen habe gg allerdings 
bin ich mir da ziemlich sicher, dass es so stimmt. Sollte ja kein Thema 
sein! Aber trotzdem kann man eventuell die Übertragung testen?

von Peter D. (peda)


Lesenswert?

Trivialfehler Pullups?

Sind zwar in jedem Datasheet ganz dick eingezeichnet, aber man muß sie 
auch beide bestücken.
Ideal sind 1,8k, da jeder I2C-Chip 3mA können muß.

Mach mal die Statemachine als switch, das ist dann viel besser lesbar, 
als if-else-Monster.


Peter

von holger (Gast)


Lesenswert?

1
TWCR = (1<<TWINT) || (1<<TWSTA) || (1<<TWEN);    //Startbedingung senden

Könnte es sein daß du hier den Interrupt abschaltest?

von holger (Gast)


Lesenswert?

1
TWCR = (1<<TWINT) || (1<<TWSTA) || (1<<TWEN);    //Startbedingung senden

Und || ist auch falsch. Einmal reicht.

von Thomas Frosch (Gast)


Lesenswert?

Ohh ja stimmt switch aber wie kann ich bei switch gleich noch meine 
TWI_Aktion abfragen (TWI_Aktion beinhaltet ob µC gerade sendet oder 
empfängt oder frei ist um etwas von beidem zu machen)
Muss ich da nicht auch wieder eine If anweisung mit einbauen? ob es 
dadurch übersichtlicher wird wenn ich zu dem ganzen dann jeweils switch 
und if habe?!? Oder geht es irgendwie einfacher?

Habe erst 2kOhm Widerstände benutzt nun habe ich diese mal durch 10kOhm 
ersetzt anschließend durch 1,6kOhm -> keine reaktion.

Müssen die auf beide seiten der TWI "Leitung", also an jeden µC? sind im 
moment nur knapp 10cm. Habe ein bereits laufendes TWI system allerdings 
ohne Interrupt da habe ich jeweils einen 4,7kOhm und einen 2kOhm 
parallel geschalten nur auf einer Seite. Meine Leiterlänge ist dabei 
20m. (Ja ich weiss ist etwas lang für TWI aber funktioniert.)

von Thomas Frosch (Gast)


Lesenswert?

Ahh die doppelstriche. Wieder mal ein Typischer Copy Paste fehler. Hab 
den Fehler einmal gemacht und überall hinkopiert. Allerdings ist es mir 
dann aufgefallen und ich habe es überall geändert blos da nicht! 
Super!!!

Allerdings kein effekt!

(1<<TWINT)
hab ich zwar jetzt sicherheitshalber mal rausgenommen funktioniert aber 
immer noch nicht!

Aber bei allen Programmen die ich mit TWI gesehen habe war es so also 
muss es schon passen. Dieser Aktion löscht ja nur das Interrupt Flag. 
Aber dass heißt ja nicht dass kein Interrupt mehr auftreten kann. 
Interrupt wird mit (1<<TWIE) angeschalten. Und das ist bei TWI_Init auch 
so...

von holger (Gast)


Lesenswert?

>Interrupt wird mit (1<<TWIE) angeschalten. Und das ist bei TWI_Init auch
>so...
1
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);    //Startbedingung senden

Und du meinst das TWIE hier gesetzt bleibt?
Das seh ich aber anders.

von Thomas Frosch (Gast)


Lesenswert?

??? Warum wird den hier TWIE gelöscht???? Also ich hab das so aufgefasst 
dass ich mit 1<<TWINT einfach nur dass Interrupt Flag lösche aber nicht 
den TWI Interrupt abschalte??!?

Ist es dann überall falsch 1<<TWINT zu machen??!?! ich muss doch aber 
irgendwie den Interrupt Flag löschen oder?

Gut am Anfang vielleicht nicht. Aber trotzdem ändert nichts dran. Werde 
es noch einmal testen.

von Thomas Frosch (Gast)


Lesenswert?

Ahhhhhhhhhhh sry!!! Ja klaro da fehlt wohl dass hier |=

DANKE!!!

von Thomas Frosch (Gast)


Lesenswert?

Funktioniert! Zumindest wird der Interrupt ausgelöst! Mal sehen was 
jetzt noch so an problemen auftaucht!

von Peter D. (peda)


Lesenswert?

Ich mach das so:
1
ISR( TWI_vect )
2
{
3
  uint8_t twcr_shadow = TWCR;
4
5
  switch( TWSR >> 3 ){          // state 0 .. 0x1F
6
// ...
7
  }
8
  TWCR = twcr_shadow;           // reset interrupt flag
9
}

Alle Aktionen werde per AND/OR auf dem twcr_shadow ausgeführt und am 
Schluß wird durch das Rückschreiben der Interrupt gelöscht.


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.