mikrocontroller.net

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


Autor: Luca Bertoncello (lucabert)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Luca Bertoncello (lucabert)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau dir mal den Input Capture Mode an. Damit klappt das besser.

Oliver

Autor: Luca Bertoncello (lucabert)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ):

uint16_t capturevalue[2];

void timer1Init(void)
{
  TCCR1B = (1 << CS10); // normal mode, no prescaling
  TCCR1B |= (1 << ICES1); // input capture trigger on rising edge
  TIMSK |= (1 << TICIE1) | (1 << TOIE1); // Input Capture and Overflow interrupts enabled
}

ISR(TIMER1_CAPT_vect)
{
  static int8_t index = 0;

  capturevalue[index] = ICR1; // read and store capture value

  TCCR1B ^= (1 << ICES1); // toggle trigger edge
  TCCR1B |= (1 << ICF1); // clear IC flag after trigger edge change by writing it to 1
  index ^= 1; // toggle index
}

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

Autor: Luca Bertoncello (lucabert)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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.