Forum: Mikrocontroller und Digitale Elektronik Nochmal PWM: was mache ich falsch?


von Luca B. (lucabert)


Angehängte Dateien:

Lesenswert?

Hallo, Leute!

Ich kämpfe immer noch gegen diesem Kompass und PWM...

Mir ist gesagt worden, daß PWM so arbeitet: ich bekomme ein Signal auf 
einem PIN, und ich muß zählen wie lange dieses Signal läuft.
Da der Kompass im schlimmsten Fall ein Signal vom 0.01ms schicken kann, 
soll ich einen Timer haben, der diese Auflösung hat.

Als Anhang mein Code. Leider funktioniert nicht, und ich verstehe 
wirklich nicht, was ich falsch mache...
Wenn ich die SIGNAL-Funktion so umschreibe:

SIGNAL(SIG_OUTPUT_COMPARE3A)
{
  usek1++;
  if(usek1 == 100000L)
  { // EINE Sekunde...
    sek++;
    usek1 = 0L;
  }
}

dann das Programm läuft. Sobald ich was mehr mache (auch nur ein a = a + 
1), stürtzt das Programm ab schon beim Init.
Warum, denn?!?

Kann jemand mir helfen?

Danke sehr!
Luca Bertoncello

von hans (Gast)


Lesenswert?

Deine Routine wird alle 10 µS per Interrupt aufgerufen. Aber wie
lang braucht die Routine?
Schau mal die .LST an und zähl die Takte zusammen, simuliere
im Studio oder setz mal den Timer höher.
Alle 5 Min. eine Routine mit 10 Min. Bearbeitungszeit schaft
kein AVR.
gruß hans

von Luca B. (lucabert)


Lesenswert?

Mmmm... du hast Recht...
Das habe ich total vergessen...

Dann würde diese Idee funktioneren?
Der Timer ist standardmäßig ausgeschaltet. Wenn ich ein Signal auf dem 
PIN bekomme, werde ich den Timer starten, und sobald dieses Signal vom 
PIN verschwindet, halte ich dem Timer.

Würde es gehen?

Nun kommt immer noch die Frage: wie kann ich ein Interrupt auflösen, 
wenn ein Signal auf einem PIN kommt oder verschwindet?
Und noch, wie kann ich NUR der Interrupt vom Timer3 starten/stoppen?

Danke!
Luca Bertoncello

von Oliver (Gast)


Lesenswert?

Schau dir mal den Input Capture Mode an. Damit klappt das besser.

Oliver

von Luca B. (lucabert)


Lesenswert?

@Oliver: ich versuche seit gestern diesen "Input Capture Mode" zu 
verstehen, aber erfolglos...

Deswegen will ich jetzt versuchen was selber zu schreiben...

Andere Idee, bzw. PRAKTISCHE Beispiele?

Danke
Luca Bertoncello

von Oliver (Gast)


Lesenswert?

Keine andere Idee. Nimm den Input-Capture-Mode.

Lass dein Timer mit einer passenden Taktfrequenz im Normalmode laufen. 
Dazu enablest du den Input Capture Mode, die Input-Capture-ISR, und, 
falls erforderlich, den overflow-ISR.

etwa so ( ins unreine, ungetestet ):
1
uint16_t capturevalue[2];
2
3
void timer1Init(void)
4
{
5
  TCCR1B = (1 << CS10); // normal mode, no prescaling
6
  TCCR1B |= (1 << ICES1); // input capture trigger on rising edge
7
  TIMSK |= (1 << TICIE1) | (1 << TOIE1); // Input Capture and Overflow interrupts enabled
8
}
9
10
ISR(TIMER1_CAPT_vect)
11
{
12
  static int8_t index = 0;
13
14
  capturevalue[index] = ICR1; // read and store capture value
15
16
  TCCR1B ^= (1 << ICES1); // toggle trigger edge
17
  TCCR1B |= (1 << ICF1); // clear IC flag after trigger edge change by writing it to 1
18
  index ^= 1; // toggle index
19
}

Der Prozessor speichert beim auftreten der steigenden Flanke ganz 
automatisch und alleine den aktuellen Timerwert im Input Capture 
Register, und löst dann den zugehörigen Interrupt aus. In der ISR holst 
du nun den Wert aus dem Register, und schaltest von steigender auf 
fallende Flanke um. Bei der folgenden fallenden Flanke wird wieder der 
Zählerstand abgespeichert, und schon hast du in capturevalue zwei Werte, 
aus denen sich im Hauptprogramm das PWM-Verhältnis berechnen lässt.

Die overflow-ISR brauchst du nur, falls der Timer innerhalb der 
PWM-Periode mehr als einmal überlaufen kann. Dann muß da noch ein Zähler 
eingebaut werden.

Oliver

von Luca B. (lucabert)


Lesenswert?

Danke, Oliver!

Nur 'ne Frage noch, und zwar: wie kann ich sagen, daß ich zB die PINE4 
als Auflöser nutzen kann?

Danke!
Luca Bertoncello

von Stefan E. (sternst)


Lesenswert?

> Nur 'ne Frage noch, und zwar: wie kann ich sagen, daß ich zB die PINE4
> als Auflöser nutzen kann?

Gar nicht. Input-Capture ist fest mit einem Pin verbunden, nämlich den, 
der mit "ICP" bezeichnet ist.

von Oliver (Gast)


Lesenswert?

Es ginge zwar noch über den Analog-Comparator, aber das bringt dich auch 
nicht auf Pin PE4 (obwohl du noch nicht verraten hast, welchen Prozessor 
du eigentlich einsetzt).

In dem Codebeispiel oben fehlt noch die Logik, die dem Hauptprogramm 
mitteilt, daß ein neues Wertepaar zur zur Auswertung vorhanden ist. Aber 
das kriegst du sicher selber hin.

Ausserdem sollte dein Prozessor nicht gerade mit 1Mhz Takt laufen. Wenn 
der kürzeste Puls 10 Microsekunden beträgt, wird das sonst knapp. Obwohl 
das ISR-Regsiter direkt am Anfang der Capture-ISR gelesen wird, vergehen 
doch einige Taktzyklen nach dem Auslösen des Interrupts. Da solltest du 
mal einen Simulator anwerfen, oder die Takte von Hand zählen.

Oliver

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.