Archiv verlassen und diese Seite im Standarddesign anzeigen : Stoppuhr
Hallo!
ich bin gerade dabei mir eine Stoppuhr zu bauen, welche die Zeit zwischen Schalter1 und Schalter2 stoppt - in sekunden und milisekunden
kann mir vielleicht jmd helfen, mit der Bascom-Hilfe komme ich nicht weit.
setzt mal den code rein damit man sehen kann wie weit du bist.
ansonsten sieh dir die timer funktion an und externen interuppt
also so sollte es irgendwie aussehen,
mir fehlt halt noch die stoppuhrfunktion, ich weiß nicht wie ich die hochzählen lassen soll
$regfile = "M8def.dat"
$crystal = 16000000
$hwstack = 100
$swstack = 100
$framesize = 100
Dim Millisekunden As Byte
Dim Minuten As Byte
Dim Sekunden As Byte
Config Portc = Output
Config Pinb.1 = Input
Config Pinb.3 = Input
Portb.1 = 0
Portb.7 = 0
Do
Config Timer1 = Timer , Prescale = 64
Const Timervorgabe = 40536
If Pinb.1 = 0 Then
On Timer1 Timer_irq
Print "schalter 1"
Enable Interrupts
end if
Millisekunden = 00
Minuten = 0
Sekunden = 0
' - - - - - - -
If Pinb.3 = 1 Then
Print "schalter 2"
Disable Timer1
Print "Zeit: " ; Minuten ; ":" ; Sekunden ; ":" ; Millisekunden ; " "
End If
Loop
Che Guevara
13.12.2009, 15:54
Hallo derpedi,
sieh dir mal folgenden code an:
$regfile = "m8def.dat"
$crystal = 16000000
$baud = 19200
$framesize = 40
$hwstack = 40
$swstack = 40
Config Pind.2 = Input
Config Pind.3 = Input
Portd.2 = 1
Portd.3 = 1
Dim Millisekunden As Word
Dim Sekunden As Byte
Dim Minuten As Byte
Dim Stoppuhr_flag As Bit
Const Timer1_vorgabe = 49536
Stoppuhr_flag = 0
Config Int0 = Falling
On Int0 Stoppuhr_starten
Enable Int0
Config Int1 = Falling
On Int1 Stoppuhr_stoppen
Enable Int1
Config Timer1 = Timer , Prescale = 1
Timer1 = Timer1_vorgabe
On Timer1 Stoppuhr
Stop Timer1
Enable Timer1
Enable Interrupts
Do
If Stoppuhr_flag = 1 Then
Reset Stoppuhr_flag
Print "Minuten: " ; Minuten ; " Sekunden: " ; Sekunden ; " Millisekunden: " ; Millisekunden
Print "Zeit (MM:SS:mm): " ; Minuten ; ":" ; Sekunden ; ":" ; Millisekunden
End If
Loop
End
Stoppuhr_starten:
Start Timer1
Return
Stoppuhr_stoppen:
Stop Timer1
Set Stoppuhr_flag
Return
Stoppuhr:
Timer1 = Timer1_vorgabe
Incr Millisekunden
If Millisekunden = 1000 Then
Millisekunden = 0
Incr Sekunden
End If
If Sekunden = 60 Then
Sekunden = 0
Incr Minuten
End If
Return
Zu deinem Code kann ich nur folgendes sagen:
1. "Configs" sollten immer vor dem Mainloop, am Anfang des Programms stehen
2. Gewöhn dir bitte einen strukturierten Programmierstil an, das ist leicher für dich selbst und auch für die Leser deines Codes.
Das soll jetzt keine Beleidigung/Demütigung o.ä. sein, sondern nur eine "Hilfestellung".
Gruß
Chris
Sauerbruch
13.12.2009, 21:47
...ich hätte auch noch ´n paar Tips:
Config Pinb.1 = Input
Config Pinb.3 = Input
Portb.1 = 0
Portb.7 = 0
I/O-Ports muss man nicht extra als Eingang konfigurieren - das sind sie von ganz alleine, wenn man den Controller hochfährt. Das hat mit den "DDR"-Registern zu tun, die initial alle auf &B00000000 stehen.
Gleiches gilt für die Port-Register (z.B. PORTB.1 oder PORTB.7) - auch die sind automatisch 0, unless otherwise noted :-)
Mit "Enable TimerX" und "Disable TimerX"hält man den Timer mitnichten an - man aktiviert bzw. deaktiviert nur den Interrupt der ausgelöst wird, wenn der Timer überläuft. Was Du meinst ist "Start TimerX" und "Stop TimerX".
(To be continued...)
So ´ne Stoppuhr ist für´s erste natürlich ein ganz schön sportliches Projekt... und wenn´s als ganzes nicht geht, kann man kaum herausfinden, wo der Fehler liegt. Hast Du denn schon mal einfachere Dinge probiert, wie z.B.
- den Timer-Überlauf mit ´ner LED bei verschiedenen Preloads darzustellen?
- externe und interne Interrupts auszulösen?
- Eingangspins abzufragen?
etc., etc... Anhand so kleiner Mini-Projekte kann man am besten den Umgang mit den unzähligen Möglichkeiten lernen, die einem Bascom bietet. Ich selbst habe übrigens den "Durchbruch" geschafft, als ich mir das Buch von Roland Walter gekauft habe. Ist didaktisch wärmstens zu empfehlen, und voller sehr lehrreicher Mini-Codes für alle wesentlichen Funktionen eines Mikrocontrollers einschließlich UART- und TWI-Kommunkation, ADC-Wandler etc., etc.
Hey,
nach sehr langer Winterpause habe ich mich heute mal wieder mit meiner Stoppuhr beschäftigt. Und sie ist fertig und funktioniert. zwar leider nicht ganz genau, bei 60sek habe ich eine abweichung von 2,8 sekunden oder so. Aber sie misst quasi auf die viertelsekunde genau
weiß jmd auf welchen startwert ich den timer setzen muss damit ich bei einem prescaler von 64 genau 0.25 sekunden bekomme? - 16mhz
und wie kann ich noch einen 3. schalter dazu bekommen, so etwas wie eine reset taste zu sein? so dass ich wieder neu die zeit stoppen kann.
$regfile = "M8def.dat"
$crystal = 16000000
$baud = 9600
Config Portc = Output ' Kompletter C Port Output
Config Pinb.0 = Input ' Eingang 1
Config Pinb.1 = Input ' Eingang 2
Portb.0 = 0
Portb.1 = 1
Do
If Pinb.0 = 1 Then ' Startknopf
Print "Start"
Enable Interrupts
Enable Timer1 ' Timer: GO
Dim W As Word
Dim A As Integer
Dim B As Integer
Dim C As Integer
Config Timer1 = Timer , Prescale = 64
A = 0 ' A = 1/4 Sekunden
B = 0 ' B = ganze Sekunden 1 - 9
C = 0 ' C = 10er Zahlen
W = Timer1
Timer1 = W
Do
On Timer1 Isr_timer1
Loop
Isr_timer1:
Print "interrupt!" ; W
A = A + 1
If A = 4 Then
B = B + 1
A = 0
End If
If B = 10 Then
C = C + 1
B = 0
End If
Print "A=" ; A
Print "B=" ; B
Print "C=" ; C
W = 0
End If
' Stoppknopf
If Pinb.1 = 0 Then ' Timer STOPP
Stop Timer1
If A = 1 Then
Print "Das waren " ; C ; B ; "," ; "25 Sekunden"
End If
If A = 2 Then
Print "Das waren " ; C ; B ; "," ; "5 Sekunden"
End If
If A = 3 Then
Print "Das waren " ; C ; B ; "," ; "75 Sekunden"
End If
If A = 0 Then
Print "Das waren " ; C ; B ; "," ; A ; " Sekunden"
End If
End If
Return
Loop
Hallo derpedi,
ich kenn mich mit Basic nicht so gut aus, kann dir aber sagen, dass du, wenn du geschickt programmierst mit deiner Hardware eine Genauigkeit von 2-3µs bekommen kannst.
Gruß, Yaro
Setze dies
Timer1=62500
als ersten Befehl in die Isr_timer1, dann kommt der Interrupt exakt nach 0,25 Sekunden.
Aber:
Der On Timer1 Befehl sollte vor die Do...Loop.
Du musst die Prints aus der ISR nehmen. Die Ausführung dauert so lange, dass der nächste Interrupt schon wieder ansteht.
Wenn du unbedingt eine Ausgabe willst, dann
- setze in der ISR nur ein Flag
- prüfe dies in der Do...Loop ab
- setze das Flag zurück
- führe die Print Befehle aus.
Besserwessi
23.01.2010, 01:31
Ein Problem für die Genauigkeit kann es schon sein wenn der Timer Startwert jedesmal per Hand gesetzt wird. Mit den vorteiler 64 mag das gerade noch gehen, es kann aber gelegentlich Fehler geben.
Der Timer 1 hat auch einen mode bei dem die Hardware immer nur bis zu einem bestimmten Wert Zählt (CTC Mode).
Die Variablendeklaration gehört vor den eigentlichen Code. Die ISR kommt in der regel ganz ans Ende, nicht irgendwo in die Hauptschleife, und dazu noch mitten in ein IF... . Ein wunder das der Compliler sich da nicht beschwert.
Ich kenne mich wirklich nicht allzu gut mit Bascom und Programmierung allgemein aus, vielleicht könnt ihr nochmal drüber schauen ob alles gut aussieht. funktionieren tuts
siehts gut aus?
$regfile = "M8def.dat"
$crystal = 16000000
$baud = 9600
Config Portc = Output ' Kompletter C Port Output
Config Pinb.0 = Input ' Eingang 1
Config Pinb.1 = Input ' Eingang 2
Portb.0 = 0
Portb.1 = 1
Dim W As Word
Dim A As Integer
Dim B As Integer
Dim C As Integer
Do
Config Timer1 = Timer , Prescale = 64
A = 0 ' A = 1/4 Sekunden
B = 0 ' B = ganze Sekunden 1 - 9
C = 0 ' C = 10er Zahlen
W = Timer1
Timer1 = 62500
If Pinb.0 = 1 Then
Sound Portb.0 , 200 , 500 ' Startknopf
Print "Start"
Enable Interrupts
Enable Timer1 ' Timer: GO
' angeblich jetzt alle 0,25s
On Timer1 Isr_timer1
Do
Loop
Isr_timer1:
'Print "interrupt!" ; W
A = A + 1
If A = 4 Then
B = B + 1
A = 0
End If
If B = 10 Then
C = C + 1
B = 0
End If
Print C ; B ; " Sekunden"
End If
' Stoppknopf
If Pinb.1 = 0 Then ' Timer STOPP
Stop Timer1
Sound Portb.0 , 200 , 500
Waitms 10
Sound Portb.0 , 200 , 500
If A = 1 Then
Print "Das waren " ; C ; B ; "," ; "25 Sekunden"
End If
If A = 2 Then
Print "Das waren " ; C ; B ; "," ; "5 Sekunden"
End If
If A = 3 Then
Print "Das waren " ; C ; B ; "," ; "75 Sekunden"
End If
If A = 0 Then
Print "Das waren " ; C ; B ; "," ; A ; " Sekunden"
End If
End If
Return
Loop
Besserwessi
07.03.2010, 18:02
Wenn funktioniert ist gut, gut aussehen tut's aber nicht. Der Code ist immer noch fast so schlecht sortiert wie zuvor.
Mich wundert es, daß sich der Compiler nicht über die Unordnung beschwert.
peterfido
07.03.2010, 21:37
Meine StopUhr läuft recht genau. Den Code habe ich auf dem anderen Rechner.
Die Werte allerdings im Kopf...
Timer0
Quarzoszillator: 4 MHZ
Timerstartwert: 100
Prescaler 256
damit zählt er quasi die 100stel Sekunden.
Am Ende der Messung die Hundertstel Sekunden durch 600 teilen und vom Wert abziehen.
Wenn lZeit also die 100stel beinhaltelt:
lMerker = lzeit/600
lzeit=lzeit-lmerker
Dann nur noch die hundertstel in Stunden, Minuten, Sekunden, hundertstel aufteilen.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.