Archiv verlassen und diese Seite im Standarddesign anzeigen : timer vll mal erklären???
hallo, also ich blicks einfach net durch. ich suche und suche und finde einfach keine lösung. ich möchte einfach nur dass mein programm 5 minuten läuft per knopfdruck. und sich dem selben stoppen lässt und mit nem anderen resetet.
aber ich blicks net. kann mir hier jemand mal genau den timer erklären.
Schau mal hier:
http://www.rowalt.de/mc/avr/avrboard/05/avrb05.htm
ja super aber da muss ich ja abartig umdenken ich hab nen mega8 und da is es denk ich en bischen anders.
linux_80
22.10.2006, 02:35
Das denken wir nicht, alles AVRs sind im Prinzip gleich, unterscheiden sich nur in der Anzahl Pins und in der Speichergrösse. Wenn man das mal verinnerlicht hat (ins MainBrain), kann man mit allen AVRs umgehen.
so ich hab jetzt mal was hier:
$regfile = "m8def.dat"
$crystal = 1000000
$baud = 9600
Config Portd.2 = Output
Config Portb.0 = Output
Config Pinc.0 = Input
Config Portb.1 = Output
Config Pinc.1 = Input
Portc.0 = 1
Portc.1 = 1
Portc.2 = 1
Portc.3 = 1
Dim I As Bit
On Timer0 On Timer0
Config Timer0 = Timer , Prescale = 8
Enable Timer0
Enable Interrupts
Do
If Pinc.0 = 1 Then
Portb.0 = 1
Portb.1 = 0
Portb.1 = 0
Else
Portb.0 = 0
Wait 3
Portb.1 = 1
Wait 5
Portb.1 = 0
Wait 3
End If
If Pinc.1 = 1 Then
Portb.2 = 1
Portb.3 = 0
Portb.3 = 0
Else
Portb.2 = 0
Wait 3
Portb.3 = 1
Wait 5
Portb.3 = 0
Wait 3
End If
Loop
On Timer0
I = Not I
Portd.2 = I
Return
ich hab zwar keine ahnung was des jetzt bewirkt aber auf jedenfall wird mir im programm ein fehler angezeigt:
label not fount [ontimer0 ]
weiß jemmand was des is und was dieser timer jetzt macht. weiß nur dass er ein signal über den speaker abgibt wenn er überläuft.[/code]
On Timer0 On_Timer0
On_timer0:
....
return
Der name muss genau stimmen.
ok habs und nun was macht dieser genau. ich teste den jetzt nur mal. ich glaube für dass was ich vorhabe brauche ich den timer = als counter oder irre ich mich da?
Du kannst einfach eine Variable i bei jedem Aufruf um eins hochzählen und mit einem vorgegebenen Wert vergleichen. Sind beide Werte gleich (5 Minuten Laufzeit vorbei) schaltet sich der Bot ab, sind die Werte nicht gleich(i < vorgegbener Wert) inkremetierst du i.
MfG
also kann ich i individuell verändern. gibt es da auch irgendwie ne formel zum zeit berechnen? also ich meine ich kann da jetzt jawohl nicht wirklich einfach 300 sekunden eintragen oder?
und wie kriege ich dass hin dass wenn ich jetzt nen taster betätige dass er änfängt zu zählen und wenn ich ihn nochmal drücke dass er weiterläuft?
und ne reset taste?
also hier komme ich mir echt als alleinunterhalter vor.
ich verstehe den schei... timer net und keiner hilft mir mal.
Du hättest vielleicht mal die Suche benutzen können und wärst dann auf das Programm rnAvr gestoßen. Ich hab mal mit diesem Programm den Timer0 und Prescale etc. berechnet:
Pro Sekunde wird 100 mal die ISR aufgerufen, das entspricht i += 100 pro sekunde -> Nach 3 Minuten: i = 18.000
Config Timer0 = Timer, Prescale = 1024
On Timer0 Timer_irq
'Diese Vorgabe wurde berechnet um die genaue Intervallfrequenz zu erreichen
Const Timervorgabe = 100
'Hier werden die Timer aktiviert
Enable Timer0
Enable Interrupts
Do
Loop
Timer_irq:
Timer0 = Timervorgabe
Return
Das Programm ist für einen Atmega mit 16Mhz Quarz gedacht, wenn du eine andere Quarzfrequenz hast, musst du es mit Hilfe von rnAvr anpassen.
Als Reset Taste kannst du ja die Reset Taste vom AVR benutzen, aber was meinst du mit:
und wie kriege ich dass hin dass wenn ich jetzt nen taster betätige dass er änfängt zu zählen und wenn ich ihn nochmal drücke dass er weiterläuft?
Zum starten kannst du einfach eine Taste abfragen und wenn die Taste gedrückt wurde könntest du eine Variable taster_gedrueckt auf eins setzen. In der ISR schreibst du dann nicht einfach i++; sondern machst noch eine Abfrage ob taster_gedrueckt 1 ist, wenn ja dann wird i inkrementiert, wenn nein dann passiert nix. Wenn die Taste nochmal gedrückt wird könntest du die Variable taster_gedrueckt wieder auf 0 setzen.
Hoffe das war das, was du wissen wolltest.
na jetzt kommt mal rollen in die sache.
also ich hab mich da vertippt.
ich möchte das programm per tastendruck 5 minuten laufen lassen. nun soll das programm aber anhalten wenn ich die taste erneut drücke und auch weiterlaufen wenn ich se wieder drücke.
reseten will ich es irgendwie mit ner anderen taste.
Für die Reset Taste muss du einfach den Reset-Pin deines AVRs (bei mir is es Pin9, mega32) über eine Taste mit Masse verbinden.
Hab hier mal das Programm geschrieben, ist natürlich nicht ausführbar weil du die Eingangports definieren musst und noch die Syntax anpassen, weil ich die nicht so gut kenne (programmiere in C).
dim i as integer
dim taste_gedrueckt as bool
taste_gedrueckt = 0
Config Timer0 = Timer, Prescale = 1024
On Timer0 Timer_irq
'Diese Vorgabe wurde berechnet um die genaue Intervallfrequenz zu erreichen
Const Timervorgabe = 100
'Hier werden die Timer aktiviert
Enable Timer0
Enable Interrupts
Do
if [taste] == 1 then
if taste_gedrueckt = 0 then taste_gedrueckt = 1 endif
if taste_gedrueckt = 1 then taste_gedrueckt = 0 endif
endif
Waitms 1
Loop
Timer_irq:
Timer0 = Timervorgabe
if i == 30000 then
i = 0
taste_gedrückt = 0
'Hier können auch Befehle stehen, die ausgeführt werden wenn die 5 Minuten erreicht sind.
else if taste_gedrückt == 1 then
i++
endif
Return
Das Programm wird über eine Taste gestartet und kann mit der selben Taste unterbrochen werden und der timer wieder "eingeschaltet" werden (stimmt net ganz, weil der timer ja weiterläuft, nur wird i net inkrementiert). Nach 5 Minuten stoppt das Programm die Inkrementation von i und muss mit der Taste neu gestartet werden.
MfG
noch ne grundlegende frage was heißt prescale und warum hast du 1024 hier angegeben.
Prescale gibt den Wert an, durch den die Frequenz des Quarzes geteilt wird. Damit zählt der Timer dann von 0-255 und löst beim Überlauf einen Interrupt aus und der Code in der ISR wird ausgeführt. Ohne den Prescaler würde der Timer bei einem 16Mhz Quarz, 16.000.000/256 Interrupts pro Sekunde auslösen.
edit: achja die 1024 hab ich mit dem Programm rnAvr berechnet
cool also danke schon mal ich meld mich falls ich es nicht hinbekomme.
ich verstehe net ganz was du da bei do machst kannst mir dass mal erklären?
In der Do Schleife wird eine Taste abgefragt. ([taste] musst du mit Portb.1 oder ähnlichem ersetzen)
Wenn die Variable taste_gedrueckt 1 ist, erhält sie nun den Wert 0, wenn sie 0 war, erhält sie den Wert 1.
Diese Variable wird verwendet um die Inkrementierung von i und somit deinen "Counter" anzuhalten bzw. zu starten.
Am Anfang vom Programm wird taste_gedrueckt der Wert 0 zugewiesen. Sprich die Variable i bleibt unverändert, weil sie nur inkrementiert wird wenn taste_gedrueckt 1 ist. Drückt man nun zum Starten der 5 Minuten auf die Taste, wird taste_gedrueckt auf 1 gesetzt und somit i inkrementiert. Dies geschieht solange bis taste_gedrueckt wieder 0 ist. Das kann entweder der Fall sein, wenn die 5 Minuten erreicht sind oder wenn du nochmals auf die Taste gedrueckt, dadurch wird taste_gedrueckt der Wert 0 zugewiesen.
Hoffe du verstehst es ^^
MfG
also des programm läuft net wirklich hab jetzt alles mal eingetippt bloß sind dann so eta 5 fehler drinn.
Wie gesagt das Programm ist auch net da um es zu kopieren und einzufügen, weil die Syntax mit Sicherheit net stimmt. Hast die Syntax verbessert? Was kommen denn für Fehler?
ich habe alles eingefügt bloß weiß ich eben net was ich bei dem do hinschreiben soll.
ich dreh bald durch. am anfang stimmt ja alles hab ich auch soweit hingeschrieben.
bloß was soll ich da hinschreiben bei dem do. ich kann da ja net 5 mal die selbe taste reinschreiben.
taste_gedrueckt ist ne Variable und [taste] musst du mit dem Eingangsport an der die Taste hängt ersetzen. Diesen musst du natürlich vorher als Eingang definieren.
MfG
habs jetzt mal angepasst:
Dim I As Integer
Dim 1 As Bool
1 = 0
Config Timer0 = Timer, Prescale = 1024
On Timer0 Timer_irq
Const Timervorgabe = 100
Enable Timer0
Enable Interrupts
Do
If Pinc.2 = 1 Then
If 1 = 0 Then 1 = 1 End If
If 1 = 1 Then 1 = 0 End If
endif
Waitms 1
Loop
Timer_irq:
Timer0 = Timervorgabe
If I = 30000 Then
i = 0
1 = 0
Else If 1 = 1 Then
i++
endif
Return
hoer bringt er mir in dem do feld fehler sprich beide if sätze und des end if am ende vom do satz.
und am ende noch einer bei 1=0 und bei Else If 1 = 1 Then
ich verstehs net ganz ehrlich. hab dir jetzt mal alles hingeschrieben wenn du weißt was falsch ist könntest mir des ja vll sagen. dank dir schon mal.
$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
Dim I As Integer
Dim taste_gedrueckt As Integer
taste_gedrueckt = 0
Config Portc.2 = Input
Config Timer0 = Timer, Prescale = 1024
On Timer0 Timer_irq
Const Timervorgabe = 100
Enable Timer0
Enable Interrupts
Do
If Portc.2 = 1 Then
If taste_gedrueckt = 0 Then taste_gedrueckt = 1
If taste_gedrueckt = 1 Then taste_gedrueckt = 0
End If
Waitms 1
Loop
Timer_irq:
Timer0 = Timervorgabe
If I = 30000 Then
taste_gedrueckt = 0
I = 0
Elseif taste_gedrueckt = 1 Then
Incr I
End If
Return
So gehts, sorry war vorher einiges falsch weil ich wie gesagt die Bascom Syntax net (gut) kann..
hab hier mal alles übersichtlich dargestellt was nicht ganz geht.
$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
Dim I As Integer
Dim 1 As Integer
1 = 0 error
Config Portc.2 = Input
Config Timer0 = Timer, Prescale = 1024
On Timer0 Timer_irq
Const Timervorgabe = 100
Enable Timer0
Enable Interrupts
Do
If Portc.2 = 1 Then
If 1 = 0 Then 1 = 1 error
If 1 = 1 Then 1 = 0 error
End If
Waitms 1
Loop
Timer_irq:
Timer0 = Timervorgabe
If I = 30000 Then
1 = 0 error
I = 0
Elseif 1 = 1 Then error
Incr I
End If error
Return
ach und dass mit den syntax war net der fehler. des hab ich schon eingebaut gehabt. daran liegts net.
Du darfst einer Variable nicht den Namen "1" geben!
$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
Dim I As Integer
Dim Led As Integer
Led = 0
Config Portc.2 = Input
Config Timer0 = Timer, Prescale = 1024
On Timer0 Timer_irq
Const Timervorgabe = 100
Enable Timer0
Enable Interrupts
Do
If Portc.2 = 1 Then
If Led = 0 Then Led = 1
If Led = 1 Then Led = 0
End If
Waitms 1
Loop
Timer_irq:
Timer0 = Timervorgabe
If I = 30000 Then
Led = 0
I = 0
Elseif Led = 1 Then
Incr I
End If
Return
so gehts. aber sollte man anstatt der beiden if sätze nicht else einsetzen für den letzten if satz?
Hää? ich versteh nicht ganz dein Problem?
Nimm doch den Code den ich oben gepostet hab, dieser funktioniert.
Und ja du kannst der Variable taste_gedrueckt irgendeinen anderen Namen zuweisen, nur sollte der nicht mit einer Zahl anfangen!
Edit: ja else kannst du auch machen
achso noch eine frage an welcher stelle muss ich nun mein programm einfügen?
also habs jetzt drauf geflasht alles geklappt. nur is die led die ich ansteuere eben net aus sondern ein. und abschalten tut se sich auch net per knopfdruck.
und mein erstes programm dass ich in die do schleife geschrieben habe geht auch nimmer
$regfile = "m8def.dat"
$crystal = 1000000
$baud = 9600
Config Portb.0 = Output
Config Pinc.0 = Input
Config Portb.1 = Output
Config Pinc.1 = Input
Config Pinc.2 = Input
Portc.0 = 1
Portc.1 = 1
Portc.2 = 1
Portc.3 = 1
Dim I As Integer
Dim Led As Integer
Led = 0
Config Timer0 = Timer , Prescale = 1024
On Timer0 Timer_irq
Const Timervorgabe = 100
Enable Timer0
Enable Interrupts
Do
Do
If Portc.2 = 1 Then
If Led = 0 Then Led = 1
If Led = 1 Then Led = 0
End If
Waitms 1
Loop
Timer_irq:
Timer0 = Timervorgabe
If I = 30000 Then
Led = 0
I = 0
Elseif Led = 1 Then
Incr I
End If
If Pinc.0 = 1 Then
Portb.0 = 1
Portb.1 = 0
Portb.1 = 0
Else
Portb.0 = 0
Wait 3
Portb.1 = 1
Wait 5
Portb.1 = 0
Wait 3
End If
If Pinc.1 = 1 Then
Portb.2 = 1
Portb.3 = 0
Portb.3 = 0
Else
Portb.2 = 0
Wait 3
Portb.3 = 1
Wait 5
Portb.3 = 0
Wait 3
End If
Loop
End
habs jetzt mal so geschrieben jetzt geht des programm von mir schon mal wieder aber der timer noch net.
$regfile = "m8def.dat"
$crystal = 1000000
$baud = 9600
Config Portb.0 = Output
Config Pinc.0 = Input
Config Portb.1 = Output
Config Pinc.1 = Input
Config Pinc.2 = Input
Portc.0 = 1
Portc.1 = 1
Portc.2 = 1
Portc.3 = 1
Dim I As Integer
Dim Led As Integer
Led = 0
Config Timer0 = Timer , Prescale = 1024
On Timer0 Timer_irq
Const Timervorgabe = 100
Enable Timer0
Enable Interrupts
Do
Do
If Portc.2 = 1 Then
If Led = 0 Then Led = 1
If Led = 1 Then Led = 0
End If
Waitms 1
If Pinc.0 = 1 Then
Portb.0 = 1
Portb.1 = 0
Portb.1 = 0
Else
Portb.0 = 0
Wait 3
Portb.1 = 1
Wait 5
Portb.1 = 0
Wait 3
End If
If Pinc.1 = 1 Then
Portb.2 = 1
Portb.3 = 0
Portb.3 = 0
Else
Portb.2 = 0
Wait 3
Portb.3 = 1
Wait 5
Portb.3 = 0
Wait 3
End If
Loop
Timer_irq:
Timer0 = Timervorgabe
If I = 30000 Then
Led = 0
I = 0
Elseif Led = 1 Then
Incr I
End If
Loop
End
Timer_irq solltest du net in die Do Loop Schleife schreiben.
Außerdem hast du 2 verschachtelte Do Loop Schleifen. Du brauchst nur eine.
Und wenn du willst, dass dein Programm nur innerhalb der 5 Minuten ausgeführt wird solltest du überprüfen ob Variable Led ungleich 0 ist, sprich 1.
$regfile = "m8def.dat"
$crystal = 1000000
$baud = 9600
Config Portb.0 = Output
Config Pinc.0 = Input
Config Portb.1 = Output
Config Pinc.1 = Input
Config Pinc.2 = Input
Portc.0 = 1
Portc.1 = 1
Portc.2 = 1
Portc.3 = 1
Dim I As Integer
Dim Led As Integer
Led = 0
Config Timer0 = Timer , Prescale = 1024
On Timer0 Timer_irq
Const Timervorgabe = 100
Enable Timer0
Enable Interrupts
Do
If Portc.2 = 1 Then
If Led = 0 Then Led = 1
If Led = 1 Then Led = 0
End If
Waitms 1
If Led = 1 Then
If Pinc.0 = 1 Then
Portb.0 = 1
Portb.1 = 0
Portb.1 = 0
Else
Portb.0 = 0
Wait 3
Portb.1 = 1
Wait 5
Portb.1 = 0
Wait 3
End If
If Pinc.1 = 1 Then
Portb.2 = 1
Portb.3 = 0
Portb.3 = 0
Else
Portb.2 = 0
Wait 3
Portb.3 = 1
Wait 5
Portb.3 = 0
Wait 3
End If
End If
Loop
Timer_irq:
Timer0 = Timervorgabe
If I = 30000 Then
Led = 0
I = 0
Elseif Led = 1 Then
Incr I
End If
Return
So dürfte es funktionieren.
MfG
also jetzt geht gar nix mehr. nicht eine led leuchtet mehr. alles tot.
Du musst einmal auf die Taste drücken
Millenniumpilot
27.10.2006, 21:22
Hallo coCo,
ich bewundere Deine Ausdauer.
xbgamer sollte sich bitte mal auf den Hosenboden setzen und ein wenig Grundwissen anlesen. Dazu kann ich das Buch von Rowalt nur empfehlen - oder wenigstes die Artikel auf der Homepage (wurde ja schon empfohlen) durchlesen anstatt dieses hier zu schreiben:
"also hier komme ich mir echt als alleinunterhalter vor.
ich verstehe den schei... timer net und keiner hilft mir mal."
Du hast IMHO viel Hilfe bekommen.
Gruß Dirk
drücke auf die taste geht aber net wirklich.
zum thema lesen. ich wollte es ja extern machen mit dem timer mit jk master slave negativ flanken dotiert. aber da meinte einer dass es so doch viel einfacher ginge was ich allerdings gar net finde.
und des mit dem alleinunterhalter war allgemein bezogen da ich schon viele threats auf gemacht habe wo dann plötzlich keiner mehr bock hatte mir ne antwort zu geben.
also gut hab jetzt mal auf eigene faust des versucht zu verstehen.
also hab jetzt mal folgendes fang jetzt quasi mal von 0 wieder an:
$regfile = "m8def.dat"
'Quarzfrequenz, entsprechend ihren Angaben
'der passende Quarz muss in die Fassung gesteckt werden
$crystal = 8000000
'nur notwendig wenn rs232 benutzt werden soll
$baud = 9600
'Hier wird der Timer und der Teiler festgelegt
Config Timer0 = Timer, Prescale = 1024
'Der Port mit der dritten LED auf RN-Control wird als Ausgang programmiert
Config Pinb.0 = Output
'Hier geben wir der Definition einen schöneren Namen
Led3 Alias Portb.0
'Hier wird das Unterprogramm festgelegt, das
'in dem von ihnen eingestellten Intervall aufgerufen wird
On Timer0 Timer_irq
'Diese Vorgabe wurde berechnet um die genaue Intervallfrequenz zu erreichen
Const Timervorgabe = 100
'Hier werden die Timer aktiviert
Enable Timer0
Enable Interrupts
'Hier ist die Programmhauptschleife
Do
'Hier könnte Ihr Hauptprogramm stehen
Loop
'Dies ist der Programmteil, der in dem von ihnen gewählten
'Intervall aufgerufen wird
Timer_irq:
Timer0 = Timervorgabe
'Hier könnte nun ihre beliebige IRQ-Routine stehen
'Dabei sollte man darauf achten das diese nicht mehr Zeit
'benötigt, als das Intervall zuläßt
'Der Zustand der LED wir umgekehrt, wodurch sich blinken ergibt
'Hohe Frequenzen sind natürlich nicht mehr sichtbar
Toggle Led3
Return
so jetzt blinkt die led schon mal. jetzt soll die led als nächster schritt per taster an und abgeschaltet werden wie geht dass? ganz langsam bitte. falls ihr mir noch helft.
vll kannst du mir erst mal erklären wie ich überhaupt die 5 minuten hinbekomme.
also ne lassen wa dass mit den 5 minuten. sag mir bitte nurnoch jemand wie ich es einstelle dass die led genau im sekundentakt blinkt.
Wenn du prescale auf 1024 und Timervorgabe auf 100 hast, bei nem 8 Mhz Quarz, wird die ISR 50 mal pro Sekunde aufgerufen, sprich "Toggle Led3" darf nur alle 50 mal ausgeführt werden. Wie das geht steht weiter oben in diesem Thread.
Benutzt du RN-Control? Weil wenn ja, dann musst du die Tastenabfrage mit nem ADC machen, weil beim RN-Control die 5 Tasten an einem Port hängen.
also hab jetzt mal ne schaltung extern für ne 7 segment anzeige auch gemacht. kannst ja mal schaun.
allerdings is jetzt da noch die frage wie ich ihn rückwärts zählen lasse. des mit anhalten is kein problem hab ich ne schaltung aus meinem elektrotechnik unterricht. nur eben rückwärts
des mit 50 mal hab ich gar net gefunden.
will also des toggle als clock verwenden. sprich im sekundentakt blinken geht dann auf die schaltung die oben is.
hab jetzt mal dess hier
$regfile = "m8def.dat"
$crystal = 8000000
$baud = 9600
Config Timer0 = Timer , Prescale = 1024
Config Pinb.0 = Output
Led3 Alias Portb.0
On Timer0 Timer_irq
Const Timervorgabe = 100
Enable Timer0
Enable Interrupts
Do
Loop
Timer_irq:
Timer0 = 100
Toggle Led3
Return
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.