Go Down

Topic: CTC - Timer 2 - TCCR2A - gezielter Reset notwendig - Warum? (Read 609 times) previous topic - next topic

combie

Ich sehe gerade, hier bist du mit deinem Problem voll abgeblitzt.

Habe ich auch Verständnis für.
Denn es ist ganz offensichtlich kein Problem der IDE.
Noch nicht mal der Tool Chain. (der erzeugte asm Code ist korrekt)

Wenn es das Problem überhaupt gibt, dann steckt es im µC selber.
In der Hardware.
Und da können wir alle nichts dran machen.

Merke:
> Wir können den Wind nicht ändern,
> aber die Segel anders setzen.
Der Pessimist sieht die Wolke vor der Sonne.
Der Optimist sieht die Sonne hinter der Wolke.

Mantra: Die Sonne scheint immer!


Doc_Arduino

Hallo,

mit Schadenfreude kann bei mir niemand Punkte sammeln.

Den Link werde ich mir anschauen. Danke. Ich forsche weiter ... ob es nur das eine Register betrifft oder nur Timer 2 ...

Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

combie

Quote
mit Schadenfreude kann bei mir niemand Punkte sammeln.
Die Schadenfreude existiert nur in deinem Kopf!

Merksatz:
> Ich bin verantwortlich, für das, was ich sage.
> Nicht für das, was du empfindest.
Der Pessimist sieht die Wolke vor der Sonne.
Der Optimist sieht die Sonne hinter der Wolke.

Mantra: Die Sonne scheint immer!

Doc_Arduino

Am Ende sind immer die anderen schuld die alles falsch verstehen. Ja ne is klar.

Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

combie

Wer Schuld sucht, wird welche finden.
Auch gerne bei anderen!
Der Pessimist sieht die Wolke vor der Sonne.
Der Optimist sieht die Sonne hinter der Wolke.

Mantra: Die Sonne scheint immer!

combie

Quote
Jedoch gibt es offensichtlich einen nicht logisch erklärbaren Abhängigkeitseffekt.
Bin eben auf ein ähnliches Problem gestoßen ...
Und bei der Fehlersuche, bin ich auch näher an dieses, dein Timerproblem heran gekommen.



Leider ist meine jetzige Ansage auch nur eine Hypothese.
Denn die Innereien des AVR Timers sind geheim.
Wir haben nur das Datenblatt.


Grundsätzlich, kann man den Timer als endlichen Automaten betrachten.
Eben nicht in Software, sondern in Hardware gegossen.

Und genau diesen Automaten bringst du in einen ungültigen Zustand, aus dem er sich mehr befreien kann.


Also meine Erkenntnis:
Das Problem besteht aus einer Kombination von 2 Gegebenheiten!

Erstens:
Der Timer befindet sich in Mode 1

Zweitens:
Es wird OCR2A = 249 gesetzt und sofort darauf der Timer in Mode 2 versetzt.


Das crashed.


Warum kommt der Automat dabei aus dem Tritt?

Im Mode 1 wirkt  OCR2A = 249 nicht auf dem Register direkt ausgeführt, sondern der Wert wird erst in ein Schattenregister geschrieben und beim Timer Überlauf dann ins Vergleichsregister.

OCR2A = 249 ist also nur ein Auftrag, der zur späteren Ausführung im Timer hinterlegt wird.


Im Mode 2 gibt es dieses Schattenregister nicht.

Erfolgt die Umschaltung von Mode 1 zu Mode 2 zu schnell, kann der Auftrag nicht ausgeführt werden, und der Timer bleibt hängen, der ganze AVR bleibt stehen.

Abhilfe 1:
Erst den Mode einstellen, und dann OCR2A setzen.

Abhilfe 2: (zum testen)
Nach OCR2A = 249 ein delay() einfügen, so dass der endliche Automat im Timer, die Chance bekommt den Auftrag auszuführen.

Es ist also der klemmende Auftrag, welcher den Timer/AVR ermordet.
Ich behaupte, das betrifft alle AVR mit diesem Schattenregister.


-----
Reicht dir das als Erklärung?




Der Pessimist sieht die Wolke vor der Sonne.
Der Optimist sieht die Sonne hinter der Wolke.

Mantra: Die Sonne scheint immer!

Doc_Arduino

Hallo,

deine Forschungsergebnisse decken sich mit denen von avrfreaks. Das reicht mir als Erklärung. Vielen Dank für deine Mühen. Wenn man das Problem verstanden hat kann man (ich) damit besser umgehen.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

combie

Mittlerweile, bin ich mit meinen Forschungen ein Stückchen weiter gekommen....

Eins war schon klar:

OCR2A = 249;
Wird nicht übernommen, wenn direkt danach in den CTC Mode gewechselt wird.

Bisher offen ist, warum dann alles stehen bleibt, auch eine serielle Ausgabe.

Da bin ich jetzt näher dran!
Code: [Select]

ISR(TIMER2_COMPA_vect)          // Timer 2 Interrupt

  /*
  static bool state = LOW;
  state = !state;
  digitalWrite(pin_T2, state);                   
  */
  PINB = _BV(PINB4); // Arduino Pin 10 schnell toggeln
}

Mit dieser ISR schafft  dein Programm wieder die Ausgaben.
Und es wird ein Signal an Pin 10 ausgegeben.

Der Grund für diese Verbesserung:
Da der Timer intern noch mit OCR2A == 0 läuft, da ja OCR2A = 249;  nicht zur Wirkung gekommen ist, läuft der Timer mit zu hoher Frequenz.
So hoher Frequenz, dass es nicht für deine ISR reicht.
Meine ist wesentlich schneller, darum läuft der Rest wieder.

Aber wenn man den Vorteiler auf 1 stellt, dann ist meine ISR auch zu langsam.
------


Warum stoppt die Serielle?
Warum stoppt delay() und millis()?

Die Interrupt Priorität von Timer2 ist höher, als die von der UART und von Timer0
Darum wird der Timer2 Interrupt immer bevorzugt behandelt.
Wenn der nächste Timer2 Interrupt anliegt, bevor der letzte fertig ist, dann haben wir den Salat.

So kommt es dann, dass Serial und delay() versagen.

---------
Und jetzt komme ich zum wunderlichsten Punkt:

Dass der Timer zu schnell läuft, kann man (mit meiner ISR) an Pin 10 messen.
Der Timer läuft mit OCR2A == 0 statt mit  OCR2A == 249

Das wunderliche ist aber, dass man beim Auslesen von OCR2A  genau die 249 erhält, die man meint auch da rein geschrieben zu haben, der Timer aber unbeirrt mit OCR2A == 0 läuft.

Grrr...

--------

Ich fasse zusammen:
  • Arduino Timer Initialisierung für PWM
  • CTC Timer Initialisierungsreihenfolge (double buffering von OCR2A)
  • ISR zu groß für diese Bedingungen
  • Interrupt Priorität
  • Falsche Werte beim auslesen von OCR2A


Ich schätze mal, dass ich damit den Zoo der Irritationen/Wunderlichkeiten vollständig beieinander habe.


Habe auch schon einen Namen dafür erfunden:

Ugly Timer Trap

Der Pessimist sieht die Wolke vor der Sonne.
Der Optimist sieht die Sonne hinter der Wolke.

Mantra: Die Sonne scheint immer!

Doc_Arduino

Hallo,

ich werde das nachstellen. Liest sich alles plausibel. Das war klare Forscherarbeit. Sehr schön.
Dann war ja meine zufällig geänderte Registerreihenfolge gar nicht sooo verkehrt.  :smiley-evil:
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Doc_Arduino

Hallo,

habe es nachgestellt.
a) Timer ISR Takt sehe ich
b) mit der verkürzten/optimierten ISR kommt die 2. serielle Ausgabe
c) mit Prescaler 1024 statt 64 und "langer" ISR kommt die 2. serielle Ausgabe auch
Also hängt er wie du sagst im Timer Interrupt fest.
Wieder etwas gelernt. Danke für die Aufarbeitung.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Go Up