hy,
hab die Tage wieder einmal den arduino (mit ATmega328P) in die Hand genommen und wollte ein paar Timer durch Bit-Manipulation konfigurieren, so dass diese 1s abzählen. Ausgabe durch umschalten (an <=> aus) von angeschlossenen LED's. Ich hatte jedoch nicht sehr viel Erfolg; allgemeines C-Beispiel zB
8bit timer (1s Zählzeit) => mein Arduino schaltet erst nach ca 2sek. anstatt nach einer...
Arduino spezifisch hab ich bisher nicht wirklich etwas hilfreiches gefunden

Von daher schaut bitte über meine Programme und erklärt was falsch ist. Wahrscheinlich hab ich irgendwelche grundlegenden, arduino-spezifischen Einstellungen/Regeln/Größen nicht beachtet.
die 3 Timer:
//---------------- 8bit-Timer, abzählen einer Sekunde ---------------- //
int counter = 0;
void setup(){
DDRD = 0xFF;
PORTD = 0x00;
DDRB = 0x3F;
PORTB = 0x00;
// Ausgänge, alle auf 0
TCCR2A = (1 << WGM21);
// CTC- Mode; Clear Timer on Compare Match
TCCR2B |= ((1 << CS22) | (1 << CS21) | (1 << CS20));
// prescaler: in diesem Fall clockspeed von 16MHz / 1024 = 15625Hz für den timer
OCR2A = 125;
// 15625 / 125 = 125 => nach 125 durchläufen ist eine Sekunde vorbei
TIMSK2 = (1 << OCIE2A);
//Compare A Match Interrupt Enable für timer2/counter2
// Vergleichswert = 125, Interrupt wird ausgelöst wenn TCNT2 = OCR2A
SREG = (1 << 7);
// interrupts enabled
}
void loop(){
while(1){
delay(1000); // überprüfen des Timers
PORTB = ~PORTB; //leds werden an bzw aus geschaltet (an <=> aus)
}
}
ISR(TIMER2_COMPA_vect){
if(counter <= 125){
counter++;
}
else{
counter = 0;
PORTD = ~PORTD;
}
}
// Ergebniss: ca 1s , aber nach 10s schon abweichung von +0,5s => da bei jedem durchlauf ISR zusätzlich Takte "hinzufügt" ?
//-----------------------------------------------------------//
//-----------8bit-Timer, abzählen einer Sekunde -------------//
int counter = 0;
void setup(){
DDRD = 0xFF;
PORTD = 0x00;
DDRB = 0x3F;
PORTB = 0x00;
// Ausgänge, alle auf 0
TCCR2B |= ((1 << CS22) | (1 << CS21) | (1 << CS20));
// prescaler: in diesem Fall clockspeed von 16MHz / 1024 = 15625Hz für den timer
TIMSK2 = (1 << TOIE2);
//overflow Interrupt Enable für timer2/counter2
SREG = (1 << 7);
// interrupts enabled
}
void loop(){
while(1){
delay(1000);
PORTB = ~PORTB;
// überprüfung, ob Timer stimmt
}
}
// Takt = 15625Hz geteilt durch 256 = 61,04 => nach rund 61 durchläufen ist eine Sekunde vorbei ?!
ISR(TIMER2_OVF_vect){
if(counter <= 61){
counter++;
}
else{
counter = 0;
PORTD = ~PORTD;
}
}
// Ergebniss : ungefähr 2s sind die LED's and, 2s aus usw Warum?
//-----------------------------------------------------------//
//-------------- 16bit Timer, abzählen einer Sekunde --------//
int counter = 0;
void setup(){
DDRD = 0xFF;
PORTD = 0x00;
DDRB = 0x3F;
PORTB = 0x00;
// Ausgänge, alle auf 0
SREG = (1 << 7);
// global interrupts enabled
TCCR1B |= ((1 << CS12) | (1 << WGM12));
//prescaler: in diesem Fall 16MHz /256 = 62500Hz für den timer // CTC- Mode => zählen bis vergleichswert, automatisch zurückgesetzt
TCNT1 = 0;
OCR1A = 0b1111010000100100;
// Vergleichswert = 62500 , Interrupt wird ausgelöst wenn TCNT1 = OCR1A
//62500 Takte werden gezählt mit Frequenz von 62500Hz => eine sekunde vorbei(?), durch interrupt werden leds an (für 1s) bzw ausgeschaltet (für 1s) => theoretisch
TIMSK1 = (1 << OCIE1A); //Output Compare A Match Interrupt Enable setzten
// spielt die Reihenfolge der Bit-Manipulation eine Rolle ?
}
void loop(){
while(1){
delay(1000);
PORTB = ~PORTB;
//zum vergleich, ob der timer 1s abzählt
}
}
ISR(TIMER1_COMPA_vect){
PORTD = ~PORTD; // schaltet LEDS ein und aus
}
/* => ERGEBNIS : LED's bleiben dauerhaft aus
Fehler ?
mit prescaler /64 sind die leds dauerhaft an (zu schnelles schalten für menschliches Auge ?!)
*/
habe versucht alle Schritte gut zu erklären.
Daten-Blatt:
atmega328PVielen Dank für eure Hilfe