Ich versuche, Timer1 auf dem ATtiny85 (Adafruit Trinket) zu verwenden, um jede Sekunde eine LED zu blinken. Der Prescaler-Wert ist 1024 und der Vergleichsregisterwert ist 28. Ich schleife dies 279 Mal durch, um eine Verzögerung von 1 Sekunde zu erhalten.
Mit dem folgenden Code bekomme ich ungefähr 8,5 Sekunden. Ich habe beim Kompilieren -mmcu=attiny85 und -DF_CPU=8000000UL gesetzt. Was könnte mir fehlen.
#include <stdint.h>
#include <avr/interrupt.h>
#define TIMER_OVERFLOW_COUNT 279
volatile uint16_t timerCount = TIMER_OVERFLOW_COUNT;
ISR(TIMER1_OVF_vect)
{
timerCount++;
}
int main(void)
{
DDRB = 1 << DDB1;
OCR1C = 28;
TIMSK = 1 << TOIE1;
sei();
TCCR1 = (1 << CS13) | (1 << CS11) | (1 << CS10);
while( 1)
{
if( timerCount >= TIMER_OVERFLOW_COUNT)
{
timerCount = 0;
PORTB ^= 1 << PORTB1;
}
}
return 0;
}
Die Sicherung CKDIV8 ist bei Geräten ab Werk programmiert. Wenn Sie vergessen, diese Sicherung zu deprogrammieren, läuft das Gerät mit 1/8 der erwarteten Taktfrequenz.
Eugen Sch.
timerCount
sowohl des Interrupt-Handlers als auch der Schleife ist eine schlechte Idee. Sie haben hier eine Race-Condition. Warum nicht die gesamte Logik in den Handler stecken? Es ist nicht so schwer.Arsenal
Bence Kaulics
Sub Thomas
Eugen Sch.
F_CPU
überhaupt benötigt? Ich denke, es wird nur für einige Bibliotheksverzögerungsfunktionen verwendet, die nicht im Code verwendet werden.Bence Kaulics
Eugen Sch.
Sub Thomas
Bence Kaulics
OCIE1C
Bit setzen, nicht dasTOIE1
inTIMSK
. So weit ich mich erinnere.Sub Thomas
Sub Thomas
Eugen Sch.
Bence Kaulics
OCR1C = 28
aber dann verwendenOCR1A = 28;
und einstellenOCIE1A
.Sub Thomas
Eugen Sch.
TIMER1_COMPA
.. man kann es auch sehr gut gebrauchen. Oder Sie können immer noch den Überlauf-Interrupt verwenden, wenn Sie den anfänglichen Timer-Wert jedes Mal korrekt berechnen (MAX-28).Sub Thomas
Eugen Sch.
Sub Thomas
Bence Kaulics
Sub Thomas
RWRkeSBZ