-
hi,
wenn in einem prog eine oder mehrere funktionen nach zeit x ausgeführt werden müssen, ist es schon sinnvoll, einen timer dafür zu verbrutzeln. der kann ja das gesamte zeitmanagement eines progs. steuern.
z.b.
timer-int alle 1/10 sec.
im int eine var um 1 hochzählen lassen.
bei var=30 (beispiel) led an
bei var=60 led wieder aus
' restliche zeitkritischen sachen oder nach umgebungsbedingungen
bei var=x und bedingung=y flag für anderes ereignis setzen
nach 'längstem ereignis' variable wieder nullen
so wird zwar ein tiomer verbraten, aber kein wait verwendet.
den int kann man schon kurz halten, der verbrät nur sehr wenig zeit.
grüssens, harry
-
Sehe ich das richtig, das WAIT X einfach nur viele NOP in den AVR schreibt?
Es gibt ja Programme, in denen man nur eine gewisse Anzahl von verschiedenen Wartezeiten hat. z.B. WAITMS 150/500/1000, diese aber oft einsetzt. 150 nach Tastenabfragen, 500 und 1000 für LEDs.
Wenn meine erste Vermutung richtig ist, würde der flash ja irgendwann fast nur noch mit NOPs beschrieben sein. Wie wäre es denn, wenn man einfach wie hier jetzt drei SUBs erstellt und an den jeweiligen Stellen dort hinspringt? Sprungbefehle verbrauchen ja nicht so viele Programmzeilen wie sinnlose NOPs.
Wenn es absolut Zeitkritsche Anwendungen sind, muss man halt zuvor noch die Zeiten für die Sprünge abziehen, aber ansonsten würden ein paar µs ja nicht viel ausmachen.
PS: Mark von MCS empfiehlt an Stelle von WAIT 1 WAITMS 1000 zu verwenden, weil das weniger Programmspeicher belegt.
-
Hallo,
dieser Thread ist zwar schon etwas älter, aber wer weiß vielleicht antwortet ja doch jemand auf meine Frage ohne einen neuen Thread aufmachen zu müssen...
Also ich habe eigentlich ein ziemlich ähnliches Problem.
Ich hab eine Uhr gebastelt, mit einem ATmega 16 und ner LCD (1602a), ein Wecker ist auch dabei und da sind wir auch schon beim Problem:
Ich möchte die Alarmdauer festlegen, sagen wir mal erst mal auf 5 Minuten, also 300 Sekunden.
Wenn bei meiner Uhr der Alarm (Wecker) ausgelöst wird, dann wird ein Pin frei geschalten...
Ich hab erstmal ganz einfach folgenden Code genommen:
If Alarm_stat = 1 Then
Portc.1 = 1
wait 300
Portc.1 = 0
End if
Tja, wenn ich das in mein Code einbaue, dann pausiert der ATmega 300 Sekunden lang.
In dieser Zeit bleibt meine Uhr stehen, nach 300 Sekunden geht die Uhr ganz normal weiter...
Wie könnte Portc.1 für eine gewisse Zeit auf 1 setzen, ohne diesen Befehl in die Do/Loop zu schreiben?
Oder wie würdet ihr die Alarmdauer festlegen?
Viele Dank schonmal!
-
Du hast doch eine Uhr drin. Demnach auch irgendwo eine Sub, welche jede Sekunde aufgerufen wird. Ich mache es immer so:
PseudoCode:
Code:
do
...
...
...
loop
end
sectic:
if alarmzeit=zeit then alarmdauer=300
if alarmdauer>=1 then
decr alarmdauer
set ausgang
else
reset ausgang
endif
return
-
Ja habe ich, nämich bei Config Dcf77 am Ende dieser Zeile steht bei mir Gosub = Sectic
Ist dann Alarmdauer eine neue Variable?
Anscheined schon, werds gleich mal ausprobieren...
-
Stimmt der folgende Code-Teil in deinen Augen?
Code:
Dim Alarmdauer As Word
Alarmdauer = 0
Config Portb.1 = Output ' Wecker
Portb.1 = 1 ' Wecker
Wecker Alias Portb.1
Do
Loop
End
Sectic:
If _hour = Alstd And _min = Almin Then Alarmdauer = 3
If Alarmdauer >= 1 Then
Decr Alarmdauer
Set Wecker
Else
Reset Wecker
End If
Return
Es funktioniert zwar, aber die Wecker-LED geht nach einer Sekunde wieder aus statt nach 3 Sekunden...
Ist es ok, when ich _hour = Alstd And _min = Almin schreibe?
Ich frag deswegen, weil in deinem Code _hour und _min in eine Variable stecken...
Aber wenigstens ist der Hinweiß, dass das ganze auch in Sectic zu realisieren ist, ziemlich cool! Vielen Dank...
-
Womöglich wird die Sectic öfter in der Sekunde aufgerufen. Da in meinem Beispiel (wie auch von dir übernommen) die Alarmdauer auf 3 und dann gleich wieder auf eins weniger gesetzt werden, bleiben netto nur 2 Sekunden übrig. Du kannst es auch in der Hauptschleife erledigen, indem Du z.B. die Sekunde zwischenspeicherst und dann vergleichst. Ist diese anders, dann ist eine Sekunde vergangen. Möglichkeiten gibt es halt viele.
-
Möglichkeiten gibts es bestimmt viele, nur sind leider meine Möglichkeiten begrenzt, da ich Bascom-Neuling bin...
Dein Codebeispiel hat mir deshalb auch so gut gefallen, weil ich es verstanden habe :-)
Hab eben die Alarmdauer auf 10 erhöht, leider bleibt die Alarm-LED trotzdem nur eine Sekunde an.
In dem Sectic-Bereich, also zwsichen Sectic und Return, ist nur eine Flagsetzung...
Lösche ich folgenden Code, bleibt die Alarm_LED nonstop an...
Code:
If _hour = Alstd And _min = Almin Then Alarmdauer = 10
If Alarmdauer >= 1 Then
Decr Alarmdauer
Set Wecker
Else
Reset Wecker
End If
-
Sag mal, wie meinst du das mit Sekunde zwischenspeichern?
Wie funktioniert die Alarmdauer-Regelung in der HAuptschleife?
-
Scheint, als ob irgendwas anderes passt nicht. Für eine bessere Aussage bräuchte ich mehr Code. Da du nur die Stunde und Minute vergleichst, müsste die ganze Minute über jede Sekunde Alarmdauer auf 3 gesetzt werden.
Die Sekunde zwischenspeichern geht ganz einfach:
Code:
dim sekalt as byte
...
...
do
if sekalt<>_sec then
sekalt=_sec
gosub sekuendlich
end if
loop
end
sekuendlich:
'hier der Code rein, welcher nach jeder neuen Sekunde ausgeführt werden soll. z.B.
gosub Uhranzeigen
gosub Alarme
gosub Menuetimer
gosub beleuchtungstimer
...
...
...
return