Ich kenne mich mit Bascom nicht aus. Aber die Flanke kann man im Programm immer ändern. Du hast oben geschrieben "config int0 = raising ", das stellst du auf falling. Ich würde noch die Interrupts sperren (disable Interrupt) .
MfG Hannes
Werbung
Ich kenne mich mit Bascom nicht aus. Aber die Flanke kann man im Programm immer ändern. Du hast oben geschrieben "config int0 = raising ", das stellst du auf falling. Ich würde noch die Interrupts sperren (disable Interrupt) .
MfG Hannes
Stimmt, ich dann die Flanke ändern, jedoch aber nicht die Sprungmarke dazu.
Dann bringt mir ersteres doch auch nichts? :/
Du kanst hinter der fraglichen Sprungmarke eine Fallunterscheidung vorsehen:
- wenn INT bei steigender Flanke aktiviert ist, dann Zähler rücksetzen
- wenn INT bei fallender Flaanke aktiviert ist. dann Zähler auslesen und ggf. darauf reagieren
Das relevante Bit im Steuerregister kannst du direkt testen. Anscheinend musst du dafür das Datenblatt studieren, falls es keine Ausleseroutine gibt, die diesen Hardwarebezug so hübsch abstrahiert.
Du meinst also in etwa so?
Code:$regfile = "ATtiny45.dat" $crystal = 1000000 $hwstack = 40 $swstack = 16 $framesize = 32 Pwm_mobo Alias Portb.2 Config Pwm_mobo = Input Led Alias Portb.3 Config Led = Output Config Timer0 = Timer , Prescale = 1 On Int0 Sprungmarke 'Wenn Int0 ausgelöst wird, springe zu Label Sprungmarke Enable Interrupts Do Config Int0 = Raising 'Int0 loest bei steigender Flanke aus Config Int0 = Falling 'Int0 loest bei fallender Flanke aus If Tcnt1 > X Then 'X = Anzahl der Ticks ab der der Zustand der LED geaendert werden soll Led = 1 Else Led = 0 Loop Sprungmarke: If Int0 = Raising Then Timer0 = 0 Enable Timer0 Else Stop Timer0 Return 'zutück ins Hauptprogramm springen
Zumindest nach dem Label 'Sprungmarke' geht es in die Richtung, die ich meinte.
Genaueres kann ich nicht sagen, weil ich keine Ahnung von Bascom habe.
Ich sehe hier ein paar Probleme:
Erstens: Config INT0 = Falling und Config INT0 = Rising nacheinander ist ziemlich sinnlos, weil der zweite Befel den ersten überschreibt. Es resultiert also ein Interrupt auf eine fallende Flanke.Code:Do Config Int0 = Raising 'Int0 loest bei steigender Flanke aus Config Int0 = Falling 'Int0 loest bei fallender Flanke aus If Tcnt1 > X Then 'X = Anzahl der Ticks ab der der Zustand der LED geaendert werden soll Led = 1 Else Led = 0 Loop
Zweitens: TCNT1 ist ja der Zählerstand des Timers 1, der kontinuierlich hochzählt. Irgendwann wird er zwangsläufig größer werden als die Variable X, und dann schaltet sich die LED ein.
Wenn Du INT0 auf "Change" konfigurierst, löst jede Flanke einen Interrupt aus. Wenn Du am Anfang der ISR eine Abfrage des INT0-Pins machst, kannst Du unterscheiden, ob es eine steigende (PIN = 1) oder eine fallende (PIN = 0) Flanke war. Du bräuchtest dann nur noch ein geeignetes Vefahren, die Zeiten zwischen steigendrn und fallenden Flanken zu messen. Aber das ist auch kein Hexenwerk...
Ud in der ISR gibt´s auch ein paar Probleme:
"Enable Timer1" startet nicht den Timer, sondern aktiviert lediglich den Interrupt beim Überlauf des Timers. Zum Starten des Timers nimt man Start Timer1.
Und "If Int0 = Rising" geht auch nicht, das wird Bascom nicht kompilieren. Wenn, dann müsstest Du die niedrigsten beiden Bits im MCUCR-Register abfragen. Aber bei genauer Betrfachtung bauchst Du diese Abfrage gar nicht!
Danke für deine Antwort!
Du hast absolut recht.
Es soll natürlich das Register von TIMER0 abgeglichen werden, also TCNT0.
Heißt, mit "Config INT0 = Change" springt er bei jeder Flanke (egal ob fallend oder steigend) zum Label, das ich beim "On INT0 ..." gewählt habe?
Damit das funktioniert muss ich Interrupts global aktivieren, nehme ich an, zusätzlich auch noch "Enable INT0"?
Am Label frage ich dann ab, ob der Pin 1 oder 0 ist, je nachdem setze ich Timer 0 auf 0 und starte ihn, oder stoppe ihn?
Der Abgleich des Registers des Timers, gehört der dann noch in die ISR oder ins Hauptprogramm?
In diesem würde dann ja nach jetzigem Stand ... nichts stehen? Oo
Dazu würde ich dann wie oben beschrieben einen Timer auf 0 setzen und starten, bzw. stoppen und ggf. noch den Zählerstand mit einer Variablen abgleichen.
Gut zu wissen, ein echtes Fettnäpfchen.
Ja, habe ich schon beim ersten Kompilieren bemerkt, aber wie du sagst, man braucht es tatsächlich nicht.
Code zum aktuellen Stand der Dinge:
Code:$regfile = "ATtiny45.dat" $crystal = 1000000 $hwstack = 40 $swstack = 16 $framesize = 32 Pwm_mobo Alias Pinb.2 Config Pwm_mobo = Input Led Alias Portb.3 Config Led = Output Config Timer0 = Timer , Prescale = 1 'Timer 0 wird konfiguriert Config Int0 = Change 'Der Interrupt soll bei jeder Falke ausgelöst werden On Int0 Sprungmarke 'Wenn Int0 ausgelöst wird, springe zu Label Sprungmarke Enable Interrupts Do If Tcnt0 > X Then 'X = Anzahl der Ticks ab der der Zustand der LED geaendert werden soll Led = 1 Else Led = 0 Loop End Sprungmarke: If Pwm_mobo = 1 Then Timer0 = 0 Start Timer0 Else Stop Timer0 Return 'zurück ins Hauptprogramm springen
Geändert von Flo3578 (21.10.2015 um 23:38 Uhr)
Lesezeichen