Hallo,
ich versuche mit dem Nano und dem Timer1 einen Overflow interrupt nach ca. 32,768ms auszulösen.
Meine Annahmen:
- System Clock Frequenzey = 16.000.000 Hz
- Timer Resolution = 16 bit
- Prescaler = Clk/8
Mein Code sieht so aus:
Grundsätzlich funktioniert der Code auch, die Led wird getoggelt. Leider passt die Frequenz nicht. Mein Logicanalyzer sagt, Led = HIGH für 2ms und Led = LOW für 2ms. Das ganze hab ich noch mit dem Simulator im AVR Studio 7 überprüft. Gleiches Ergebnis.Code:int timer1_led = 12; ISR(TIMER1_OVF_vect) { digitalWrite(timer1_led, !digitalRead(timer1_led)); } void setup() { pinMode(timer1_led, OUTPUT); // ######### Timer 1 //Prescaler = 8 TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10); TCNT1 = 0; TIMSK1 |= (1 << TOIE1); sei(); } void loop() { while (1) { } }
Ich dachte ich hätte das mit den Timern so langsam verstanden... scheint noch nicht so zu sein.
Um rauszufinden ob ich einen Denkfehler habe oder mein Program falsch ist schreibe ich noch mal kurz was ich erwartet hätte.
Der Nano läuft mit 16 Mhz. Der Timer1 hat 16 bit, zählt also bis 65536 bis er den Overflowinterrupt auslöst. Mit dem Prescaler von 8 benötigt er dafür 32,768ms [Zeit = ( 2^16*8 )/16.000.000]. Dann springt er in die Interruptroutine und toggelt die Led.
Wo liegt mein Fehler? Fehlt noch ein Register was ich setzen muss? TCCR1A z.B.? Falls ja was muss ich da einstellen?
Vielen Dank.
Gruß Daniel
- - - Aktualisiert - - -
Na bitte...
Ich hab den Fehler selbst gefunden. Hier der korigierte Code:
Code:int timer1_led = 12; ISR(TIMER1_OVF_vect) { digitalWrite(timer1_led, !digitalRead(timer1_led)); } void setup() { pinMode(timer1_led, OUTPUT); // ######### Timer 1 TCCR1A = 0; //Prescaler = 8 TCCR1B = (0 << WGM13) | (0 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10); TCNT1 = 0; TIMSK1 = (1 << TOIE1); sei(); } void loop() { while (1) { } }
Der "|" hat das Fehlverhalten verursacht. Was genau das bedeutet muss ich noch nachlesen. Aber nicht mehr heute!
Unser Sommer ist ein grün angestrichener Winter. Das einzige reife Obst, das wir haben, sind gebratene Äpfel. [Heinrich Heine]
Wo hast Du denn den Code gefunden ??
Nu fällt´s mir schwer zu helfen, denn arduinoisch kann ich nicht. Und bei mir toggelts halt mit dem Code - simples C. Weils schnell gehen sollte mit Soft-Blinken auf PB5 (user definded LED); natürlich gehts auch mit Hardware-PWM auf PB1 (die ist auf meinem Clone-Testboard aber ohne LED ).. ich versuche mit dem Nano und dem Timer1 einen Overflow interrupt nach ca. 32,768ms auszulösen.
Ich hab den Fehler selbst gefunden. Hier der korigierte Code:Code:.. void setup() { pinMode(timer1_led, OUTPUT); // ######### Timer 1 //Prescaler = 8 TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10); TCNT1 = 0; TIMSK1 |= (1 << TOIE1); sei(); } ..
..
Der "|" hat das Fehlverhalten verursacht. Was genau das bedeutet muss ich noch nachlesen. Aber nicht mehr heute!
Code:// ============================================================================= = // == Timer Aufgabe: Soft-PWM ansteuern // Datenblatt Atmel-8271J-AVR- ATmega-Datasheet_11/2015 // - - - - - - - - - - - - - - - - void TC1TMR_init(void) // Init Timer/Counter 1 für 2 ms Servoperiode { // // - - - - - - - - - - - - - - - - // TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10); // Das ist Quatsch TCCR1B |= (1<<WGM12); // => CTC, TOP = OCR1A Doc Seite 133 TCCR1B |= (1<<CS11); // übliche Schreibweise für clk/8 => 2,000 MHz 134 //TCCR1B |= (1<<CS12); // Prescaler clk/256 => 136 // Wenn CS12 genommen wird, tickert der Interrupt mit 16MHz/256 => 62,5 kHz. // Dann kann mit // OCR1A = 1907; // => alle 32,774 ms 1 Interrupt gemessen werden // Bei dem von dir gewählten clk/8 bzw. 2 MHz müssen wir OCR1A höher ansetzen OCR1A = 61035; // => alle 32,768 ms 1 Interrupt gemessen werden // das ist schon etwas langsamer als Dein Wunsch // TCNT1 = 0; // Diese Festlegung versteh ich nicht ! ? ! ? TIMSK1 |= (1 << TOIE1); TIMSK1 |= (1<<OCIE1A); // Tmr/Cntr1 Oput CompA Mtch intrrpt enabled // - - - - - - - - - - - - - - - - } // ============================================================================= = // ============================================================================= = // === ISR für TIMER1_COMPA_vect ==================== = // Es wird NUR // - - - - - - - - - - - - - - - - ISR (TIMER1_COMPA_vect) // Servo[Svpt] wählen + dessen Rampe starten { // ToggleBit ( PORTB, PB5 ); // User defined LED // - - - - - - - - - - - - - - - - return; // // - - - - - - - - - - - - - - - } // Ende ISR (TIMER1_COMPA_vect) // ============================================================================= =
Ciao sagt der JoeamBerg
Lesezeichen