-
Hall zusammen habe mich in den letzten Tagen noch einmal mit dem Thema auseinandergesetzt :
Dabei ist jetzt folgende Frage aufgetreten :
es braucht ja für den syncimpuls einen zusätzlichen timer dei startet wenn und wenn der impuls länger als 2.5 auf high bleibt überläuft.
Welche werte müsste dann der Timer haben , mein e nbisherigen berechnungen scheiterten
und wäre es auch möglich einen 16mhz quarz zu verwenden ? wie müsste dann der andere timer sein ?
viele fragen hoffe mir kann jemand helfen
-
Das kann man ganz einfach überschlagen:
16 MHz und ein Prescaler Prescaler von 256 ergeben eine Timer-Taktfrequenz von 62,5 kHz. Damit zählt der Timer alle 16µs um einen Schritt hoch. Nach einer Laufdauer von 2,5ms wäre er damit bei 156, und ein 8-bit-Timer würde nach ca. 4,1 ms überlaufen. Damit würde einer der beiden "kleinen" Timer reichen, und Du bräuchtest den Timer nach einem Überlauf noch nichtmal auf einen bestimmten Vorwert einzustellen sondern hättest sogar noch etws "Luft", falls einzelne Servo-Impulse vielleicht doch mal länger sind als 2,5ms.
Du musst aber natürlich wissen, ob der Ruhe-Pegel nach dem letzten Servo-Impuls High oder Low ist.
-
so was ich rausgefunden habe ist der pegel high .. habe es jetz mal soweit so gelöst timer1 für syncimpuls timer 0 für servoimpuls timer1 mit timervorgabe timer 0 mit prescaler da mir das gerade einfacher erschien. Wenn das Signal auf high geht wird auch timer 0 gestartet überläuft er war der iMpuls länger als 2.5 ms.
Code:
Dim Impulsdauer(3) As Word
Dim N As Byte
N = 1
Const Timervorgabe = 216
Config Timer1 = Timer , Prescale = 1
Config Timer0 = Timer , Prescale = 256
On Timer1 Timer_irq 'sync impuls bei overflow
Enable Timer1
Enable Timer0
Config Int1 = Change
On Int1 Flanke 'ISR bei Flankenwechsel
Enable Int1
Enable Interrupts
Do
Loop 'Hier läuft Dein Hauptprogramm
Flanke:
If Pinb.0 = 1 Then
Start Timer1
Start Timer0
Else
Stop Timer1
Stop Timer0
Impulsdauer(n) = Timer0
N = N + 1
End If
Return
Timer_irq:
Timer1 = 65496
N = 1 ' Wenn Timer überläuft handelt es sich um synchronisationsimpuls
Stop Timer0
Return
stimmt das in etwa ?
mfg
-
Zitat:
stimmt das in etwa ?
Fast... =P~
Bis auf 2 Stellen:
1.: Nach der Sequenz
Code:
Impulsdauer(n) = Timer0
N = N + 1
musst Du unbedingt beide Timer auf Null setzen - sonst zählen sie einfach von ihrem Zwischenstand weiter, und Du bekommst nicht nur falsche Impulslängen-Ergebnisse, sondern auch vermeintliche Synchronisationsimpulse, wo eigentlich gar keine waren.
2.: Wenn Du Timer 1 mit 65496 vorlädst, läuft er schon nach 40 Takten über. Bei 16 MHz und einem Prescaler von 1 wäre das nach 2,5 Mikrosekunden. Da er aber erst nach 2,5 Millisekunden überlaufen soll, muss er bis 40.000 zählen, also von einem Ausgangswert von etwa 25000 starten.
Ganz allgemein könntest Du (bei positivem Synchronisationssignal) mit einem Timer auskommen: Wenn er vor dem Überlauf angehalten wird (d.h. Impuls kleiner als 2,5ms) wertest Du den Zählerstand als Impulslänge aus, und wenn er überläuft (Impuls länger als 2,5ms) wird das als Synchronisationsimpuls gewertet (und N=1 gesetzt). Aber das ist halt eine Frage des Umgangs mit Ressourcen O:)
Und es ist etwas uneffektiv, den wesentlich höher auflösenden 16-Bit-Timer 1 für so etwas "grobes" zu verwenden wie die Entscheidung, ob der Impuls länger als 2,5ms ist, während die Impulslänge selbst von dem wesentlich ungenauer auflösenden 8-Bit-Timer gemessen wird. Aber auch das ist eine Frage der "B-Note" - funktionieren sollte Dein Code mit den genannten Änderungen trotzdem!
-
Habe es jetzt noch mal mit 2 timern gemacht um zu schauen ob ich die richtigen werte bekomme lasse ich mal die werte printen
$regfile = "m32def.dat"
$crystal = 3686400
Dim Impulsdauer(3) As Word
Dim N As Byte
N = 1
Const Timervorgabe = 216
Config Timer1 = Timer , Prescale = 1
Config Timer0 = Timer , Prescale = 256
On Timer0 Timer_irq
'sync bei Timer-Overflow
Enable Timer1
Enable Timer0
Stop Timer0
Config Int1 = Change
On Int1 Flanke 'ISR bei Flankenwechsel
Enable Int1
Enable Interrupts
Do
Loop 'Hier läuft Dein Hauptprogramm
Flanke:
If Pinb.0 = 1 Then
Start Timer1
Start Timer0
Else
Stop Timer1
Stop Timer0
Impulsdauer(n) = Timer1
Print Impulsdauer(n)
N = N + 1
End If
Print "flanke"
Timer0 = 100
Timer1 = 25536
Return
Synchronisationsimpuls: 'Wechselt Kanal zutück auf 1
Print "sync"
Return
Timer_irq:
Stop Timer0
Timer0 = 100
N = 1 ' Wenn Timer überläuft handelt es sich um synchronisationsimpuls
Print "timer irq"
Stop Timer1
Stop Timer0
Return
Die Werte für Timer1 bleiben erst ein paar mal unverändert dann plötzlich ist timer1 = 0 und beim nächsten mal stimmt es wieder ..
ideen?
mfg
EDIT : DUMMER FEHLER !! liegtt daran dass es verscheidene impulsdauern gibt (1,2,3)
-
So muss den Thread mal wieder etwas ausgraben..
Habe in den letzten Wochen etwas rumexperimentiert.
Habe mal nur mit einem Kanal experimientiert und mit diesem Code
'Pin D3 wird mit Empfänger verkabelt
$regfile = "m32def.dat" ' bei Mega 16 $regfile = "m16def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 16000000 'Quarzfrequenz
$baud = 9600
Dim Impulsdauer As Single
Dim Puls As Word
Config Int1 = Change
On Int1 Flanke 'ISR bei Flankenwechsel
Enable Int1
Enable Interrupts
Do
Print Puls
Loop 'Hier läuft Dein Hauptprogramm
Flanke:
Pulsein Puls , Pind , 3 , 1
Return
Leider kommt das Programm gar nie zum Hauptteil also zur ausgabe der Pulslänge sondern ist immer bei der Flanke am messen ?!
Gibt es irgendwelche Lösungen oder Ahnungen woran das das liegen könnte ?
mfg