mikrocontroller.net

Forum: Compiler & IDEs Variablenprobleme im Interrupt


Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
ISR(INT0_vect)
{
  uint16_t templaenge2;
  uint16_t templaenge;
  
  templaenge = (anzovfl << 8); //anz. Overflows seit letztem Flankenwechsel * 256
  templaenge += TCNT2; //Noch den aktuellen Timerwert dazu zählen
        //KONTROLLPUNKT
  templaenge2 = (uint16_t) templaenge / rcin_mikro_10; //Den Wert auf 100stel Millisekunden umwandeln.
  
  anzovfl = 0; //anz. overflows wieder auf 0
  TCNT2 = 0; // Timer auf 0
  ...
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:
ISR(INT0_vect)
{
  //uint16_t templaenge2;
  uint16_t templaenge;
  
  templaenge = (anzovfl << 8); //anz. Overflows seit letztem Flankenwechsel * 256
  templaenge += TCNT2; //Noch den aktuellen Timerwert dazu zählen
  //KONTROLLPUNKT
  templaenge/*2*/ = (uint16_t) templaenge / rcin_mikro_10; //Den Wert auf 100stel Millisekunden umwandeln.
  
  anzovfl = 0; //anz. overflows wieder auf 0
  TCNT2 = 0; // Timer auf 0
  ...
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

Autor: Frank Link (franklink)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Alex,

definier mal die Variable templaenge als

static uint16_t templaenge;

Das sollte genügen.

Gruß
Frank

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Muss die Division unbedingt in den Interrupt? Ist recht langsam und wird 
evtl. in der Varianten vom Compiler etwas herumgschoben.

Müsste man ansonsten den erzeugten Code ansehen.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was soll das "static" bringen, abgesehen von schlechterem Code?

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das static bringt nichts. Ich werde es mal mit einer klugen 
initialisierung des Timers probieren, um die / Rechnung wegzubekommen.
Danke schon mal für die vielen Antworten. Ich werde dann schreiben ob es 
klappt!
Grüsse Alex

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun habe ich es fangs zum einen Teil geschafft. Ich hatte das Prescaling 
des 8-Bit Timers2 vorher auf 8. Da ich mit 1 MHz arbeite (interner 
Takt), ergab das einen Wert von 1.25, durch den ich rechnen musste. Das 
hat anscheinend diese schwierigkeiten verursacht. Nun habe ich kein 
Prescaling mehr und kann durch 10 rechnen. Das macht er problemlos. Das 
ist jedoch nicht gerade eine gute Lösung, da ich diese Routine auch 
später noch einsetzen will mit anderen Takten. Wie könnte ich hier eine 
allgemeingültige Lösung finden?

Grüsse Alex

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Setz an deiner Auswertung an.
Wenn du dort einfach berücksichtigen kannst, dass alle Werte das 
Zehnfache von vorher sind, dann brauchst du gar nicht durh 10 
dividieren.

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich will aber machen, dass das Programm für spätere Anwendungen nur 
eingebunden und die Taktfrequenz angepasst werden muss. Dann will ich 
nicht den ganzen Code ändern... Somit könnte es einiges komplizierter 
werden.
Noch eine Frage dazu:
Wenn ich ein #define mache, z.B.:
#define MEINDEFINE1 100000
#define MEINDEFINE2 MEINDEFINE1/50
Nur so als Beispiel. Wird jetzt MEINDEFINE2 schon im Präprozessor 
berechnet und überall mit dem Ergebnis ersetzt, oder erst an der Stelle, 
an der ich es Anwende beim Programmlauf(z.B. bei jedem Programmdurchlauf 
neu berechnet?)?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alex wrote:

> Wenn ich ein #define mache, z.B.:
>
> #define MEINDEFINE1 100000
> #define MEINDEFINE2 MEINDEFINE1/50
> 
> Nur so als Beispiel. Wird jetzt MEINDEFINE2 schon im Präprozessor
> berechnet

http://www.mikrocontroller.net/articles/C-Pr%C3%A4...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.