UART&Timer Interrupt

Gast #398843
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?
Gast #398844
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...)
Gast #398852
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...
Gast #398854
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.....
Gast #398857
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.
Gast #398860
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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren