DanielSan
15.09.2017, 17:29
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:
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)
{
}
}
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.
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:
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! :-)
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:
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)
{
}
}
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.
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:
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! :-)