Forum: Mikrocontroller und Digitale Elektronik Seltsames Blinkproblem


von Erwin (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe hier ein seltsames Problem mit einem kleinen Blinkprogramm
(siehe Anhang).

Die LED blinkt 3mal, dann setzt sie komischerweise für einen Takt aus
und beginnt dann wieder 3mal und so fort. Ich sehe meinen Fehler nicht.


Ratlos Erwin

von Peter S. (peter) Benutzerseite


Lesenswert?

Ich kenn mich mit Bascom nicht aus (kenne nur VB.NET und C), aber das
hier:

Do
 If Umlauf = 0 Then
    Umlauf = 250
    Portd.6 = 1
 End If

 If Umlauf = 0 Then
    Umlauf = 250
    Portd.6 = 0

 End If
Loop

mach keinen Sinn.
Es ist quasi Zufall in welche If-Anweisung er springt. (Jenachdem ob
Umlauf vor dem ersten oder zwischen dem ersten und dem zweiten If 0
wird.

Dim x as Short = 0

Do
 If Umlauf = 0 Then
    Umlauf = 250
    If x = 0 Then
      Portd.6 = 0
      x = 1
    Else
      Portd.6 = 1
      x = 0
    End if
 End If
Loop

von Erwin (Gast)


Lesenswert?

@Peter
Danke erst mal. Jetzt habe ich es auch gesehen. (Vor die Stirn schlag)
Short gibt´s in Bascom nicht, kann ja Bit nehmen.

Danke
Erwin

von Profi (Gast)


Lesenswert?

Man liest ja immer wieder, dass ISRs möglichst kurz sein sollen (damit
andere Interrrupts auch mal drankommen) und man möglichst viel in der
main machen soll.
Aber ob es dabei auf 100ns ankommt? Ich würde in diesem Fall alles in
der ISR erledigen:

Ontimer0:

Timer0 = 6                              'Timer sofort neu laden
Decr Umlauf
if Umlauf >=128 then     Portd.6 = 1    'LED ausschalten
                else     Portd.6 = 0    'LED einschalten

Return

oder
Manchmal ist es hilfreich, sich in das Zahlensystem des µC
hineinzudenken. Für diesen ist die Zahl 250 krumm, lieber ist ihm 256.
Dadurch kannst Du Dir viele Abfragen sparen, da Bytes und Counter von
selbst auf 0 / 255 überlaufen.

Um das zu kompensieren und wieder auf für Menschen gerade (= übliche,
bequeme) Frequenzen kommt, verwendet man auch entsprechende Quarze
(z.B. 2^22 = 4,194304 MHz)

Ontimer0:

' Timer0 = 6                              'Timer sofort neu laden
' Timer durchlaufen lassen
Decr Umlauf
if Umlauf = 128 then
  Portd.6 = 1    'LED ausschalten
  endif
if Umlauf =   0 then
  Portd.6 = 0    'LED einschalten
  endif
Return

Oder

Ontimer0:

' Timer0 = 6                              'Timer sofort neu laden
' Timer durchlaufen lassen
Decr Umlauf
if Umlauf = 0 then  'ergibt halbe Blinkfrequenz
  Portd.6 = NOT Portd.6   'LED togglen
  ' oder
  Portd.6 = 1 - Portd.6   'LED togglen
  ' ich weiß nicht, wie der toggle-Befehl in Bas heißt
  endif

Return


Außerdem: der Timer im CTC-Mode ist unabhängig von der
Interrupt-Response-Time (Laden des Timers mit 6 zu unbekannter Zeit -->
ungenaues Timing, Jittern).

von Erwin (Gast)


Lesenswert?

@Profi
Dieses Stückchen Programm ist nur der Teil eines großen. Ich habe
nur zur Anschaulichkeit den Teil heraus"operiert".

Blöderweise muß ich den Timer0 dafür nehmen, da Timer1 für etwas
anderes gebraucht wird. Ich bin auch an den Quarz gebunden und muß
solche Kunstgriffe machen, da ich einen Sekundenimpuls so nicht anders
kriege.
Irgendwann habe ich mal gelernt, daß man aus der Interruptroutine so
schnell wie möglich wieder "verschwinden" soll, deshalb im
Hauptprogramm der Spaß.
Jetzt zeichne ich mir mal einen Ablaufplan für Deine Vorschläge.
(Lach nicht; das mach ich bei fremdem Code immer so, um mich
reinzudenken.

Danke Dir

Erwin

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.