Forum: Mikrocontroller und Digitale Elektronik 8051 in ISR wird Output_pin nicht immer gesetzt


von KernoKopp (Gast)


Lesenswert?

Hallo Gemeinde,

bin noch nicht so fit im Programmieren.

Controller AT89C2051
Sprache C

Mit Timer 0 und Timer 1 wird eine PWM erzeugt.
Eine externe Schaltung löst Interrupt an Port (P3.2) aus und in der ISR 
wird eine LED hoch bzw. runter gedimmt.

In der ISR wird Timer 0 gestartet (somit die PWM gestartet) und auch 
wieder gestoppt, sobald die ISR durchlaufen ist.

Auszug ISR:
1
void Extern0_ISR (void) interrupt 0
2
{
3
  TR0 = 1;   // Timer 0 wird gestartet
4
  PWM_ON^=1; //schaltet bei Eintritt zwischen den IF - Anweisungen hin und her
5
6
  if(PWM_ON) // erhöht die Leuchtkraft bix max
7
  {
8
    for(pwm_value=255; pwm_value>=1; pwm_value--)
9
      { 
10
        TH1 = pwm_value;
11
        delay(500);
12
      }
13
14
    TR0 = 0;        // Timer 0 wird gestoppt
15
    delay(20);      // auf was muss ich hier warten????
16
    PWM_output=0;   // soll dann maximale Leuchtkraft erhalten    
17
  }
18
19
  if(!(PWM_ON))     // reduziert die Leuchtkraft bis leichtes Dimmen
20
  {
21
    for(pwm_value=1;pwm_value<=230;pwm_value++)
22
    {
23
      TH1 = pwm_value;
24
      delay(500);
25
    }   
26
  }
27
28
}


Es wird mit jedem externen Signal zwischen den beiden if-Anweisungen 
getoggelt.
TH1 ist das TimerRegister, in welches die Pulsweitenwerte geladen 
werden.
Die 1.Anweisung erhöht die Leuchtkraft.
Die 2. reduziert wieder die Leuchtkraft.
Das reduzieren der Leuchtkraft in if-Anweisung 2 läuft sauber.

Die 1. if-Anweiung macht nicht immer was sie soll.
Sie erhöht die Leuchtkraft.
Ist die maximal Leuchtkraft erreicht, sollte der PWM_output - Port, nach 
abschalten des Timers, aktiv bleiben. doch mal bleibt er es manchmal 
nicht.
Der Timer kann abgeschaltet werden, da bei maximaler Leuchtkraft, keine 
PWM
gebraucht wird.
Ich habe ein Delay eingebaut, das reduziert die Aussetzer, aber 
beseitigt sie nicht vollständig.

Woran liegt das?
Muss ich was berücksichtigen, damit
1
PWM_output=0;
 (Low-Aktiv) immer ausgeführt wird?

Mfg KernoKopp

von R. W. (quakeman)


Lesenswert?

Also um ehrlich zu sein finde ich deine PWM Routine etwas seltsam. Es 
würde mich sogar wundern, wenn diese ISR genau das machen würde, was du 
haben willst.
Bezieht sich die "delay" Funktion auf eine von dir geschriebene Funktion 
oder auf eine Basisfunktion einer Library?
Das du "Aussetzer" hast, welche mit einem "delay(20)" an dieser Stelle 
geringer werden ist schon sehr seltsam. Du solltest mal den gesamten 
C-Code als Dateianhang posten um einen besseren Überblick über die 
Funktionsweise zu erhalten.

Ciao,
     Rainer

von Xmega User (Gast)


Lesenswert?

will jetzt nicht den Stil kritisieren, nur genereller Hinweis das eine 
ISR so flott wie möglich sein sollte und ein Delay, also aktives Warten 
nicht zu empfehlen ist. Klar "manchmal" muss man solch hässliche Dinge 
tun, sollten aber vermieden werden.
Ansonsten noch der Hinweis, das ein PWM Ausgang beim Anhalten des Timers 
nicht zwingend auf 0 oder 1 steht ! Also wenn die PWM gestoppt wird, am 
besten den PWM Mode deaktivieren und den Port auf den gewünschten 
Zustand setzen, da die PWM Funktion die I/O Funktion normalerweise 
ausser Kraft setzt... evtl. hilft das!

Gruss

von Peter D. (peda)


Lesenswert?

Der AT89C2051 hat keine HW-PWM, Du mußt schon zeigen, wie Du die SW-PWM 
machst.
Warscheinlich mit hoher Priorität, da Du ja im externen Interrupt 
elendig lange hängen bleibst.
Und dann haut der/die Timerinterrupt(s) dazwischen, wo Du es nicht 
erwartest.


Peter

von KernoKopp (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

hier im Anhang mal der gesamte Code.

@ Peter:
Die Priorität der Timer habe ich hoch gesetzt. Ohne dem gehts garnicht.

@ Fox Mulder:
Das "delay" ruft ein Funktion auf.
Ich dachte mir, dass das keine schöne Lösung ist. Das Delay hatte ich 
nur eingesetzt um zu sehen und verstehen, ob ich da noch auf was warten 
muss.
Das ein Flag gelöscht wird oder so.

@ XMega User:
Der Ausgangsport wird durch PWM_output=0, am Ende der If-Anweisung 
aktiviert

@Peter: Ist dein code der PWM8CH.C51 auch zu Dimmen geeignet, wenn noch 
andere Sachen laufen?


Danke Kerno

von Peter D. (peda)


Lesenswert?

KernoKopp wrote:
> @Peter: Ist dein code der PWM8CH.C51 auch zu Dimmen geeignet, wenn noch
> andere Sachen laufen?

Ja natürlich.

Es ist etwas Überlegung notwendig, um Programme so zu schreiben, daß 
nicht nutzlos irgendwo gewartet wird und dadurch andere Prozesse 
verhungern.

Wenn Wartezeiten benötigt werden, dann wird zur Main-Loop zurückgekehrt 
und das nächste mal wieder geprüft, ob die Wartezeit (per Timerinterrupt 
gezählt) vorbei ist.

Wenn man so programmiert, dann staunt man richtig, welche Menge an 
unterschiedlichen Tasks so ein kleiner MC quasi gleichzeitig ausführen 
kann.


Peter

von KernoKopp (Gast)


Lesenswert?

Also kurz gesagt, der Code ist Schrott.
Dennoch Hut ab 8051.

;o)

Ich versuche einen anderen Weg zu finden.

Danke an alle.

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.