Hallo zusammen,
wieder einmal etwas von mir. Ich bin mir gerade ein Programm zum
Einlesen von RC-Kanälen am machen. Ich habe mich für eine nicht ganz
sooo schöne Lösung für einen Mega8 entschieden, da ich nur solche
besitze und nicht auf andere warten will.
Die Lösung ist für max. 7 Kanäle und man darf nur eine ungerade Anzahl
einlesen. Dabei muss man die Kanäle 1,3,5,7 (sofern so viele vorhanden,
geht auch mit weniger) über Dioden an Int0 anschliessen. Die Kanäle
müssen von einem Empfänger sein. Die Kanäle 2,4,6 müssen nicht
angeschlossen werden (dürfen auch nicht).
Das gibt mir ein schönes Rechtecksignal, welches ich über int0 auslesen
kann.
Es funktioniert alles fast wie es sollte. Nur noch kleine Sachen gehen
nicht wie sie sollen. Jedenfalls kann ich das Signal auswerten und ich
habe alles geprüft. (habe es erst mit einem Kanal versucht, aber sollte
auch mit mehr gehen.)
Nun gibt es aber ein Problem, das ich nicht begreife. Der Anfang meines
int0 Interrupts sieht so aus:
1 | ISR(INT0_vect)
|
2 | {
|
3 | uint16_t templaenge2;
|
4 | uint16_t templaenge;
|
5 |
|
6 | templaenge = (anzovfl << 8); //anz. Overflows seit letztem Flankenwechsel * 256
|
7 | templaenge += TCNT2; //Noch den aktuellen Timerwert dazu zählen
|
8 | //KONTROLLPUNKT
|
9 | templaenge2 = (uint16_t) templaenge / rcin_mikro_10; //Den Wert auf 100stel Millisekunden umwandeln.
|
10 |
|
11 | anzovfl = 0; //anz. overflows wieder auf 0
|
12 | TCNT2 = 0; // Timer auf 0
|
13 | ...
|
Wie gesagt, so funktioniert alles. Nun finde ich das aber recht unschön
und ich will hier alles mit einer tempvariablen machen. Dann sieht der
Code so aus:
1 | ISR(INT0_vect)
|
2 | {
|
3 | //uint16_t templaenge2;
|
4 | uint16_t templaenge;
|
5 |
|
6 | templaenge = (anzovfl << 8); //anz. Overflows seit letztem Flankenwechsel * 256
|
7 | templaenge += TCNT2; //Noch den aktuellen Timerwert dazu zählen
|
8 | //KONTROLLPUNKT
|
9 | templaenge/*2*/ = (uint16_t) templaenge / rcin_mikro_10; //Den Wert auf 100stel Millisekunden umwandeln.
|
10 |
|
11 | anzovfl = 0; //anz. overflows wieder auf 0
|
12 | TCNT2 = 0; // Timer auf 0
|
13 | ...
|
In der ersten (unschönen) Variante geht alles wie es sollte und beim
KONTROLLPUNKT kommt ein Wert, der dem Timerabstand seit dem letzten
Flankenwechsel entspricht.
Bei der zweiten Variante kommt beim KONTROLLPUNKT (der noch VOR der
Änderung des Codes liegt!!!!!) immer der selbe Wert.
Beim Rest des Interruptcodes ersetze ich einfach noch an einer Stelle
das templaenge2 mit templaenge.
An was liegt dieses Komische verhalten?
Grüsse Alex