Hallo :)
Ich habe mal eine Frage zu dem Timer bzw dem Überlauf und die Auswertung
davon. Und zwar habe ich ein Rechtecksignal, in dem ich die Dauer des
jeweiligen High bzw Low Pegels messen will.
Ich habe bei Flankenwechsel also ein Interrupt ausgelöst, welches die
Periodendauer bestimmen soll. Wie bekomme ich das aber hin, wenn der
Timer (cont mode) einmal überläuft. Aus dem Family User Guide werde ich
nicht schlau und hier im Forum habe ich leider auch nicht das passende
gefunden.
Ich habe zwar schon ein wenig Probiert, jedoch ist dies nur für einen
einzigen Überlauf sinnvoll(soweit ich das richtig gemacht habe!?!?).
Ein kleines Problem nebenbei noch: Warum löst er mal nur auf steigenden
Flanken und mal auf fallenden Flanken aus, ändert sich jedesmal, wenn
ich das programm auf den uC lade?
Danke schonmal
Em Gr schrieb:> Ich habe bei Flankenwechsel also ein Interrupt ausgelöst, welches die> Periodendauer bestimmen soll. Wie bekomme ich das aber hin, wenn der> Timer (cont mode) einmal überläuft. Aus dem Family User Guide werde ich> nicht schlau und hier im Forum habe ich leider auch nicht das passende> gefunden.
Zuallererst mal:
Wenn deine Variablen start und stop unsigned 16-Bit Variablen sind, dann
kannst du dir das hier
if(stop>start)
{
periode=stop-start;
}
if(stop<start){
periode=(stop+(65535))-start;
}
sparen.
Durch die unsigned Arithmetik kommt auch dann das richtige Ergebnis
raus, wenn stop kleiner als start ist.
D.h. wenn zwischen start und stop nur ein einziger Überlauf liegt, UND
du nicht mehr als 65535 als Differenz rausbekommen kannst, dann reicht
es, wenn du rechnest
periode = stop - start;
und in allen Fällen kommt das richtige Ergebnis raus.
Nur dann, wenn deine Differenz prinzipiell größer als 65535 werden kann,
dann musst du die Überläufe auch tatsächlich berücksichtigen.
Und dann geht das so:
Wenn stop größer/gleich als start ist, dann werden für alle angefallenen
Überläufe jeweils 65536 addiert. Andernfalls wird die Anzahl der
Überläufe um 1 vermindert, weil durch die 16-Bit Subtraktion 1 Overflow
schon aus der Rechnung rausfällt.
if( stop < start )
nrOverflows--;
periode = (stop - start) + nrOverflows * 65536UL;
(und wenn du in dieses allgemeine Schema probehalber 1 Overflow
einsetzt, dann kommt dann auch raus, dass man 1 Overflow überhaupt nicht
berücksichtigen muss, weil sich dieser 1 Overflow durch das if zu 0
reduziert)
Leider hast du (wie so viele vor dir), wieder mal die
Variablendefinitionen nicht gezeigt, so dass man nicht sagen kann, ob da
16 Bit unsigned gerechnet wird (werden kann) oder nicht. Die
Definitionen bzw. die Datentypen von Variablen sind WICHTIG! Sie
bestimmen im Detail, wie Berechnungen durchgeführt werden!
Em Gr schrieb:> Ein kleines Problem nebenbei noch: Warum löst er mal nur auf steigenden> Flanken und mal auf fallenden Flanken aus, ändert sich jedesmal, wenn> ich das programm auf den uC lade?
(Ohne den MSP im Detail zu kennen)
Ich schätze mal, weil du hier
P1IES ^= BIT2; //Interrupt bei Flankenwechsel an BIT2
das Bit toggelst.
Setze es gezielt auf 0 oder auf 1, je nachdem wie du es brauchst. Beim
'Hochfahren' des Programms willst du gesicherte Verhältnisse und nicht
davon abhängen, wie das Bit vorher stand und auf welch dubiosen Wegen es
einen Reset überlebt hat.
Du willst es auf 1 haben? Dann setze es auch auf 1!
P1IES |= BIT2;
PIES steht für PortInterruptEdgeSelect.
Each PxIES bit selects the interrupt edge for the corresponding I/O pin.
Bit = 0: The PxIFGx flag is set with a low-to-high transition
Bit = 1: The PxIFGx flag is set with a high-to-low transition
Allenfalls musst du die Anfangsbedingung lesen bzw. kennen.
Vielen Dank für die schnellen Antworten :) TOP!!
Okay, den Sinn habe ich halbwegs verstanden, nur wie füge ich dies in
den Code ein, ich müsste ja quasi eine Abfrage haben, ob der Timer
übergelaufen ist und wenn, dann jedesmal nrOverflow++; ausführen, aber
wenn oder habe ich das jetzt immer noch nicht richtig verstanden?
Wieso bei nicht vorhanden Überlauf nrOverflow--;?
Hier ist mal der Code, den ich bis jetzt habe, ich dachte vorhin, das es
reichen würde.
Bitte nicht meckern wie, ich es angesetzt habe^^ bin noch Anfänger.
Es geht darum, ein Signal auszuwerten, welches 4 Byte enthält, und diese
sollen nun aus dem "eingefangenen" Signal herausgefiltert werden.
kurze Periode(egal ob low oder high) ist ne 0 und lange ist 1.
Dann wird dies in "zahl" geschrieben, und sobald zahl 8 bit voll hat,
wird zahl in zahl1-4 geschrieben und es fängt wieder von vorne an.
Em Gr schrieb:> Hat vielleicht jemand zu später Stund noch ne Ahnung?
1. Den Timer so konfigurieren oder teilen, dass kein Überlauf erfolgen
kann.
2. Timer mit Flankenwechsel synchronisieren.
3. Timer Interrupt nutzen und Überlauf erkennen und zählen.
4. In der Port1 ISR die Flankenauswertung umschalten.
TimerA schrieb:> 4. In der Port1 ISR die Flankenauswertung umschalten.
Klasse, es funktioniert zumindest schonmal mit dem Flankenwechsel :)
Mit dem TimerInterrupt bekomme ich jetzt auch halbwegs hin.
Danke ;)
Em Gr schrieb:> Klasse, es funktioniert zumindest schonmal mit dem Flankenwechsel :)> Mit dem TimerInterrupt bekomme ich jetzt auch halbwegs hin.> Danke ;)
Da dich ja sowieso nur interessiert, ob die Länge in bestimmten
Bereichen ist
1
//Periodenauswertung
2
if(periode>=signalmin&&periode<=signalminmax)
3
bit=0;
4
if(periode>=signalminmax&&periode<=signalmax)
5
bit=1;
und es dir auf die ganz genauen Werte eh nicht ankommt, würde ich an
deiner Stelle den Vorteiler des Timers soweit erhöhen, bis die erwartete
Pulslänge in einem Bereich ist, so dass nicht mehr als 65535 Timerticks
anfallen und ich somit Überläufe überhaupt nicht berücksichtigen muss.
Ich muss mir ja nicht selbst das Leben schwer machen.
Mit dem Timer Overflow funktioniert es leider noch nicht so ganz.
Ich glaube, dass ich das falsch verstanden/programmiert habe. Er zählt
zwar hoch(wenn der Zähler wieder auf 0 gesetzt wird) und wird auch bei
erkanntem Signal(Flankenwechsel) ausgewertet und wieder auf 0 gesetzt,
jedoch sind die Werte meiner Meinung nach zu hoch(mal 20-30 und mal ca.
1000-2000)..
Dieser dürfte doch bei der kurzen Dauer der Flankenwechsel höchstens ein
paar Werte ca.1-5 hoch gezählt werden und nur bei der Ruhephase in die
Höhe gehen!?
Karl Heinz Buchegger schrieb:> würde ich an>> deiner Stelle den Vorteiler des Timers soweit erhöhen
Also mal meine Gedankengänge:
Ich hab ein Rechtecksignal, mit unterschiedlich langen high und low
Flankenwechsel,
Kurzer Wechsel = 0, (ca. 40µs)
Langer/längerer Wechsel = 1, (ca 70µs)
Nun kommt eine Ruhephase, die ca. 20-30ms dauert.
Dann kommt wieder das Signal.
Soweit ich errechnet habe, beträgt einmal bis 65535 zählen ca. 4ms.
Deswegen kann ich doch denke ich mal gar keine Vorteiler setzen, da
sonst der schnelle Wechsel der Flanken zu schnell für ein ordentliches
Ergebnis sind oder sehe ich das falsch?
Wegen dme Overflowzähler:
Zwischen dem include und dem Port1 Interrupt habe ich folgendes
eingefügt:
Em Gr schrieb:> Vielleicht hilft es ja
Wem?
Du hast die notwendigen Tipps erhalten, jetzt bist dur dran.
Em Gr schrieb:> Also mal meine Gedankengänge:
Vergleiche den Timer mit einer Uhr: Er zählt die Sekunden. Bei einer
Minute erfolgt der Überlauf. Die Sekunden beginnen wieder bei Null und
die Minuten werden mit einem anderen Zeiger gezählt.
Der Sekundentakt reicht, um Minuten, Stunden, Tage, Wochen, ...
abzuleiten.