Ich hab hier ein interessantes Problem mit einem ATtiny84 (Atmel AVR Microcontroller).
Die Funktion von Timer0 wird mit den TCCR0A- und TCCR0B-Registern gesteuert. Die relevanten Bits sind in Kommentaren im Code unten markiert. Die Detailierte Beschreibung findet man im Datenblatt, aber hier eine kurze Zusammenfassung:
Bits A: "Output Compare Match B" wird auf den entsprechenden Ausgang geschaltet.
Bits B: "Fast PWM Mode": Der Timer beginnt bei 0 und der Ausgang wird eingschaltet. Der Timer zählt nach oben. Beim Erreichen von OCR0B wird der Ausgang ausgeschaltet. Beim Erreichen von OCR0A wird der Timer auf 0 zurückgesetzt.
Bits C: Prescaler. Bei 0b000 wird der Timer angehalten. bei 0b001 läuft der Timer mit der vollen Geschwindigkeit, bei höheren Werten (bis 0b101) läuft der Timer immer langsamer.
Wichtig dabei: Der Timer läuft komplett unabhängig vom Code. Die Geschwindigkeit des Timers hat keinen Einfluss auf den Code... oder sollte keinen Einfluss auf den Code haben, denn leider passiert genau das bei mir.
Folgender Aufbau:
Die gelbe LED hängt am Timer-Ausgang. Die rote und grüne LED werden im Code unten manuell ein- und ausgeschaltet.
Die Schleife in
Logischerweise gibt es keinen Grund, warum diese Wartezeiten pro Iteration der äußeren Schleife unterschiedlich sein sollten. Aber startet man den Microcontroller, zeigt sich folgendes Verhalten:
Also aus irgend einem Grund beeinflusst der Wert in TCCR0B die Geschwindigkeit, mit der der Code ausgeführt wird.
Kommentiert man die Zeile
Ich habe keinen Plan, was hier abgeht und würde mich über jede Hilfe freuen.
*Topic verschoben*
Die Funktion von Timer0 wird mit den TCCR0A- und TCCR0B-Registern gesteuert. Die relevanten Bits sind in Kommentaren im Code unten markiert. Die Detailierte Beschreibung findet man im Datenblatt, aber hier eine kurze Zusammenfassung:
Bits A: "Output Compare Match B" wird auf den entsprechenden Ausgang geschaltet.
Bits B: "Fast PWM Mode": Der Timer beginnt bei 0 und der Ausgang wird eingschaltet. Der Timer zählt nach oben. Beim Erreichen von OCR0B wird der Ausgang ausgeschaltet. Beim Erreichen von OCR0A wird der Timer auf 0 zurückgesetzt.
Bits C: Prescaler. Bei 0b000 wird der Timer angehalten. bei 0b001 läuft der Timer mit der vollen Geschwindigkeit, bei höheren Werten (bis 0b101) läuft der Timer immer langsamer.
Wichtig dabei: Der Timer läuft komplett unabhängig vom Code. Die Geschwindigkeit des Timers hat keinen Einfluss auf den Code... oder sollte keinen Einfluss auf den Code haben, denn leider passiert genau das bei mir.
Folgender Aufbau:
Die gelbe LED hängt am Timer-Ausgang. Die rote und grüne LED werden im Code unten manuell ein- und ausgeschaltet.
C-Quellcode
- void setup()
- {
- // Alle Pins auf Ausgang stellen.
- DDRA = 0xFF;
- DDRB = 0xFF;
- // Periodendauer und Pulsweite
- OCR0A = 10;
- OCR0B = 1;
- // AA BB
- TCCR0A = 0b00100001;
- // BCCC
- TCCR0B = 0b00001000;
- }
- void loop()
- {
- for (byte b = 0b000; b <= 0b101; b++)
- {
- TCCR0B = 0b00001000 | b;
- PORTB |= 0b00000001; // Grün ein
- for (volatile int i = 0; i < 0x1000; i++) asm volatile ("NOP");
- PORTB &= ~0b00000001; // Grün aus
- for (volatile int i = 0; i < 0x1000; i++) asm volatile ("NOP");
- PORTB |= 0b00000010; // Rot ein
- for (volatile int i = 0; i < 0x1000; i++) asm volatile ("NOP");
- PORTB &= ~0b00000010; // Rot aus
- for (volatile int i = 0; i < 0x1000; i++) asm volatile ("NOP");
- }
- }
Die Schleife in
void loop()
setzt den Prescaler und lässt dann zuerst die rote LED blinken, und dann die grüne. Die for-Schleifen dazwischen vertrödeln einfach nur etwas Zeit.Logischerweise gibt es keinen Grund, warum diese Wartezeiten pro Iteration der äußeren Schleife unterschiedlich sein sollten. Aber startet man den Microcontroller, zeigt sich folgendes Verhalten:
- Die gelbe LED ist ausgeschaltet, da der Timer noch nicht läuft (Prescaler = 0b000).
Die grüne LED blinkt, dann die rote. Das passiert relativ schnell. Es dauert ca. 0.5 Sekunden. - Die gelbe LED schaltet ein, weil der Timer jetzt läuft (Prescaler = 0b001).
Die grüne LED blinkt, dann die rote. Das geschieht jetzt aber sehr langsam. Es dauert ca. 20 Sekunden. - Die grüne LED blinkt, dann die rote. Das geschieht jetzt schneller als vorher. Ca. 1 Sekunde.
- Für die restlichen Iterationen dauert das Blinken dann wieder ca. 0.5 Sekunden (aber nie weniger).
- Die gelbe LED schaltet wieder aus, sobald der Prescaler auf 0b000 gesetzt wird.
Also aus irgend einem Grund beeinflusst der Wert in TCCR0B die Geschwindigkeit, mit der der Code ausgeführt wird.
Kommentiert man die Zeile
TCCR0B = 0b00001000 | b;
aus, blinken die LEDs konstant ca. alle 0.5 Sekunden.Ich habe keinen Plan, was hier abgeht und würde mich über jede Hilfe freuen.
*Topic verschoben*
"Luckily luh... luckily it wasn't poi-"
-- Brady in Wonderland, 23. Februar 2015, 1:56
Desktop Pinner | ApplicationSettings | OnUtils
-- Brady in Wonderland, 23. Februar 2015, 1:56
Desktop Pinner | ApplicationSettings | OnUtils
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()