www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik I2C Übertragung unterbrechen (z.B. ATmega16 etc.)


Autor: Matthias Thüringer (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich bin gerade dabei ein minimales "Multitasking" aufzubauen. Ein Task 
davon soll eine Kommunikation über die TWI Schnittstelle abhandeln. Die 
Kommunikation an sich funktioniert soweit. Zum Testen sollte mein 
Programm prinzipiell so aussehen:
Der Slave befindet sich in einer Endlosschleife, in der er zyklisch 
nachsieht, ob es was zu tun gibt oder nicht. Bei einem Interrupt sichere 
ich mir das TWI Status Register(TWSR). Setze ein Flag, dass es jetzt 
etwas zu arbeiten gibt und verlasse die ISR wieder. In der Hauptschleife 
"sieht" der Task "jetzt gibts was zu tun" und arbeitet alle weiteren 
nötigen Schritte ab. Wenn er fertig ist, wartet er wiederum bis der 
nächste Interrupt auftritt.
Soweit die Idee. Mein Problem ist aber, das nach dem Verlassen der ISR 
sofort wieder in die ISR gesprungen wird, und wieder und wieder.... 
Irgendwann kommt doch die Abarbeitung des Tasks in der Hauptschleife 
dran und die Kommunikation geht weiter.
Ihr könnt euch vorstellen wie lange! Genau, bis zum nächsten Interrupt!
In den Datenblättern ist beschreiben, dass es nach dem Interrupt die 
jeweilige definierte Softwareaktion auszuführen ist. Mir ist schon klar, 
dass der Interrupt nach dem Verlassen der ISR immer noch ansteht und das 
der Grund ist warum er wieder in die ISR springt. Der logische Schritt 
war die Interruptflags in dem TWI Control Register(TWCR) zu bearbeiten. 
Also TWIE usw. zurückzusetzen. Fehlanzeige! Sobald in diesem Register 
irgendetwas verändert wird, fühlt sich das TWI-Modul veranlasst, mit der 
Abarbeitung fortzufahren(z.B. den Inhalt des Adressregisters auf den Bus 
zu legen). Wenn das TWI Modul mir somit keine Möglichkeit lässt, selbst 
zu entscheiden, wann ich die weitere Abarbeitung vornehme, dann hat der 
Interrupt für mich nicht wirklich einen nutzen.
Ich habe den Beginn der Übertragung mit dem Oszi aufgezeichnet und 
angehängt.
Der gelbe Graph stellt die Sprünge in die ISR dar. Also jeder 
Flankenwechsel bedeutet einen Sprung in die ISR.
Rosa ist die Datenleitung und Grün der Takt.

Hat jemand eine Idee, wie ich es schaffe nach dem Verlassen der ISR 
nicht wieder in die ISR zu springen? Also selbst enscheiden kann, wann 
es weiter geht?

Autor: Klaus 2m5 (klaus2m5)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du in der Hauptschleife ein Flag abfragst, ob ein TWI-Interrupt 
stattgefunden hat, dann kannst Du auch gleich das TWINT im TWCR pollen. 
Der Interrupt ist vollkommen sinnlos.

Autor: Matthias Thüringer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast schon recht. Der Programmaufbau ist zum testen gedacht gewesen. 
Später soll nicht in einer Endlosschleife eine Variable gepollt werden, 
sondern andere Tasks laufen die bestimmte (u.a. zeitliche)Bedingungen 
einhalten müssen. Wenn ich aber in der TWI-Kommunikation "festsitze" 
kommen andere Tasks die eine höhere Priorität haben nicht dran. Evtl. 
kann dann die Echtzeitbedingung nicht eingehalten werden. Ich habe ein 
bestimmtes Zeitfenster, in der die TWI-Kommunikation laufen darf und 
kann. Wenn der TWI-Interrupt während der Bearbeitungszeit eines anderen 
Tasks auftaucht, muss er laut Vorgabe warten bis er dran kommt. Also in 
der ISR alles nötige sichern und sie wieder verlassen. Die Bearbeitung 
des Interrupts hätte dann in dem für ihn vorgesehene Zeitfenster 
passieren sollen.
Mal sehen wie groß die ISR wird, wenn alles in ihr verarbeitet wird und 
wie lange ich in ihr aufgehalten werde...

Autor: Klaus 2m5 (klaus2m5)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn die Hauptschleife zu bestimmten Zeiten nicht unterbrochen werden 
darf, dann solltest Du in dieser Zeit alle Interrupts disablen (CLI). In 
der ISR muss nichts gesichert werden, denn ohne Abarbeitung des 
anstehenden Status geht auch von selbst nichts weiter. Nach SEI werden 
sofort die anstehenden Interrupts abgearbeitet.

Du könntest Programmteile mit höherer Priorität auch selbst als 
Interrupt starten, dann werden sie auch nicht unterbrochen. Dies kann 
durch Timer oder I/O Interrupt (Du setzt selbst die Bedingung an einem 
I/O-Pin, der dann den Interrupt auslöst) geschehen.

Wenn nur ein Teil der Interrupts verhindert werden soll, wirds beim AVR 
schwierig, denn Prioritäten bei Interrupts kann der AVR nicht.

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.