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?
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
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?
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
1 | TWCR = (1<<TWINT) || (1<<TWSTA) || (1<<TWEN); //Startbedingung senden |
Könnte es sein daß du hier den Interrupt abschaltest?
1 | TWCR = (1<<TWINT) || (1<<TWSTA) || (1<<TWEN); //Startbedingung senden |
Und || ist auch falsch. Einmal reicht.
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.)
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...
>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.
??? 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.
Ahhhhhhhhhhh sry!!! Ja klaro da fehlt wohl dass hier |= DANKE!!!
Funktioniert! Zumindest wird der Interrupt ausgelöst! Mal sehen was jetzt noch so an problemen auftaucht!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.