PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Variable im 1Hz-Takt Togglen



Blade_Vampire
08.05.2009, 15:21
Hi,

Ich habe ein Programm, das mehrere Ausgänge über If-Abfragen steuert, jetzt möchte ich, dass eine Bit-Variable im 1Hz Takt auf High und dann wieder Low geht, also quasi "blinkt".
Ich hab ein bisschen nachgelesen und das mit dem Timer schon hinbekommen, also sie togglet im 1Hz-Takt, das ist soweit gut, allerdings funktioniert dann mein restliches Programm nicht mehr, wenn ich dann ein bisschen die Zeiten verändere funktioniert zwar das Programm wieder (mit leichten verzögerungen bei der Eingabe) aber dann ist die Variable ständig auf high.
Die Variable soll später dafür da sein eine Anzeige blinken zu lassen, da ich aber mehrere Lampen hab die, wenn sie aktiv sind, alle im gleichen Takt blinken sollen wollte ich das so lösen.

Wie kann ich das anstellen, dass ich es so einbinden kann das mein Programm noch läuft und die Variable immer getogglet wird?
Gibt wahrscheinlich eine einfache Lösung aber ich bekomms nicht gebacken ;).

Danke!

Ceos
08.05.2009, 15:58
versuch mal ein wenig programmcode zu posten ... du weist schon, wahrsagerei ist hier im forum nicht so ausgeprägt ;)

Blade_Vampire
08.05.2009, 16:58
Also das hier ist der Code für den Timer, alleine funktioniert er, wenn ich meinen Code dazupacke dann geht gar nichts mehr, entweder ist die variable immer high oder das restliche Programm reagiert gar nicht.


Config Timer1 = Timer , prescale 64

On Timer1 Timer1_isr
Enable Timer1
Enable Interrupts

Do
NOP
Loop

End

Timer1_isr:
Load Timer1, 195
C = 0 : waitms 5 : C = 1
Diesen Code hab ich aus einem Buch, alleine funktioniert er auch ganz gut.

Und hier mein Code (ohne das geblinke):

Main:
'Rauchmelder unscharf schalten

Debounce Rauchmelder , 0 , Rmtoggle , Sub


'Schütz An/Aus
If Einschalten = 0 Then Goto Setzen
If Ausschalten = 0 Then Goto Rsetzen


'Not-Aus
If Notaus = 1 And B = 1 Then
Gelb = C
Elseif Notaus = 0 And B = 1 Then
Gelb = 1
End If


'Rauchmelder-Ausgelöst
If Feuer = 0 And F = 0 Then
Alarm = An
Goto Rsetzen
Else
Alarm = Aus

End If

Goto Main 'loop


'Flip-Flop setzen
Setzen:
Schuetz = An
Gelb = An
B = An
Goto Main

'Flip-Flop zurücksetzen
Rsetzen:
Schuetz = Aus
Gelb = Aus
B = Aus
If F = 1 Then
Gosub Rmtoggle
End If
Goto Main


Rmtoggle:
Toggle F
If F = 1 Then
Rot = C
Else
Rot = 0
End If

Return

End

C ist die besagte Variable.

Ich weiß, dass das ständige Goto eigentlich ein Unding ist, aber ich hab grade erst mit Bascom angefangen und bin erst dabei mich einzuarbeiten ;), vorher hab ich alles in Elektronikhardware aufgebaut.

Ceos
08.05.2009, 17:28
so wenig ich von bascom verstehe, so sehr würd cih vermuten, dass unter deinem rmtoggle ein goto main fehlt, der fällt dort aus allen wolken und beendet das programm meines erachtens!

EDIT: mein fehler das ist die funktion für das debounce!!

mh irgendwie will mir nichts auffallen


ausserdem ist das waitms IN einer ISR schon fast sträflich!

Blade_Vampire
08.05.2009, 17:34
ausserdem ist das waitms IN einer ISR schon fast sträflich!

Ja ich wunder mich auch ein bisschen, aber ich hab das 1:1 aus einem Buch abgeschrieben und da stand es so drin ;), ich hab nirgens eine anleitung gefunden wie man soetwas in ein bestehendes programm einbaut, deswegen weiß ich eben nicht wie ich das einsetzen muss, damit beides läuft ;).

Edit: Ich habs jetzt etwas umgeschrieben, ohne goto, mir ist grad so ein Geistesblitz gekommen :D, das funktioniert auch, auch wenn der timer drin ist funktioniert es noch, allerdings blinkt nichts.

Hier der neue Code:

$regfile = "m8def.dat"

$crystal = 8000000


Config Portc.1 = Input
Config Portc.2 = Input
Config Portc.3 = Input
Config Portc.4 = Input
Config Portc.5 = Input


Config Portd.0 = Output
Config Portd.1 = Output
Config Portd.2 = Output
Config Portd.3 = Output


Set Portc.1
Set Portc.2
Set Portc.3
Set Portc.4
Set Portc.5


Config Debounce = 30


Const An = 1
Const Aus = 0



Einschalten Alias Pinc.1
Ausschalten Alias Pinc.2
Rauchmelder Alias Pinc.3
Notaus Alias Pinc.4
Feuer Alias Pinc.5


Schuetz Alias Portd.0
Gelb Alias Portd.1
Rot Alias Portd.2
Alarm Alias Portd.3

Dim F As Bit
Dim B As Bit
Dim A As Bit
Dim C As Bit
C = 1


Config Timer0 = Timer , Prescale = 1024
Enable Timer0
Enable Interrupts

'On Timer0 Timer0_isr
Do
NOP
'Rauchmelder unscharf schalten

Debounce Rauchmelder , 0 , Rmtoggle , Sub


'Schütz An/Aus
If Einschalten = 0 Then Gosub Setzen
If Ausschalten = 0 Then Gosub Rsetzen


'Not-Aus
If Notaus = 1 And B = 1 Then
Gelb = C
Elseif Notaus = 0 And B = 1 Then
Gelb = 1
End If


'Rauchmelder-Ausgelöst
If Feuer = 0 And F = 0 Then
Alarm = An
Gosub Rsetzen
Else
Alarm = Aus

End If

Loop

'loop
'Flip-Flop setzen
Setzen:
Schuetz = An
Gelb = An
B = An
Return

'Flip-Flop zurücksetzen
Rsetzen:
Schuetz = Aus
Gelb = Aus
B = Aus
If F = 1 Then
Gosub Rmtoggle
End If
Return


Rmtoggle:
Toggle F
If F = 1 Then
Rot = C
Else
Rot = 0
End If

Return

'Timer0_isr:
'Load Timer0 , 195
'C = 0 : Waitms 5 : C = 1
'Return

End

Ich hab den Timer da jetzt mal auskommentiert und C auf 1 gesetzt, weil sonst gar nichts geleuchtet geschweige denn geblinkt hat ;).

Dirk
08.05.2009, 18:28
Hallo Blade_Vampire,

ohne dass ich deinen Code vollständig angesehen habe:

1. Ich würde in der ISR die Variable C nur toggeln, das heißt, bei jedem Aufruf der ISR von 0 auf 1 wechseln und umgekehrt. Waitms muss da raus.

2. Deine Hauptschleife (Do-Loop) ist extrem schnell, wenn du keinen weiteren Code drin hast. D.h., dass Debounce 30ms wartet, um den Taster ein 2. Mal abzufragen, danach flitzt dein Hauptprogramm weiter und landet nach wenigen us wieder bei Debounce. Wenn da der Taster noch nicht losgelassen wurde (die Finger sind meist nicht so schnell), hat der Pegel von Rauchmelder noch nicht gewechselt.
Ich würde die Hauptschleife ewas verzögern, z.B. um 50 oder 100ms.
Bei einer Alarmanlage braucht man ja eigentlich auch keine so hohe Speed, um auf die Zustände von Tasten oder Alarmkontakten zu reagieren.

Gruß Dirk

mycroc
08.05.2009, 18:55
es könnte sein das es Blinkt, aber zu schnell. Bei 8Mhz und einem Vorteiler von 1024 + "Load Timer0, 195" macht alle ca. 0,025 S einen überlauf.

Blade_Vampire
08.05.2009, 21:19
Hallo Dirk und mycroc

vielen Dank für den Tipp! Ich hab jetzt das mit waitms rausgeschmissen und anstelle dessen einfach mal testweise toggle C reingeschrieben und siehe da, es geht :).

Das was du zum Debounce gesagt hast, ist mir erst gar nicht aufgefallen, aber ich habs jetzt mal provoziert und es ist wirklich so ;), ich hab jetzt 100ms eingestellt.

Das mit der Blinkgeschwindigkeit stimmt auch, es lief erst sehr schnell, so dass man es fast nicht als Blinken identifizieren konnte (ich benutze zum Anzeigen größere Glühbirnen, die ziemlich träge sind, erkannt hab ichs nur an der zusätzlichen LED an der Steuerung), ich hab ein bisschen mit den Zeiten rumgespielt und verschiedene Werte ausprobiert, jetzt blinkt es annähernd auf 1Hz.

Vielen Dank an euch, für die Hilfe!

Gruß, Kai