www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART&Timer Interrupt


Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Morgen,

kann es sein dass sich der UART-Receive und der Timer-Compare Interrupt
irgendwie gegenseitig behindern?

Beide ISR-Routinen sind ziemlich lang. Macht es Sinn den einen
Interrupt auszuschalten und danach wieder ein, während der andere
läuft?

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Beide ISR-Routinen sind ziemlich lang.
Fehler! ISR immer so kurz wie möglich machen.

>Macht es Sinn den einen Interrupt auszuschalten und danach wieder
>ein, während der andere läuft?

Beim AVR ist immer nur eine ISR aktiv. Während ihrer Abarbeitung können
zwar andere Interrupts auftreten, diese werden aber erst noch Beendigung
der ISR bearbeitet.

Verkürz die beiden ISR auf das nötigste, dann hast du auch keine
Probleme mit Überschneidungen.
(USART-Empfang kann man gut in einem Ringpuffer zwischenlagern...)

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Verkürz die beiden ISR auf das nötigste..

Exakt! (Meine) Goldene Regel:
Mache möglicht viel mit, aber möglicht wenig in Interrupts

Autor: Thilo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und die Prioritäten der Interrupts beachten, falls mehrere gleichzeitig
aktiv sind!

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ändert sich leider gar nichts.

Das erzeugte Signal ist soweit auch in Ordnung, nur alle 5-10s gibt es
irgendwie nen Ruckler, so ähnlich wie ne Spannungsspitze.

Aber komisch dass es nur alle 5-10s auftritt, obwohl der UART alle 90ms
ausgewertet wird...

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann hast du scheinbar ein anderes Problem...

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und was kann das sein?

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zeile 42...(in deinem nicht geposteten Quellcode)

Autor: Björn (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, vergessen!

Hier ist der Code......

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
tmp2 = array2;
          for( i = 1; i; i *= 2 )
          *(tmp2++) = (c&i) ? 54 : 35;

        Array_Servo2[3]  = array2[0];
        Array_Servo2[5]  = array2[1];
        Array_Servo2[7]  = array2[2];
        Array_Servo2[9]  = array2[3];
        Array_Servo2[11] = array2[4];
        Array_Servo2[13] = array2[5];
        Array_Servo2[15] = array2[6];
        Array_Servo2[17] = array2[7];

       state = STATE_IDLE;

Den "Klotz" hast du doppelt...

Einfacher wäre es, wenn du ein Feld mit 2 Indizes benutzen würdest:
Array_Servo[2][18]
Dann könntest du in Abhängigkeit des "states" das jeweilige Feld
beschreiben.
Und wenn du ein wenig rechnest, kannst du dir die Hilfsfelder
sparen...

das würde dann so aussehen:
tmp = 3;
for( i = 1; i; i *= 2 )
{
 Array_Servo[ServoNr][tmp] = (c&i) ? 54 : 35;
 tmp += 2;
}
state = STATE_IDLE;

Du kannst dir auch eine Menge Speicherplatz sparen, wenn du nur eine
Hilfsvariable/-Feld benutzt. Es kann ja nicht passieren, dass auf beide
Felder gleichzeitig zugegriffen wird.
Dass man das alles noch etwas weiter verschönern kann, hatte ich ja
irgendwann schon mal erklärt...

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könntest du bitte noch mal die gesamte Problemstellung aufschreiben?
Es ging irgendwie um die Erzeugung verschiedener Puls-Längen in
Abhängigkeit empfangener Datenbytes, oder?

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genau!

Also,

mit dem Timer Interrupt erzeuge ich mir ein Signal.
Bei diesem Signal (Highpegel ) sollen alle ca. 90ms neun Low-Pegel mit
einer bestimmten Länge erzeugt werden.

Also erst mal 90ms Highpegel, dann ein Lowpegel von 45µs, ein Highpegel
von 120µs, 50µs Low, 120µs High, 50µs Low, 120µs High, 50µs Low, 120µs
High, 50µs Low, 120µs High, 50µs Low, 120µs High, 50µs Low, 120µs High,
50 µs Low, 120 High, 40 µs Low und dann wieder 90ms Pause.

Mit diesem auf den ersten Blick komischen Signal soll ein Servo
angesteuert werden. Kein Standard Servo! Dieser Servo benötigt ein
Start-Bit(hier die 45 µs) und dann 8 weitere Bit für die jeweilige
Stellung. Dabei sind 40µs eine 0, und 50µs eine 1. Heißt also wenn
alle Bits 1 sind ganz nach rechts, wenn alle Bits 0 sind ganz nach
links. Die voreingestellten Werte sind für die Mittelstellung.

Nun soll ein ankommendes Byte über UART so ausgewertet werden, dass
mir die Bits entsprechend gesetzt werden. Funktioniert auch alles
bestens.

Nun benutze ich das STK500 mit einem Atmega88 drauf. AD-Wandler
eingerichtet und den Servo über ein Poti gesteuert. Klappt auch alles
Prima. Servo fährt in alle Positionen und auch ohne diese komischen
Ausschläge alle paar Sekunden.

Das Problem tritt nur auf, wenn ich jetzt zwei STK500 verwende. Das
eine verwende ich als Sender, das andere als Empfänger. Verbunden sind
die beiden über UART. Masse ist auch verbunden. Wenn ich nun mit einem
Poti an einen Board, den Servo am anderen Board steuern will treten
diese komischen Ausschläge des Servos alle paar Sekunden auf. Ansonsten
fährt der Servo aber in die gewünschten Positionen.

Nun weiß ich nicht wie ich diese komischen Ausschläge da weg bekommen
kann.....

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weiß keiner woher das kommen könnte?

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab es immer noch nicht hinbekommen! ;-(

@Jonny:

Wozu steht denn das temp = 3; in folgenden Teilstück?

tmp = 3;
for( i = 1; i; i *= 2 )
{
 Array_Servo[ServoNr][tmp] = (c&i) ? 54 : 35;
 tmp += 2;
}
state = STATE_IDLE;


Hab das Stück Code was du oben gepostet hast noch nicht ganz kapiert.

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bin zwar nicht Jonny, aber wenn du dir den Verlauf der Schleife
anguckst, stellst du fest, dass das Array ab Eintrag Nummer 3 erst
verändert wird (die Einträge davor sind ja quasi konstant).
Danach werden wird nur jeder 2. Eintrag (die mit ungeradem Index)
verändert.
So kann man sich die Verwendung des Hilfsarrays sparen.
Du solltest das "Programm" einfach mal auf Papier "ablaufen" lassen
und die einzelnen Werte aufschreiben. Das bringt IMHO mehr als wenn man
sich das im Simulator anguckt.

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah, jetzt hab ich es kapiert! DANKE!

Doch das andere Problem lässt sich einfach nicht lösen! Haste da nicht
auch ne Idee?

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Leider nicht.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schade, aber trotzdem Danke!

Hab da noch ne Frage...

Du hast mir oben das geschrieben:

tmp = 3;
for( i = 1; i; i *= 2 )
{
 Array_Servo[ServoNr][tmp] = (c&i) ? 54 : 35;
 tmp += 2;
}
state = STATE_IDLE;


müsste es nicht:

*tmp = 3;
for( i = 1; i; i *= 2 )
{
 Array_Servo[ServoNr][*tmp] = (c&i) ? 54 : 35;
 tmp += 2;
}
state = STATE_IDLE;

heißen. Also noch die Sternchen davor?

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein.
tmp ist einfach nur ein Zähler (Byte-Variable). Natürlich kannst du den
auch als Pointer deklarieren - das kostet aber unnötig Speicherplatz.
Die Deklaration hätte ich vielleicht noch dazuschreiben sollen.

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.