Folgendes Szenario stellt sich mir (momentaan in den Weg): Ich habe ein Rechtecksignal, dessen Frequenz ich mit Hilfe des Input Capture Unit des Timers 1 meines ATmega32 messen will. Soweit so gut, das funktioniert auch. Mit dieser Gemessenen Frequenz möchte ich jetzt eine Sinusschwingung mit PWM und Timer0 erzeugen. Dazu hab ich eine Tabelle im Flash abgelegt, welche 64 Werte eine viertel Sinusschwingung enthält. Um nun de aus den 64 Werten resultierenden 128 Schritte für eine komplette Periode zu durchlaufen lade ich in das OCR1A Register den gemessenen Frequenzwert, den ich zuvor 7 mal nach rechts verschoben habe (also durch 128 dividiert - wenn ich jetzt nicht ganz auf dem Schlauch stehe). Und da fangen die Probleme an. Timer1 läuft im "normal mode". die Interrupts für Input Capture und Output_Compare_1_A sind aktiviert und die ISRs sind vorhanden. Die Frequenzmessung allein funktioniert. Nun setze ich alles unter Strom und folgendes passiert: Solange das Rechtecksignal anliegt, erzeugt mir der Timer 0 entweder eine beliebige Gleichspannung, oder eine Frequenz von 0,8 Hz, aber feiner Sinus. Schalte ich jetzt mein Rechtecksignal ab, so erzeugt er mir genau die Frequenz, die ich an den Eingang als Rechteck angelegt habe als schöne Sinuswelle. Ich habe schon versucht, den Timer1 anzuhalten, als ich das OCR1A Register verändert habe (mehr eine Verzweiflungstat), habe OCR1B mit einbezogen, also beie Interrupts abwechseln ausgeführt und in der ISR des einen den OCR1x - Registerwert des anderen neu geschrieben. Bei der Frequenz handelt es sich um eine niedrige Frequenz von < 1kHz, also mein AVR sollte mit 16 MHz da locker mitkommen. Bei Timer 1 ist ein Prescaler von fclk/8 eingestellt. das reicht damit für einen Frequenzbereich von 30Hz bis 2MHz (theoretisch). Der dennoch relative kleine Prescaler ist auf eine möglichst hohe Auflösung der Frequenzmessung zurückzuführen, auch wenn ich diese im Moment nicht nutzen kann (Timer0). Der Sourcecode ist als anhang mit bei...
SIGNAL(SIG_INPUT_CAPTURE1) ... TCNT1 = 0x0000; ... Dann kann ja der compareinterrupt nicht gehen. Peter
Hallo Peter, danke für die Antwort, nur versteh ich's nicht ganz. Kannst du mir das genauer erkären? TCNT1 ist doch das Zählregister des Timer1, oder? Das will ich bei einem Capture-Ereignis zurücksetzen, so dass der Timer wieder von vorn beginnt. Und die Compare-Ereignisse sollten ja so ca. 128 mal dazwischen auftreten, da keine schnellen Frequenzändeerungen zu erwarten sind. Wo liegt mein Denkfehler??? THX
Laß doch den Timer durchlaufen und nimm dann die Differenz zum vorherigen Capturewert. Peter
Wenn Du den alten und den neuen capture-Wert in einer uint16_t Variablen speicherst und Dir sicher bist, daß zwischen beiden Ereignissen nicht mehr als ein Überlauf des Zählers erfolgt ist, kannst Du beide ohne Behandlung eines möglichen Überlaufs direkt subtrahieren.
Guten Morgen! Ich hab jetzt meinen Fehler gefunden. Hab in der ISR für das Capture-Ereignis das Compareregister nicht geladen. Da muß natürlich der erste Wert der gemessenen Zeit/128 drin stehen, sonst steht's bei 0x0000 und da passiert logisch nicht viel & das Nachladen des Registers bleibt da auch aus. Trotzdem danke an alle für eure schnelle Hilfe!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.