Hallo allerseits! Ich habe eine Frage bzgl des Overflow Interrupts beim
Timer/Counter0 des ATMega324A. Ich habe den unten aufgeführten Code. Ich
hab diesen zunächst nur mit Hilfe des Datenblatts erstellt. Dieser
scheint mir aber korrekt, da in den Threads, die ich hier im Forum
gefunden hab, es genauso gemacht wurde. Nun mal zur genauen
Problembeschreibung.
Ich will Timer0 im "Phase correct PWM mode" betreiben. Gemäß des
Datenblatts wird jedes mal wenn der Timer wieder den BOTTOM-Wert
erreicht hat das Timer/Counter Overflow Flag gesetzt, wodurch der
Interrupt ausgelöst werden kann. In der ISR möchte ich dann den Wert des
OCR von Timer2 ändern. Timer2 wird im CTC Mode betrieben.
Leider passiert nichts. Die Werte ändern sich nicht und bleiben auf den
Initialisierten Werten. Folglich wird der Overflow Interrupt des Timer0
nicht aufgerufen. Komischerweise funktioniert aber der Compare Match
Interrupt, wenn ich ihn für Timer0 implementiere (also TIMSK0 =
1<<OCIE0A mit entsprechender ISR). Im AVR-Studio habe ich auch darauf
geachtet, dass das richtige Device ausgewählt ist.
Ich wäre euch sehr denkbar, wenn Ihr mich auf Fehler hinweisen könntet
bzw wisst, woran es liegen könnte.
1
#ifndef F_CPU
2
#define F_CPU 16000000UL // or whatever may be your frequency
Ich habe jetzt folgendes probiert:
Zur einfachen Signalgebung habe ich vor der while-Schleife einen Pin auf
High gesetzt. In der Overflow ISR habe ich diesen dann auf Low gesetzt.
Das funktionierte. Jedoch wird der Wert des OCR2A nicht geändert. Gibt
es innerhalb des ATMega Zugriffsbeschränkungen, welche nicht erlauben,
dass in einer ISR eines Timers Werte eines anderen Timers geändert
werden können?
Wie sieht deine Hardware aus? Ein Schaltplan wäre nützlich.
Im Zweifelsfall auch ein Bild deines Aufbaus.
Kannst du denn mit Sicherheit erkennen dass dein Programm
überhaupt läuft, dass dein Prozessor einen (und den richtigen)
Clock hat?
Interessent schrieb:> Leider passiert nichts. Die Werte ändern sich nicht und bleiben auf den> Initialisierten Werten.
Woran erkennst du das?
Mitlesa schrieb:> Wie sieht deine Hardware aus? Ein Schaltplan wäre nützlich.> Im Zweifelsfall auch ein Bild deines Aufbaus.>> Kannst du denn mit Sicherheit erkennen dass dein Programm> überhaupt läuft, dass dein Prozessor einen (und den richtigen)> Clock hat?>> Interessent schrieb:>> Leider passiert nichts. Die Werte ändern sich nicht und bleiben auf den>> Initialisierten Werten.>> Woran erkennst du das?
Der Aufbau ist recht einfach. Ich habe die jeweiligen Pins, die ich
benutze, an LEDs angeschlossen. Zusätzlich verwende ich ein Oszilloskop.
Dass die Werte sich nicht ändern erkenne ich am Oszilloskop. Wenn ich in
den ISR nichts mache, bleiben die Werte ohnehin auf den initialisierten
Werten, was ja auch so gewollt ist. Nehme ich nun in der ISR Änderungen
der OCRx-Register vor, ändern sich die Werte weiterhin nicht. Das tritt
allerdings nur bei der Overflow ISR auf! Ändere ich die Werte in der
Compare Match ISR, treten die gewollten Änderungen auf.
Interessent schrieb:> Der Aufbau ist recht einfach.
Das ist ein aussagekräftiger Schaltplan.
Auch den Aufbau kann man gut erkennen.
Nach den Angaben müsste ja alles funktionieren.
Interessent schrieb:> Der wird allerdings nicht viel zum lösen> des Problems beitragen.
Ja, weil ein unvollständiger Schaltplan kein Schaltplan ist.
Und weil ein Aufbau so gestaltet sein kann dass eine
Schaltung nicht funktioniert.
Nach dem gezeigten Schaltplan kann jedenfalls nichts funktionieren.
Minimum ist eine ausreichende Stromversorgung, Abblock Kondensatoren,
und - nach deiner Frequenzinformation zu urteilen - eine Beschaltung
mit Quarz und Last-Kondensatoren.
Da man dir offensichtlich jeden Popel einzeln aus der Nase ziehen
muss bin ich draussen.
Interessent schrieb:> Jedoch wird der Wert des OCR2A nicht geändert.
Wodurch stellst du das fest?
Dein Timer 0 wird mit 2 MHz getaktet. Als 8-Bit-Timer läuft er nach
128 µs über und ändert das OCR2A. Das ist verdammt häufig. Timer 2
läuft zu allem Überdruss mit konstant versetzter Phase zu Timer 0
über, denn er wird ebenfalls mit 2 MHz getaktet. Damit ist bekommt er
möglicherweise sowieso nur jede zweite Änderung von OCR2A überhaupt
mit. OCR2A wird in Zehnerschritten geändert, sodass es nach ca. 25
Änderungen wieder beim alten Wert ist, oder alle 3 Millisekunden.
Wenn du dir die LEDs mit dem Auge betrachtest, dürfte das Auge das
alles zu einer einzigen Helligkeit integrieren. Ein Oszi wäre sicher
schnell genug, die sich ändernde Modulation zu erfassen …
Davon abgesehen:
1
if(OCR2A>=254)
2
OCR2A=0;
Das wird kaum so funktionieren, wie du dir das vorstellst. Du startest
mit 79, es werden dann schrittweise 10 addiert, bis du irgendwann bei
249 bist. Im nächsten Schritt werden wieder 10 addiert, dann bist du
bei 3 (259 - 256), es geht weiter mit 13, 23, …, 253. Diese
if-Bedingung greift nur sowas von selten, dass du sie genauso gut
komplett weglassen kannst.
Interessent schrieb:> // Timer0: Enable Phase correct PWM(non-inverted), prescaler = 8> TCCR0A = (1<<WGM02) | (0<<WGM01) | (1<<WGM00) | (1<< COM0A1) | (0<<> COM0A0);
WGM02 befindet sich nicht in TCCR0A sondern in TCCR0B.
Bei dem zweiten Timer ist es genau so.
Holger L. schrieb:> Interessent schrieb:>> // Timer0: Enable Phase correct PWM(non-inverted), prescaler = 8>> TCCR0A = (1<<WGM02) | (0<<WGM01) | (1<<WGM00) | (1<< COM0A1) | (0<<>> COM0A0);>> WGM02 befindet sich nicht in TCCR0A sondern in TCCR0B.> Bei dem zweiten Timer ist es genau so.
Vielen Dank für den Hinweis!
Jörg W. schrieb:> Interessent schrieb:> Davon abgesehen:>>
1
>if(OCR2A>=254)
2
>OCR2A=0;
3
>
>> Das wird kaum so funktionieren, wie du dir das vorstellst. Du startest> mit 79, es werden dann schrittweise 10 addiert, bis du irgendwann bei> 249 bist. Im nächsten Schritt werden wieder 10 addiert, dann bist du> bei 3 (259 - 256), es geht weiter mit 13, 23, …, 253. Diese> if-Bedingung greift nur sowas von selten, dass du sie genauso gut> komplett weglassen kannst.
Besten Dank. Das hat mich auf den richtigen Weg gebracht!