mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Mega128 + avrgcc + twi = Problem


Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
ich verwende das TWI Interface eines mega128 zusammen mit dem avrgcc. 
Die TWI ISR ist bisher so deklariert, das sie durch andere Interrupts 
nicht unterbrochen werden kann. Nun möchte ich aber explizit andere 
Interrupts während der TWI ISR Ausführung zulassen. Dabei habe ich 
folgende Probleme:

1.) Wenn ich die TWI ISR durch folgendes avrgcc Macro unterbrechbar 
mache:
    void TWI_vect( void ) __attribute__( ( interrupt ) );
    Habe ich das Problem, das die TWI ISR in einer Endlosschleife hängen
    bleibt. D.d. sobald in die TWI ISR gesprungen wird, geht der
    Controller wohl davon aus das schon wieder ein Interrupt eingetreten
    ist und springt wieder in die TWI ISR. Das Verhalten scheint mir
    plausibel da das TWINT Bit auch noch gesetzt ist.

2.) Wenn ich in der TWI ISR explizit den TWI Interrupt deaktiviere
    ( TWIE = 0 ) und darauf durch sei( ) die globalen Interrupts wieder
    aktiviere so tritt das Problem von 1.) nicht mehr auf. Die TWI ISR
    wird auch unterbrechbar. Jedoch überträgt das TWI interface nur noch
    Müll.

Irgendwie komme ich überhaupt nicht weiter. Deshalb meine Frage an euch:
Wie bekomme ich es hin, das die TWI ISR des mega128 durch weitere 
Interrupts unterbrechbar wird ? Habe ich irgendwas übersehen ?!

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Edit: Mir ist noch folgendes aufgefallen: Sobald das TWIE Bit auf 0 
gesetzt wird, wird implizit auch das TWSR Register auf 0 gesetzt. Das 
Verhalten ist mir nicht klar ?!

Autor: Marvin M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei den AVRs sind Interrupts von Haus aus nicht unterbrechbar, das muss 
man Softwaremäßig lösen (Interrupt-Freigabe mit SEI).
Abgesehen davon gibt es noch andere Probleme, z.B. Priorisierung (das 
können die AVRs ebenfalls nicht). Der Müll könnte auch durch 
Stack-Probleme zustande kommen - allerdings nur eine Vermutung.
Ich würde versuchen, ohne solche Klimmzüge auszukommen.
Interrupts allgemein werden so kurz wie möglich gehalten, keine 
Warteschleifen etc. in Interrupts - wenn man das beherzigt, muss man 
meist keinen Interrupt unterbrechbar machen.

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deswegen kann man mit dem genannten Macro auch explizit Interrupts in 
ISR´s freischalten. Das Macro macht nichts anderes wie ein sei am Anfang 
der ISR zu einzufügen. Bisher hatte ich nie solche Probleme und setze es 
sehr häufig ein das ISR´s unterbrechbar sind. Nur das TWI Interface 
scheint sich hier anders zu verhalten.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja, bei den AVRs ist es nicht schön gelöst mit den Interruptprioritäten 
(es gibt sie leider nicht).
Und zu allem Übel löschen die Interrupts, die langsam sein dürfen, beim 
Eintritt nicht ihr Interruptflag (UART, I2C, EEPROM).


Ich hab mir daher ne 2.Interruptpriorität in Software gebastelt und zwar 
mit T0.
T0 läuft alle 256 Zyklen über und hält sich selbst an. Damit kann er 
nicht mehr sich selbst unterbrechen. Er wird aber als ISR_NOBLOCK 
definiert und ist damit unterbrechbar.
Dann pollt er alle low priority Interruptquellen und führt die Handler 
aus.
Und zum Schluß startet er sich wieder.

Damit das funktioniert, müssen die high Priority Interrupts kürzer 256 
Zyklen sein.
Und die low priority Interrupts werden bis zu 256 Zyklen verzögert 
ausgeführt.

Ich hab das für ne 8-Kanal Software-PWM mit UART und I2C benötigt.
Funktioniert sogar.
Ich hätts ja lieber mit nem 8051 gemacht und mir den ganzen Aufwand 
gespart, aber die funktional geeigneten NXP LPC9xx sind leider nicht 5V 
kompatibel.


Peter

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, so ähnlich habe ich das auch gemacht. Aber das hilft mir jetzt nicht 
weiter. Keiner eine Idee wie ich die TWI ISR unterbrechbar mache ?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mario wrote:
> Ja, so ähnlich habe ich das auch gemacht. Aber das hilft mir jetzt nicht
> weiter.

Warum nicht?

> Keiner eine Idee wie ich die TWI ISR unterbrechbar mache ?

Wenn Dir die Idee nicht gefällt, denk Dir was anderes aus.
Ich sage ja nicht, daß dies die einzige Lösung ist.
Aber sie funktioniert und ist sauber.


Peter

P.S.:
Man muß einen Timerinterrupt opfern, weil nur diese ihr Flag automatisch 
löschen und damit das SEI schnellstmöglichst ausgeführt werden kann.

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich muss unmittelbar auf das TWI Interface reagieren und habe nicht die 
Zeit eine gewisse Zeit später zu pollen ob ein Interrupt anliegt. 
Gleichzeitig muss ich auf externe Interrupts horchen und darf dort 
keinen "verschlucken".

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du den TWI-Interrupt abschaltest, musst du darauf achten, dass du 
das TWINT-Flag nicht aus versehen löschst, denn dann geht ja das TWI 
wieder auf Sendung:
//also nicht:
  TWCR &= ~(1<<TWIE);
//sondern vl. so (nicht gestestet
  TWCR &= ~(1<<TWIE)|(1<<TWINT));
Wenn das erstmal nach totalem blödsinn klingt, schau(t) noch mal nach 
wie man (die meisten) Interruptflags löscht...

hth. Jörg

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mario wrote:
> Ich muss unmittelbar auf das TWI Interface reagieren und habe nicht die
> Zeit eine gewisse Zeit später zu pollen ob ein Interrupt anliegt.

Ich fürchte, dann hast Du das I2C gründlich mißverstanden.
Das I2C wartet immer auf den langsamsten Teilnehmer (SCL-Stretching).
Und wenn das HW-I2C richtig implementiert ist, kannst Du das auch nicht 
verhindern.

Ich weiß, daß beim PIC das I2C nicht vollständig implementiert ist.
Wenn Du also den AVR mit nem PIC verheiraten willst, hast Du schlechte 
Karten.

I2C von 8051, AVR, ARM7 verstehen sich aber prima (warten aufeinander).


Peter

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jörg:
Genau DAS wars autsch. Vielen Dank für den Tip !

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.