Forum: Mikrocontroller und Digitale Elektronik ISR mehrfach aufrufen.


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Martin B. (nutnic)


Bewertung
0 lesenswert
nicht lesenswert
Guten Abend,

ich habe einen ATMega32.
Ich habe die Aufgabe eine Steuerung zu schreiben für ein Technikler 
Projekt.

Ich habe eine Entprellung, aus diesem Forum, programmiert.
Die die ISR benötigt.

ISR( TIMER0_OVF_vect )

Jetzt brauche ich aber diese ISR auch für einen Timer.
Der den selben Funktionsaufruf hat.

Also auch:

ISR( TIMER0_OVF_vect )

Wie mache ich das jetzt ich habe zwei mal unterschiedlichen Code ?
Und der Compiler beschwert sich bei mir mit :


Error    Disabling relaxation: it will not work with multiple 
definitions

Vielen Dank schon mal.

Gruß Nutnic

: Verschoben durch Moderator
von Theor (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Leider falsche Rubrik.


Aber gut.

Nun vergiss einfach mal kurz das es um Interrupts geht.

Du hast eine Funktion TuWas (), die irgendwas macht. Z.B. "a = b + 1;".

Dann kommst Du darauf, dass Du noch eine Funktion TuWas () benötigst. 
Die soll "g = 12%k;" tun.

Beide sollen auch immer gleichzeitig, bzw. unmittelbar hintereinander 
aufgerufen werden.

Nun geht das nicht, weil es (in C) nicht zwei Funktion gleichen Namens 
geben darf. Also, was liegt näher als, die Anweisungen beider Funktionen 
TuWas () in einer Funktion TuWas () zu vereinigen?
1
TuWas () {
2
  a = b + 1;
3
  g = 12%k;
4
}

Nun hat man in C ohnehin nicht die Wahl, zwei Funktionen gleichen Namens 
zu schreiben. Aber es geht ohnehin nicht darum.

Es geht vielmehr darum, wie gezeigt, dass zwei "Funktionalitäten" in 
einer Funktion vereinigt werden!

Den Rest kannst Du jetzt vermutlich allein, oder?

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Um die funktionale Trennung hervorzuheben, kann man es aber auch als 2 
Inline-Funktionen schreiben:
1
inline void foo1( void )
2
{
3
  // irgendwas
4
}
5
6
inline void foo2( void )
7
{
8
  // irgendwas
9
}
10
11
ISR( TIMER0_OVF_vect )
12
{
13
  foo1();
14
  foo2();
15
}

von Theor (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Peter D. schrieb:
> Um die funktionale Trennung hervorzuheben, kann man es aber auch als 2

Ich halte diese Variante nicht für eine "funktionale" sondern eine 
"textuelle" Trennung. Funktional geht es ja gerade um Vereinigung, nicht 
um Trennung.

Mein Einwand bezieht sich natürlich nicht auf den Vorschlag selbst, den 
ich für sinnvoll halte, Peter.

von Unverstand (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Erkläsr doch mal einfach, was diese beiden, oder der eine
Code-Schnippsel ISR() und ISR() machen soll!

Wer/was ruft sie auf?
Was für Resourcen sind ihr/ihnen zugeordnet?
Welche Parameter werden übergeben?
Woher weiß/wissen sie, dass Taste A, oder B entprellt werden soll?
Wie soll das funktionieren?

MANCHMAL hilft nachdenken.

Lösung ist VIELLEICHT, dass diese von einem Timer aufgerufene ISR
sich einfach um alle vorhandenen Tasten kümmern muss und irgendwo
den entprellten Tastenzustand für jede Taste bereitstellen muss.

(Machen bis jetzt die meisten so - es sei denn, du präsentierst
ein neues, besseres Verfahren.)

Dazu muss man natürlich ein wenig über saubere Abschreibübungen
hinausgewachsen sein. Oder es mal versuchen!

von posti (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hi

Da Du einen Timer-Überlauf benutzt - sind in beiden Beispielen die Timer 
gleich schnell?
Bei Überlauf gehe ich von dem Wechsel zur Null aus - bliebe die 
Geschwindigkeit.
Diese wird von dem Schnipsel bestimmt, Der den Interrupt schneller 
braucht.

Die langsamere Funktion kannst Du dann entweder nur 'alle X Aufrufe' mit 
verarbeiten, oder der Routine den häufigeren Ablauf beibringen.

Blödes Beispiel: Die Tastenentprellung will nur alle 1024µs aufgerufen 
werden, die andere Routine aber alle 512µs.
Dann entweder die Prüf-Werte der Tastenenprellung verdoppeln und jedes 
Mal mit durchlaufen lassen, oder mit einem Flag mithalten, ob beim 
nächsten Mal die langsame Routine mit ausgeführt werden soll.

Bei Unterschieden größer als 2 reicht ein Flag nicht mehr, bei komplett 
anderen Aufrufzeiten könnte man die zwei Compare-Match Interrupts 
benutzen.
Beim Langsameren wieder hochzählen, bis die Zeit reif ist.
Bei Beiden mußß, da der timer nicht rückgesetzt werden kann, der nächste 
Match-Point jedes Mal berechnet werden.

MfG

von einfalt (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Martin B. schrieb:
> Jetzt brauche ich aber diese ISR auch für einen Timer.
> Der den selben Funktionsaufruf hat.

Dann leg doch die Entprellung auf einen anderen Timer.

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]
  • [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.