PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frage zu Zeitabhängiger Funktion



Henry
28.02.2009, 21:18
Hallo,

ich bin gerade dabei mit BASCOM eine Schalting zu programmieren, die mir später mal die Beleuchtung in einem RC-Modell steuern soll.

Zu dieser gehöhrt z.B. die ansteuerung zweier LEDs als Doppelblitz, wie es bei Einsatzfahrzeugen üblich ist.

Nun habe ich dies zur Zeit über einen Zähler realisiert und steuere die Ausgänge mit IF-Abfragen. (siehe Code)
Da dies im Moment die einzige Funktion ist an der ich tüftel, funktioniert es auch ganz gut.
Nun habe ich aber die Befürchtung, wenn ich weitere Dinge in meinem Programm anstellen möchte (z.B. die Auswertung eines RC-Kanals), das ich dann in Schwieriglkeiten kommen werde was Optik angeht (unregelmäßiges Blinken).
Es sollen vermutlich auch noch andere Ausgänge mit Blitz bzw. Blink funktionen belegt werden.

Kann mir jemand einen Tipp geben wie solch eine Funktion eleganter gelöst werden kann, ohne das sie vom Hauptprogramm beeinträchtigt wird?
Die If-Abfragen in die Interruptroutine zu verlegen ist vermutlich die noch schlechtere Umsetzung.

Hier noch der derzeitige Code:


'--------------------------------------------------------------
' Beleuchtung_M8_test.bas
' Testprogramm für Beleuchtungssteuerung
'--------------------------------------------------------------
$regfile = "m8def.dat"
$crystal = 8000000


Config POrtC = Output
Config PORTB.4 = Output
Config portb.5 = Output

Config Timer0 = Timer , PRESCALE = 64

On Timer0 Tim0_isr

Enable Timer0
Enable Interrupts

Timer0 = 131 'Timerregister auf 156 voreinstellen


Dim zaehler as Integer


Doppelblitz1 Alias PortC.5
Doppelblitz2 Alias Portc.4
KontrollLED Alias PortB.4


Zaehler = 0

Do

If zaehler = 10 or zaehler = 210 then
Doppelblitz1 = 1
End IF

If zaehler = 160 or zaehler = 360 then
Doppelblitz1 = 0
End IF


If zaehler = 410 or zaehler = 610 then
Doppelblitz2 = 1
End IF

If zaehler = 560 or zaehler = 760 then
Doppelblitz2 = 0
End IF

If zaehler >= 1000 then
zaehler = 0
end IF

Loop

'Interruptrotiene Timer0 Overflow
Tim0_isr:
Timer0 = 131 'Timerregister auf 156 voreinstellen
incr zaehler
Return

End

Danke schon einmal für eure Hilfe

TomEdl
01.03.2009, 11:03
Hallo Henry!

Eleganter lässt sich deine Problemstellung lösen, wenn man statt den "If-Then" abfragen die Abfrage "Select Case" benutzt.

Das ganze würde dann so aussehen:


$regfile = "m8def.dat"
$crystal = 8000000


Config PORTC = Output
Config PORTB.4 = Output
Config portb.5 = Output

Config Timer0 = Timer , PRESCALE = 64

On Timer0 Tim0_isr

Enable Timer0
Enable Interrupts

Timer0 = 131 'Timerregister auf 156 voreinstellen


Dim zaehler as Integer


Doppelblitz1 Alias PortC.5
Doppelblitz2 Alias Portc.4
KontrollLED Alias PortB.4


Zaehler = 0

Do

Select Case zaehler
Case 10 to 210 : Doppelblitz1 = 1
Case 160 to 360 : Doppelblitz1 = 0
Case 410 to 610 : Doppelblitz2 = 1
Case 560 to 760 : Doppelblitz2 = 0
Case 1000 : zaehler = 0
End Select

Loop

'Interruptrotiene Timer0 Overflow
Tim0_isr:
Timer0 = 131 'Timerregister auf 156 voreinstellen
incr zaehler
Return

End


Übrigens würde auch dein Programm nicht allzu viel Rechenzeit belegen, da kann man locker noch viele andere Sachen inzwischen machen. Du kannst auch die Taktfrequenz auf 1Mhz runtersetzen, dass spart Strom und reicht auch völlig aus!

Grüße
Thomas
:)

for_ro
01.03.2009, 11:30
@TomEdl
Deine Version ist zwar leichter zu lesen, macht allerdings nicht genau das Gleiche wie seine.
Er hat Umschaltpukte benutzt, z.B. bei 10 und 210 den Doppelblitz1 = 1 setzen, und bei 160 auf 0: bedeutet also, dass zwischen 10 und 159 1 gesetzt ist und zwischen 160 und 209 0, dann wieder von 210-359 1 und über 360 0. Bei sieht das ziemlich anders aus, wie du in deinem Select leicht sehen kannst.

Gruß

Rolf

Henry
01.03.2009, 12:54
Hallo,

Danke euch erst einmal für die Antworten
Rolf hat rect, das würde eine komplett andere Funktion als bei mir ergeben. Prinzip ist aber verstenden.
Aber über Case hatte ich auch schon nachgedacht. Habe gerade auch mal probiert ob statt "to" auch ein "OR" akzeptiert wird. Wird es natürlich nicht, wäre ja auch zu einfach gewesen. Das wäre dann natürlich eine schönere Sache.

Müsste dann halt so aussehen:


Select Case zaehler
Case 10 : Doppelblitz1 = 1
Case 160 : Doppelblitz1 = 0
Case 210 : Doppelblitz1 = 1
Case 360 : Doppelblitz1 = 0
Case 410 : Doppelblitz2 = 1
Case 560 : Doppelblitz2 = 0
Case 610 : Doppelblitz2 = 1
Case 760 : Doppelblitz2 = 0
End SELECT
Die Frage ist nur, ist das von der Bearbeitung her schneller durch als meine ganzen If-abfragen?

EDIT:
Es spart auf jeden Fall schon einmal Speicher, was in meinem Fall wichtiger wäre als Strom Sparen. Beim Strom Sparen kann es sich ja nur um ein paar µA handeln, oder irre ich mich da?

TomEdl
01.03.2009, 14:46
Hallo!

Sry, da hab ich dein Programm wohl falsch gedeutet. Tut mir leid!

Aber Select-Case spart auf alle Fälle Zeit. Ich würde an deiner Stelle trotzdem auf 1Mhz runtergehen, denn bis jetzt nutzt du den µC eigentlich gar nicht richtig aus. Es handelt sich dabei schon um bis zu 10mA, die eingespart werden können.

Gruß
Thomas

Henry
01.03.2009, 15:24
Hallo Thomas,


...
Sry, da hab ich dein Programm wohl falsch gedeutet. Tut mir leid!
...

Das braucht Dir nicht leid zu tun, schließlich kann ja niemend durch die Gedankengänge aller anderen durchblicken ;-)


...
Aber Select-Case spart auf alle Fälle Zeit. Ich würde an deiner Stelle trotzdem auf 1Mhz runtergehen, denn bis jetzt nutzt du den µC eigentlich gar nicht richtig aus. Es handelt sich dabei schon um bis zu 10mA, die eingespart werden können.
...
Habe auch bereits auf Deinen Select-Case Vorschlag (mit meinen Anpassungen) umgestellt und es läuft gut.
Nun werde ich versuchen meinen RC-Kanal dazu bringen und schauen ob der zweite Interrupt die Blinkerei schon aus dem Tritt bringt.
10mA ist natürlich schon eine andere Größenordnung, da gebe ich Dir durchaus Recht.
Ich habe nur bedenken das ich Zählerwerte verliere wenn ich langsamer werde. Probiren kann ich aber mal, vermutlich sind meine Bedenken eher unbegründet.

TomEdl
01.03.2009, 16:02
10mA ist natürlich schon eine andere Größenordnung, da gebe ich Dir durchaus Recht.
Ich habe nur bedenken das ich Zählerwerte verliere wenn ich langsamer werde. Probiren kann ich aber mal, vermutlich sind meine Bedenken eher unbegründet.
Inwiefern? Was kommt da denn noch so an Programm dazu?

Gruß
Thomas
:)

Henry
01.03.2009, 16:19
Als nächstes bin ich gerade dabei eine Auswertung für einen RC-Kanal zu integrieren, Was den µC scheinbar auch nocn nicht aus dem Tritt bringt (trotz mittlerweile 1MHz).
Und dann muss ich mal weiter schauen, evt. noch ansteuern eines Servo.
Ist noch nicht ganz zuende gedact, hauptsächlich erst einmal zum üben und kennenlernen von BASCOM.

TomEdl
01.03.2009, 17:35
Als nächstes bin ich gerade dabei eine Auswertung für einen RC-Kanal zu integrieren, Was den µC scheinbar auch nocn nicht aus dem Tritt bringt (trotz mittlerweile 1MHz).
Und dann muss ich mal weiter schauen, evt. noch ansteuern eines Servo.
Ist noch nicht ganz zuende gedact, hauptsächlich erst einmal zum üben und kennenlernen von BASCOM.
Das geht sich schon noch aus.
Wenns wirklich zu knapp werden sollte, kannst du ja dann später noch auf 4Mhz gehen.

Gruß
Thomas

Henry
01.03.2009, 17:48
...
Wenns wirklich zu knapp werden sollte, kannst du ja dann später noch auf 4Mhz gehen.
...
Da hast Du wohl recht.
Im Moment scheint es noch zu klappen, auch wenn ich mein RC-Signal anlege und damit den Interrupt auslöse.
Ich verzweifel zwar gerade an der Auswertung, aber das wird schon ;-)

Henry
01.03.2009, 20:53
Hallo Thomas,

nun habe ich die Grenze gefunden an der mir die 1MHz nicht mehr reichen ;-)
Ich hatte keine Probleme mit meiner Auswertung, sondern die Interrupts haben sich beeinflußt. Scheinbar wurden die Befehle darin nicht schnell genug abgearbeitet.

An dem Ausgang den ich als Schaltkanal festgelegt hatte war ein deutliches Flackern zu erkennen. Nach der Umstellung auf 8MHz war es weg.
Komme also leider schon am Anfang nicht mehr hin. Aber mit 2 und 4 MHz werde ich es auch noch einmal versuchen.
Leider muss ich da immer einige Anpassungen am Programm vornehmen.