setzt mal den code rein damit man sehen kann wie weit du bist.
ansonsten sieh dir die timer funktion an und externen interuppt
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
was gibt es noch zu sagen
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
Hallo derpedi,
sieh dir mal folgenden code an:
Zu deinem Code kann ich nur folgendes sagen:Code:$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
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
...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.
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?
Code:$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
Lesezeichen