Kommt der µC überhaupt in die ISR?
Die Berechnung hat da drinn auch nichts verloren!
Lass dir halt mal die Einzelwerte ausgeben. Dich interessieren die
Timerticks, die du für die High-Phase gemessen hast und die Timer Ticks,
die du für die Low Phase gemessen hast. Dann sieht man auch schon mal,
ob man sich bei den Flags vertan hat, und die Werte dauernd die Plätze
wechseln. Wenn man ganz hinten in einer Berechnung Blödsinn rauskriegt,
dann schaut man sich halt mal die Eingangswerte in diese Berechnung an.
Denn wenn die schon falsch sind, dann ist klar, dass hinten nichts
richtiges rauskommen kann. Diese Binsenweisheit scheint aber zu einfach
zu sein, interessanterweise muss man das den Leuten immer wieder
beibringen.
Du solltest auch bedenken, dass dir die Umschaltung der Flankenrichtung
einen Interrupt bescheren kann. Wenn man sich die gemessenen Timerticks
ansehen würde, könnte man das in den Zahlenwerten sehen, wenn die
Differenzen lächerlich unrealistisch gering sind.
In einer ISR sind die Interrupts sowieso ausgeschaltet. Du brauchst da
nichs aktivieren oder deaktivieren. Ganz im Gegenteil: in einer iSR die
Interrupts wieder zu aktivieren, kann gefährlich sein.
Stell den ganzen Timer auch so, dass du Overflows im Zählbereich erst
mal ignorieren kannst. Eine PWM ändert sich ja normalerweise nicht in
der Frequenz. d.h. das kann man so einstellen, dass ein kompletter PWM
Zyklus nicht länger als 65535 Timertakte dauert. Dann bist du das
Problem der fast (aber doch nicht) gleichzeitigen Capture und Overflow
Interrupts fürs erst mal los (was nicht heisst, dass man sich nicht
später doch noch drum kümmert).
Alles in allem wieder mal Kardinalfehler Nummero Uno: zuviel auf einmal
geschrieben ohne zwischendurch zu testen. Nichts geht und in dem ganzen
Wust weiss man nicht wo man mit der Fehlersuche anfangen soll. Alles was
man weiss ist, dass ganz hinten am Ende einer längeren Kette von
Ereignissen nicht das richtige rauskommt - Hilfe!
1 | volatile Variable 'Begin' // Timerstand bei der ersten steigenden Flanke
|
2 | volatile Variable 'EndPuls' // Timerstand am Ende des Highpulses
|
3 | volatile Variable 'Ende' // Timerstand nach der Low-Phase (beendet durch steigende Flanke)
|
4 | volatile Variable 'Wertetriplett ist komplett'
|
5 |
|
6 | ISR( ... )
|
7 | {
|
8 | if( steigende Flanke ) {
|
9 | if( ersteFlanke ) {
|
10 | if( Wertetriplet nicht komplett ) { // Sicherung, dass die main mit
|
11 | // der Auswertung hinterher gekommen ist
|
12 | Wert für Begin merken
|
13 | umschalten auf fallend
|
14 | merken, dass erste Flanke durch
|
15 | }
|
16 | }
|
17 | else {
|
18 | Wert für komplett Ende merken
|
19 | nächste steigende Flanke ist wieder erste Flanke
|
20 | signalisieren, dass das Wertetriplet komplett ist
|
21 | }
|
22 | }
|
23 |
|
24 | else { // muss eine fallende Flanke gewesen sein
|
25 | (sicherheitshalber könnte man überprüfen, dass die erste Flanke
|
26 | bereits gekommen sein muss. Denn 1 fallende Flanke muss ja
|
27 | ausgelassen werden)
|
28 | Wert für EndPuls merken
|
29 | umschalten auf steigend
|
30 | }
|
31 | }
|
32 |
|
33 | main
|
34 | {
|
35 | ....
|
36 |
|
37 | while( 1 ) {
|
38 |
|
39 | if( Wertetriplet komplett ) {
|
40 | ausgeben ( Begin )
|
41 | ausgeben ( EndPuls )
|
42 | ausgeben ( Ende )
|
43 |
|
44 | Wertetriplet = nicht komplett
|
45 | }
|
46 | }
|
47 | }
|
dann sieht man sich mal die gemessenen Timerwerte an.
Beachte auch, dass man sich die ganze Sache mit der ersten steigenden
Flanke auch sparen könnte. Denn die steigende Flanke, die die Low-Phase
beendet, ist ja auch gleichzeitig die steigende Flanke, die den nächsten
Puls beginnt.