int timer0Counter = 0; // ตัวนับรอบ
volatile uint16_t overflowCount = 0;
void setupTimer0() {
noInterrupts();
// Clear registers
TCCR0A = 0;
TCCR0B = 0;
TCNT0 = 0;
// Set compare match register for 100 Hz
OCR0A = 156; // (16 MHz / (156 * 1024) = 100 Hz)
// CTC mode
TCCR0A |= (1 << WGM01);
// Prescaler = 1024
TCCR0B |= (1 << CS02) | (1 << CS00);
// Enable Timer 0 compare interrupt
TIMSK0 |= (1 << OCIE0A);
interrupts();
}
void setupTimer1() {
noInterrupts();
// Clear registers
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
// Set compare match register for 62.5 Hz
OCR1A = 7812.5; // (16 MHz / (7812 * 1024) = 2 Hz)
// CTC mode (Mode 4: WGM12)
TCCR1B |= (1 << WGM12);
// Prescaler = 1024
TCCR1B |= (1 << CS12) | (1 << CS10);
// Enable Timer 1 Compare Match A interrupt
TIMSK1 |= (1 << OCIE1A);
interrupts();
}
void setupTimer2() {
noInterrupts();
// Clear registers
TCCR2A = 0;
TCCR2B = 0;
TCNT2 = 0;
// Set compare match register for maximum value (255)
OCR2A = 255;
// CTC mode
TCCR2A |= (1 << WGM21);
// Prescaler = 1024
TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20);
// Enable Timer 2 Compare Match A interrupt
TIMSK2 |= (1 << OCIE2A);
interrupts();
}
void setupTimer3() {
noInterrupts();
// Clear registers
TCCR3A = 0;
TCCR3B = 0;
TCNT3 = 0;
// 10 Hz frequency (16 MHz / (1562 + 1) / 1024)
OCR3A = 1562; // Rounded value for 10 Hz
// CTC mode (Clear Timer on Compare Match)
TCCR3B |= (1 << WGM32);
// Prescaler = 1024
TCCR3B |= (1 << CS32) | (1 << CS30);
// Enable Timer3 Compare Match A Interrupt
TIMSK3 |= (1 << OCIE3A);
interrupts();
}
void setup() {
DDRC = 0xFF; // Set PORTC as output
setupTimer0();
setupTimer1();
setupTimer2();
setupTimer3();
}
void loop() {
// Main loop does nothing; everything is handled in the ISR
}
ISR(TIMER0_COMPA_vect) {
// Toggle PC6 and PC7 every 10 Hz
timer0Counter++;
if (timer0Counter >= 100) {
PORTC ^= (1 << PC0) | (1 << PC1) ; // Toggle LED
timer0Counter = 0;
}
}
ISR(TIMER1_COMPA_vect) {
// Toggle PC6 and PC7 every 10 Hz
PORTC ^= (1 << PC2) | (1 << PC3);
}
ISR(TIMER2_COMPA_vect) {
overflowCount++;
// Toggle every 13 overflows (~200 ms, which is 5 Hz)
if (overflowCount >= 13) {
PORTC ^= (1 << PC4) | (1 << PC5); // Toggle the LED or output on PC0
overflowCount = 0;
}
}
ISR(TIMER3_COMPA_vect) {
// Toggle PC6 and PC7 every 10 Hz
PORTC ^= (1 << PC6) | (1 << PC7);
}