PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RN-Control stürzt ab wenn Timer0 ISR ausführt



Chattychan
25.07.2007, 16:28
Hallo,

ich möchte mit der RN-Control ein einfaches Servo von Conrad
per Software PWM ansteuern. Komisch ist wenn der Controller die
ISR ausführt dann stürzt er ab. Servo bewegt sich kurz und macht dann
nichts mehr. Ich hab auch schon alles mögliche ausprobiert und
per Try and Error andere Werte eingesetzt jedoch verhält sich
der Servo stets gleich. Kurze Bewegung und stop.
Vielleicht kann mir ja einer weiterhelfen...

Hier der Code:


#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

int ontime = 0;
int offtime = 2000;

ISR(TIMER0_COMP_vect)
{
static int onBuf;

if( offtime - ontime > 0 )
{
onBuf = ontime;
offtime--;
}
else
{
if( onBuf == 0 )
{
offtime = 2000;
PORTA &= ~0x80;
onBuf = ontime;
}
else
{
if( onBuf == ontime )
PORTA |= 0x80;
onBuf--;
}
}
}

int main(void)
{

DDRA = 0x80;
PORTA = 0x00;

// CLK/8 Prescaler CS01
TCCR0 = (1<<CS01);

OCR0 = 20; // 16000000/8 = 1999490/20 = 99974,50Hz => 0,01ms

TIMSK |= (1<<OCIE0);

sei();

int i = 0;

ontime = 3; // links

for(i=0;i<312;i++)
_delay_ms( 16 );

ontime = 11; // mitte

for(i=0;i<312;i++)
_delay_ms( 16 );

ontime = 19; // rechts

for(i=0;i<312;i++)
_delay_ms( 16 );

ontime = 0;

while(1);
}

Viele Grüsse
Thomas

uwegw
25.07.2007, 16:36
Du solltest ontime und offtime als volatile deklarieren.

Chattychan
25.07.2007, 17:29
Hallo uweg,

danke für die zügige Antwort. Leider bringt es nicht den erhofften
Erfolg. Aber ich deklariere die Variablen trotzdem als volatile.
Danke für den Tipp. Hab wieder was dazugelernt.
Hast du oder jemand anderes noch eine weitere idee wodran es liegen könnte ?

Viele Grüsse
Thomas

CowZ
25.07.2007, 19:56
Hi,

vielleicht kann es auch daran liegen, dass neben dem COMP IRQ ein anderer Interrupt ausgelöst wird. Ist dieser nicht implementiert, springt das Programm zurück zum reset.

Gruß, CowZ

uwegw
25.07.2007, 21:43
Wenn ich das Programm kompiliere sieht das listing (.lss-Datei) soweit in Ordnung aus. Nur ein Interrupt aktiv.

Hängt der AVR wirklich komplett, oder reagier der Servo bloß nicht auf die Ansteuerung? Hast du mal irgedwas anderes ausgeben lassen, zb ne LED blinken während der Warteschleifen? Du müssest mal schrittweise analysieren, wo das Programm wirklich hängen bleibt. Also zb ne LED einschalten, und den Einschaltbefehl dann immer weiter nach hinten verschieben.

Chattychan
26.07.2007, 14:34
Hallo,

ich werd das gleich mal mit dem LED testen.

Also der Servo bewegt sich einmal ca 5-10% nach rechts. Das macht der jedesmal
wenn ich das RN-Control resette, also nach 10-20 resets liegt der Servo
rechts im Anschlag. Laut Programm müsste der aber doch folgendes machen:

links

schleife abwarten

mitte

schleife abwarten

rechts

Hab ne Frage zu dem Programm, da ich es nicht selber geschrieben habe
weil ich noch AVR Anfänger bin.

Frage1:
Was soll die Variable OCR1 = 20 eigentlich bewirken ?
Also ich meine soweit ich das mit den Timern verstanden habe,
zählt Timer0 im 8-Bit Mode hoch bis 255 und fängt dann wieder
bei 0 an. Wenn Timer0 und OCR1 übereinstimmen wird ein Interrupt
ausgelöst. Also einmal im Bereich von 0-255. Dann ist es doch
egal ob OCR1 = 40 oder 20. Fakt ist der Interrupt wird einmal ausgeführt
in der Zeit die der Controller braucht um bis 255 zu zählen.
Wenn hingegen der Timer0 wieder bei 0 anfängt wenn der Interrupt
ausgelöst wird , dann ist mir alles klar. Dann ist die PWM Frequenz die
Zeit die der Controller braucht um von 0 bis OCR1 zu zählen.

Frage2:
Offtime ist doch die Spanne in der der PWM-Port (PA0) auf ca 0V liegt.
Ontime die Zeitspanne in der PA0 auf 5V liegt.
Komisch finde ich nur dass der offtime anteil bei 2000 liegt und
der ontime grade mal bei 3.
Mittelstellung wäre doch wenn offtime 2000 und ontime 1000 wäre
also die hälfte der "Amplitudendauer" ein und die hälfte aus.
Der Timer0 bringt doch nur die Frequenz in der die "Amplituden"
erzeugt werden , oder hab ich was falsch verstanden ?

Viele Grüsse und DANKE !
Thomas

uwegw
26.07.2007, 15:17
Also der Servo bewegt sich einmal ca 5-10% nach rechts.

Das ist normales Einschaltverhalten der Servos, wenn kein Impuls angelegt wird.

Bis du eigentlich sicher, dass du am richtigen Anschluss hängst?



Hab ne Frage zu dem Programm, da ich es nicht selber geschrieben habe
weil ich noch AVR Anfänger bin.



Frage1:
Was soll die Variable OCR1 = 20 eigentlich bewirken ?
Also ich meine soweit ich das mit den Timern verstanden habe,
zählt Timer0 im 8-Bit Mode hoch bis 255 und fängt dann wieder
bei 0 an. Wenn Timer0 und OCR1 übereinstimmen wird ein Interrupt
ausgelöst. Also einmal im Bereich von 0-255. Dann ist es doch
egal ob OCR1 = 40 oder 20. Fakt ist der Interrupt wird einmal ausgeführt
in der Zeit die der Controller braucht um bis 255 zu zählen.
Wenn hingegen der Timer0 wieder bei 0 anfängt wenn der Interrupt
ausgelöst wird , dann ist mir alles klar. Dann ist die PWM Frequenz die
Zeit die der Controller braucht um von 0 bis OCR1 zu zählen.

Die Frequenz bleibt ja immer gleich (müssen 20ms pro Durchlauf sein). Was sich ändert, ist das Verhältnis von Impuls zu Pause. Das wird erreicht, indem der Compare-Match mal früher und mal später (je nach OCR0) auftritt.



Frage2:
Offtime ist doch die Spanne in der der PWM-Port (PA0) auf ca 0V liegt.
Ontime die Zeitspanne in der PA0 auf 5V liegt.
Komisch finde ich nur dass der offtime anteil bei 2000 liegt und
der ontime grade mal bei 3.
Mittelstellung wäre doch wenn offtime 2000 und ontime 1000 wäre
also die hälfte der "Amplitudendauer" ein und die hälfte aus.
Der Timer0 bringt doch nur die Frequenz in der die "Amplituden"
erzeugt werden , oder hab ich was falsch verstanden ?

Ein Servo reagiert anders als ein Motor! Die Zykluszeit ist immer 20ms, und der impuls dauert zwischen 1 und 2ms. Ruhestellung ist 1,5ms.

Chattychan
27.07.2007, 14:46
Hallo,

also ich hab das mit den LEDs jetzt mal getestet. Ich hab
die 8 LEDs von der RN-Control (PORTC) komplett
über die Main(void) verteilt. Alle LEDs leuchten.
Also wird das Programm komplett abgearbeitet.
Komisch ist hingegen wieder , wenn ich in der ersten Schleife
die das erste Delay ausführt den Wert von i<312 auf 3120 ändere dann dimmt es die LEDs
die im Programmfluss weiter unten leuchten sollen.
Was hat diese Schleife denn mit der Leuchtintensität der LEDs
zutun ? Sie dimmt sie wirklich. Hab zuerst gedacht die Schleife dauert
so lange, aber dann hab ich mich an den Wert rangetastet so dass man
sieht dass sie gedimmt werden.



Bis du eigentlich sicher, dass du am richtigen Anschluss hängst?
Ich bin mir sicher dass das gelbe Kabel vom Servo am richtigen Port
hängt. Rot ist an 5V und Schwarz an GND.

Komisch ist jetzt auch, wenn ich mit dem gelben Kabel direkt an
die Buchsenleiste von PortA gehe und es an den richtigen Port dran halte dann ruckelt
der Servo mal nach links mal nach rechts. Wenn ich das schneller mache
dann verhält sich der Servo unkontrolliert.

Viele Grüsse
Thomas

Chattychan
30.07.2007, 12:25
Hallo,

noch einer da ?

Gruss
Thomas

uwegw
30.07.2007, 12:52
Hab mal das Programm auf nen M32 gespielt und mit dem Oszi nen Blick drauf geworfen. Das Timing stimmt absolut nicht...

Chattychan
31.07.2007, 10:54
Hi,

danke für deine Antwort.

Ich bin leider noch etwas unerfahren in der Timer Programmierung. Hab das so
übernommen weil in einem anderen Thread jemand meinte das läuft bei
ihm so wie es soll.

Kurze Frage:
Ein 8-Bit Timer läuft ja bis 255 und fängt dann wieder bei 0 an. Is klar.
Setzt der Timer sich auch bei einem Compare Match auf 0 ?
Also dann wenn das Zählregister und OCR0 übereinstimmen.

Wenn nicht dann kann ich ja die Frequenz nur mittels dem Prescaler bestimmen?! Die Zähldauer (zeit im ms von 0 - 255) hängt ja nur vom
Takt des proz ab.

Verzeih mir meine dummen Fragen. Hab aus dem avr-gcc tut von mikrocontroller.net nicht alles über timer rausfinden können.
Hast du einen guten Link darüber ?

Danke !

Gruss
Thomas