Forum: Mikrocontroller und Digitale Elektronik Wie 2x interrupt verschachteln, MSP430


von Wolle G. (wolleg)


Angehängte Dateien:

Lesenswert?

Nachdem das Problem aus Beitrag "Zählrichtung festlegen" 
gelöst wurde,
gibt es meinerseits ein neues Problem.

Der dort ermittelte Zählerstand entspricht in meinem Vorhaben 
(Motorventil Heizkörperthermostat)  der Ventilstellung. Ist i.O.
In von einem Timer erzeugtem Intervall soll der Ventilstößel um einen 
bestimmten Weg verstellt werden. (hier z.B. die Weglänge von 10 
Umdrehungen) Dazu wird die Anzahl der Umdrehungen über eine 
Lichtschranke an einem Zahnrad des Getriebes gezählt.

Aus meiner Sicht wird aus irgendwelchen Gründen die interrupt-Funktion
interrupt (PORT2_VECTOR)P2anschluss (void)
nicht aufgerufen. (Blitz_gelb fehlt)

Hier aus meiner Sicht die entscheidenden Auszüge aus meinem Programm 
0074g, welches auch komplett im Anhang steht. Im diesem Programm 
funktioniert die Umdrehungsmessung nicht.
hier der Auszug:

void regler (void)
{
  b=0;
  sollwert=424;  //25°C/0,0625=400  416-->26° 384 --> 24°C
  deltatemp = temp16-sollwert;  //temp16 ist die gemessene Temp.,
                                      //  hier z.B 416 --> 26°C
  P4OUT &=~BIT0; //LED rot EIN, Kontrolle, ob regler bearbeitet wird
  warten2();
  deltatemp_anzeigen_roh();// in "DS10-g0073-LMK62-SD.h" enthalten
  //if (deltatemp  > 2)ventil_schliessen_regler();
  if (deltatemp  < (-2))ventil_oeffnen_regler();
  P4OUT |=BIT0;                // LED rot AUS
}

void ventil_oeffnen_regler (void)
      {
       AUF=1;
       zaehlerstand_anfang = zaehlerstand;
       while(zaehlerstand <(zaehlerstand_anfang + umdrehungen))
      {
       P2OUT &=~BIT4; // ZU fahren
       }
       AUF=0;
       P2OUT |=BIT4;

      }
interrupt (TIMERA0_VECTOR) Timer_A(void)
       {
       Blitz_gelb();                   //Kontrollblitz
       temp_messung_starten();
       b=b+1;
       if (b >3)regler();

       DS18B20_lesen_DS18B20nr15();
       DS18B20_lesen_DS18B20nr16();

       temp_15_anzeigen();
       temp_16_anzeigen();
       zwischenspeichern_1();
       ausgabe_restsektor();
       auf_SD_karte_schreiben();
       }

interrupt (PORT2_VECTOR)P2anschluss (void)
{
   Blitz_gelb();

   if (AUF==1)                // aufwärts zählen
{
    zaehlerstand = zaehlerstand +1;
}
   if (ZU==1)
{
   zaehlerstand = zaehlerstand -1;
    }
  zaehlerstand_anzeigen();
  P2IFG&=~BIT5;
}
In der Version Programm 0075g(läuft)  werden dieselben Funktionen für 
"Ventil schließen" bzw. "Ventil öffnen" erfolgreich verwendet, aber im 
Gegensatz zu 0074g(läuft nicht)  werden die Vorgänge über Taster 
ausgelöst und im Timer wurde die Zeile „regler“ herausgenommen.
Bei 0074g(läuft nicht) soll das Ventil nach jeweils 4 Timertakte 10 
Umdrehungen öffnen.
Das Ventil öffnet zwar, wenn die Bedingung für deltatemp. erfüllt ist, 
aber es ändert sich nicht der Zählerstand. (kein Blitz)    mein 
Hauptproblem !!
Kann es sein, dass der Timer den interrupt (PORT2_VECTOR)P2anschluss 
(void)
verhindert?

Hoffentlich habe ich mich verständlich genug ausgedrückt.

: Bearbeitet durch User
von no nested intr (Gast)


Lesenswert?

wolle g. schrieb:
> Hoffentlich habe ich mich verständlich genug ausgedrückt.

Nein, aber zur Überschrift:
Der MSP430 hat eigentlich keine nested *interrupts* . Während der ISR 
Ausführung sind Interrupts gesperrt. Aber du kannst in der ISR die 
Interrupts per Befehl wieder freigeben.
-> Steht alles im Family User Guide -> RTFM ;->

Beispiele gibt es im Netzt genug.

von no nested intr (Gast)


Lesenswert?

wolle g. schrieb:
> interrupt (TIMERA0_VECTOR) Timer_A(void)
>        {
>        Blitz_gelb();                   //Kontrollblitz
>        temp_messung_starten();
>        b=b+1;
>        if (b >3)regler();
>
>        DS18B20_lesen_DS18B20nr15();
>        DS18B20_lesen_DS18B20nr16();
>
>        temp_15_anzeigen();
>        temp_16_anzeigen();
>        zwischenspeichern_1();
>        ausgabe_restsektor();
>        auf_SD_karte_schreiben();
>        }

Au, Backe! Was ist denn das? Die ISR ist viel zu lang!
Der ganze Kram gehört in den Hauptthread. In die ISR gehört nur die 
Freigabe (z. B. ein Flag), um den Kram per if zu Klammern.

Nested Intr helfen dir nicht!!!

von Willi Wolf Wunderlich (Gast)


Lesenswert?

Es gibt da eine magische Schrift, man nennt sie Datenblatt. Lies es!

von Clemens L. (c_l)


Lesenswert?

>     while(1)
>     {
>     if (P2IN&BIT0) ventil_oeffnen_regler ();        // Taste Ventil-AUF gedrückt
>     if (P2IN&BIT1) ventil_schliessen_regler ();     // Taste Ventil-ZU gedrückt
>    }

Soll das Ventil einmal pro Tastendruck geöffnet/geschlossen werden, oder 
immer wieder so lange, wie die Taste gedrückt ist?

von Peter D. (peda)


Lesenswert?

no nested intr schrieb:
> Au, Backe! Was ist denn das? Die ISR ist viel zu lang!

Insbesondere das DS18B20 wandeln und lesen kostet tierisch Zeit. Ich 
mache es daher so, daß das 1-wire in einer eigenen Statemaschine läuft. 
Ein State macht dann z.B. das Reset bzw. ein Byte lesen oder schreiben, 
so daß es spätestens nach ~500µs zur Mainloop zurück kehrt.

von Wolle G. (wolleg)


Lesenswert?

Clemens L. schrieb:
> Soll das Ventil einmal pro Tastendruck geöffnet/geschlossen werden, oder
> immer wieder so lange, wie die Taste gedrückt ist?
Das ist eigentlich nur eine Kontrollhilfe, die mir zeigt, dass die 
Funktionen
void ventil_oeffnen_regler (void) bzw schliessen
richtig funktionieren. (hier im Beispiel 10 Umdrehungen eines 
Getriebezahnrades)
und dass der Zähler für den Stellweg in
interrupt (PORT2_VECTOR)P2anschluss (void)
ausgeführt wird. (Kontrollblitz)
Das läuft ja schon im Programm 0075g, also i.O.

Die gleiche Funktionen sollen jetzt vom Timer angestoßen werden (0074g). 
Dazu wurde die Funktion " regler (); " in den Timer eingebaut.
Das Anstoßen funktioniert auch, aber der Zähler
 „interrupt (PORT2_VECTOR)P2anschluss (void)“
arbeitet nicht, sodass das Ventil bis zum Anschlag durchläuft.
Deshalb noch einmal MEIN Hauptproblem wie schon in meinem obigen Beitrag 
genannt:

„Das Ventil öffnet zwar, wenn die Bedingung für deltatemp. erfüllt ist,
aber es ändert sich nicht der Zählerstand. (kein Blitz) „

Peter D. schrieb:
> Ich
> mache es daher so, daß das 1-wire in einer eigenen Statemaschine läuft.
> Ein State macht dann z.B. das Reset bzw. ein Byte lesen oder schreiben,
> so daß es spätestens nach ~500µs zur Mainloop zurück kehrt.

Als Programmierlaie verstehe davon nichts.(Statemaschine)

>Insbesondere das DS18B20 wandeln und lesen kostet tierisch Zeit.

Deshalb beträgt die Taktzeit bei mir > 1s.

Noch einmal mein Hauptziel:
Es soll ein Heizkörper einer normalen Warmwasserheizungsanlage über ein 
Ventil mittels elektronischem Thermostatkopf, der als PI(D)-Regler 
konzipiert ist, geregelt werden. Die kleinste Stellwegänderung 
(Ventilhub..) sollte bei 0,01mm liegen.

: Bearbeitet durch User
von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Peter D. schrieb:
> … daß das 1-wire in einer eigenen Statemaschine läuft.
> Ein State macht dann z.B. das Reset bzw. ein Byte lesen oder schreiben,
> so daß es spätestens nach ~500µs zur Mainloop zurück kehrt.

+1

Und mit einem 32768Hz-Uhrenquarz am MSP430 kann man dann sogar noch die 
einzelnen Flanken-Wechsel ganz einfach per Interrupt auslösen. So hatte 
ich das mal gemacht, siehe Bild in 1-wire als Hausbus.

von Clemens L. (c_l)


Lesenswert?

wolle g. schrieb:
> Als Programmierlaie verstehe davon nichts.(Statemaschine)

Statemachine
https://de.wikipedia.org/wiki/Endlicher_Automat

: Bearbeitet durch User
von Theor (Gast)


Lesenswert?

Der Artikel https://www.mikrocontroller.net/articles/Interrupt könnte 
ein Einstieg in die Verwendung von Interrupts sein. Ein paar der 
wesentliche Basisthemen sind dort behandelt und einige Begründungen für 
bestimmte Aussagen vorhanden.

Eine präzise und ausführliche Begründung für die Vermeidung von 
verschachtelten Interrupts würde ich an Deiner Stelle zusätzlich im 
Internet suchen. Gibt es sicher.

von Peter D. (peda)


Lesenswert?

wolle g. schrieb:
> Als Programmierlaie verstehe davon nichts.(Statemaschine)

Das ist auch nicht schnell zu erklären. Statemaschines sind ein 
eleganter Weg, mehrere Sachen scheinbar parallel auszuführen.
Von alleine macht der MC nichts parallel, sondern führt alles 
nacheinander aus. D.h. die langsamste Task bremst alle anderen aus.
Du must Dein Programm erstmal unterteilen in zeitkritische Sachen und 
den Rest. Alles nicht zeitkritische muß raus aus den Interrupts, daran 
führt kein Weg vorbei.

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Peter D. schrieb:
> Alles nicht zeitkritische muss raus aus den Interrupts, daran
> führt kein Weg vorbei.

+ 1

Und das machst Du, in dem Du im Interrupt z.B. nur ein Bit oder eine 
Boolean-Variable (das Flag) auf TRUE bzw. 1 setzt, so wie
no nested intr schrieb:
> In die ISR gehört nur die Freigabe (z. B. ein Flag)

In der "Main-Loop" lässt Du dann alles nacheinander abarbeiten, mit 
if(<Flag ist gesetzt>) { …; <lösche Flag>}.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.