Timer mit 12 Minuten Länge

Gast #146358
Hi Leute,

wollte mal fragen, ob mir jemand bei meinem Timing Problem helfen
kann:

Ich will eine Heizung schalten (Jede Sekunde einen Temperaturwert
abfragen). Falls die Temperatur dann den gewünschten Wert hat, soll die
Heizung ausgeschaltet werden. Allerdings soll die Heizung höchstens 12
Minuten laufen, auch wenn der Temperaturwert nicht erreicht wird. Wie
Programmiert man denn sowas?
Muss ich in die ISR des Timers eine globale Variable setzen, die dann
inkrementoert wird und bei 720 Durchläufen eben abschaltet. Oder hat
jemand eine bessere Idee?

Vielen Dank für eure Antworten

     Mike
Gast #146361
volatile bedeutet, daß der Compiler davon ausgehen soll, daß der Inhalt
der Variablen sich "hinter seinem Rücken" ändern kann.
Sonst könnte der Compiler beispielsweise ein Konstrukt wie

while (Variable == wert)
  Ausdruck;

dahingehend optimieren, daß "Variable == wert" nur einmal überprüft
wird und danach eine schöne Endlosschleife ausgeführt wird.
Ist Variable aber als volatile deklariert, wird mit Sicherheit bei
jedem Schleifendurchlauf getestet.
Gast #146362
Damit wird dem Compiler gesagt, dass diese Variable ihm "unterm Arsch"
geändert werden kann, d.h. ohne dass es aus seiner Sicht logisch wäre.

Der Compiler weiss nix von einem Interrupt, und wann und ob dieser
aufgerufen wird.
Wenn du also schreibst:

uint16_t counter;

main()

counter=0;

INTERRUPT...
{
counter++;
}

for (;;)
{
if (counter>720)
 heizungaus();

}

Dann wird der Compiler beim optimieren denken:
Hmm, counter wird auf 0 gesetzt, und dann im Programmverlauf nie mehr
geändert (weil ja niergends ein Aufruf der Interrupt Routine steht),
also kann ich den Vergleich gleich weglassen und heizungaus() immer
ausführen.
Oder er hält counter in einem Register, und die ISR ändert die Variable
im SRAM, aber im main() wird der Wert aus dem Register weiterverwendet.

Also, alle globalen Variablen (und auch lokale statische) die in einem
Interrupt verwendet werden immer mit volatile deklarieren.

Sonst wirst du tagelang Fehler suchen...
Gast #146364
Soll natürlich heissen:


uint16_t counter;

INTERRUPT...
{
 counter++;
}

void main(void)
{
 counter=0;

 for (;;)
 {
   if (counter>720)
     heizungaus();

 }

}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 21 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.