Programmierung mit Interrupts

Gast #2528414
Hallo,

ich habe noch nicht soviel Erfahrung mit Interruptprogrammierung und 
wollte zur Sicherheit mal nachfragen, wie ihr dieses Problem lösen 
würdet.

Aufbau eines bestehenden Programms
1
Interruptroutine()
2
{
3
  //Abfrage der unterschiedlichen Gerätefunktionien
4
  //incl. Ausgabe auf dem Display
5
}
6

7
main()
8
{
9
if(Taste)
10
 {
11
    #asm("CLI")
12
    Standby_Anzeige();
13
    #asm("SEI")
14
 }
15
}

Nun möchte ich den Code so umbauen, dass der Kontroller auch während der 
Standby_Anzeige die Interruptroutine durchläuft und bei Alarm die 
Standby_Anzeige automatisch beendet (sonst wird sie nach einer 
definierten Zeit automatisch beendet).

Dazu habe ich mir gedacht, dass ich das Abschalten des Interrupts vor 
der Standby_Anzeige entferne und eine Globale Variable "Standby_Aktiv" 
einführe.
Diese wird vor dem Eintritt in die Standby_Anzeige auf 1 gesetzt und bei 
Verlassen wieder auf 0. Diese Variable "Standby_Aktiv" wollte ich nun in 
der Interruptroutine vor jeder Ausgabe am Display abfragen.
Ich hab das auch getestet, aber es klappt nicht!! :-(

Wie löse ich dieses Problem richtig???
@  Sarah (Gast)

>ich habe noch nicht soviel Erfahrung mit Interruptprogrammierung

Wie man es sinnvollerweis macht, siehe Interrupt.


>Interruptroutine()
>{
>  //Abfrage der unterschiedlichen Gerätefunktionien
>  //incl. Ausgabe auf dem Display

Falsch, siehe Artikel oben. Ausgaben gehören nicht in den Interrupt.

>main()
>{
>if(Taste)
> {
>    #asm("CLI")
>    Standby_Anzeige();
>    #asm("SEI")

Naja, etwas unglücklich formuliert. Man muss aber halt Daten atomar 
zwischen Interrupt und Main austauschen.

>Nun möchte ich den Code so umbauen, dass der Kontroller auch während der
>Standby_Anzeige die Interruptroutine durchläuft

Das tut er, wenn man es richtig macht. Siehe oben.

> und bei Alarm die
>Standby_Anzeige automatisch beendet (sonst wird sie nach einer
>definierten Zeit automatisch beendet).

Macht man mit einer Statemachine.

MfG
Falk
Gast
OK, gibt es eine einfache Möglichkeit ein "solch falsch aufgesetztes 
Programm" mit wenig aufwand (ohne es komplett umzuschreiben) zum Laufen 
zu bekommen?
Gast
Zu was sollte es gut sein, Fehler immer wieder zu machen, und nicht 
einfach mal was richtig zu programmieren?

Mit fällt nur Faulheit oder Zeitmangel ein. Beides keine guten Hilfen 
bei der Programmierung.
Gast
Ja, da hast du recht.
Aber abgesehen davon, dass man keine Ausgaben in der Interruptroutine 
machen soll, warum funktioniert meine "Sperrvariable = Standby_Aktiv" 
nicht und obwohl ich diese nach Verlassen der Standby_Anzeige() wieder 
auf 0 setze?
Gast
> machen soll, warum funktioniert meine "Sperrvariable = Standby_Aktiv"

Ohne Quelltest kann man maximal raten: Wenn die Funktion eine Abfrage 
(==) sein soll, dann ist die Zuweisung (=) falsch.
Sarah schrieb:
> OK, gibt es eine einfache Möglichkeit ein "solch falsch aufgesetztes
> Programm" mit wenig aufwand (ohne es komplett umzuschreiben) zum Laufen
> zu bekommen?

Das gute ist, dass bei einer Umorganisation viele Codeteile oft einfach 
übernommen werden können. Zb war es wahrscheinlich ziemlich 
zeitaufwändig das Schema der Anzeigen (was wird wo ausgegeben) 
auszuknobeln. Das kann ja alles so bleiben wie es ist. Es passiert nur 
an einer anderen Stelle im Programm.
Berechnungen werden ja nicht ungültig, nur weil sie an einer anderen 
Stelle passieren. etc. etc.

D.h. Bei Programmen in der Größenordnung, wie sie in einem kleinen µC 
typisch sind, ist das Neuaufsetzen gar nicht sooooo viel Aufwand wie es 
zunächst klingt.

Erst mal den Rahmen grundsätzlich neu machen und dann schaun welche 
Codestellen aus dem alten Programm mehr oder weniger 1:1 ins neue 
Programm ev. an eine andere Stelle eingepasst werden können.

Falk hat das Stichwort schon genannt: Mit einer Statemachine kriegt man 
fast alles vernünftig in den Griff.
Sarah schrieb:
> Diese Variable "Standby_Aktiv" wollte ich nun in
> der Interruptroutine vor jeder Ausgabe am Display abfragen.
> Ich hab das auch getestet, aber es klappt nicht!! :-(

Kann nicht klappen.
Der Interrupt merkt sich ja die Ausgaben nicht, d.h. sie fehlen einfach.

Eine Ausgabe macht man üblicher Weise nur en einer Stelle, vorzugsweise 
am Ende der Mainloop. Und dann in einem festen Zeitraster (z.B. 200ms), 
damit die Anzeige nicht wild flackert und der Nutzer sie ablesen kann.
Muß ein Interrupt was ausgeben, schreibt er das in einen Displaypuffer, 
denn dann die Mainloop ausgibt.

Man kann auch generell eine Displaypuffer nehmen und ein Timerinterrupt 
gibt immer ein Zeichen daraus aus.


Peter

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.