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: atmega328P
Vielen Dank für eure Hilfe