////////////////////////////////////////////////////////////
// ATmega328p
// - Three timers: Timer 0, Timer 1, Timer 2
// - Each timer has two output compare registers
// that control the PWM width for the timer's two outputs
// - When the timer reaches the compare register value,
// the corresponding output is toggled.
// - The two outputs for each timer will normally have the
// same frequency, but can have different duty cycles.
////////////////////////////////////////////////////////////
#define OC2A 0x08
#define OC0A 0x40
int8_t delta1 = 1;
int8_t delta2 = -1;
ISR(TIMER2_COMPA_vect){
if (OCR2A == 255){
delta1 = -1;
}
else if(OCR2A == 0){
delta1 = 1;
}
OCR2A += delta1;
}
ISR(TIMER0_COMPA_vect){
if (OCR0A == 255){
delta2 = -1;
}
else if(OCR0A == 0){
delta2 = 1;
}
OCR0A += delta2;
}
void loop() {
}
void setup() {
// Disable global interrupt
cli();
// Setting output port
DDRB |= OC2A;
DDRD |= OC0A;
///////////////////////////////////////////////////////////
// Timer/Counter 2
// - RCCR2A = 0b 1000 0011;
// >> (011) Waveform Generation Mode: Fast PWM
// >> (10) Compare Output Mode: Clear OC2A on compare match
// - RCCR2B = 0b 0000 0111;
// >> (110) Clock Select: Prescaler 256
// - TIMSK2 = 0b 0000 0010;
// >> (1) Output Compare Match A Interrupt Enable
//
// Timer/Counter 0
// - RCCR0A = 0b 1000 0011;
// >> (011) Waveform Generation Mode: Fast PWM
// >> (10) Compare Output Mode: Clear OC0A on compare match
// - RCCR0B = 0b 0000 0011;
// >> (011) Clock Select: Prescaler 64
// - TIMSK0 = 0b 0000 0010;
// >> (1) Output Compare Match A Interrupt Enable
///////////////////////////////////////////////////////////
// Common settings
TCCR2A |= (1 << WGM21) | (1 << WGM20);
TCCR2B |= (1 << CS22) | (1 << CS21) | (0 << CS20); // prescaler
TCCR0A |= (1 << WGM01) | (1 << WGM00);
TCCR0B |= (0 << CS02) | (1 << CS01) | (1 << CS00);
// Setting for OC2A
TCCR2A |= (1 << COM2A1);
TIMSK2 |= (1 << OCIE2A);
// Setting for OC0A
TCCR0A |= (1 << COM0A1);
TIMSK0 |= (1 << OCIE0A);
// Output 1 (OC2A), initial frequency
// 16MHz / 256 (prescaler) / 256 (8-bit) = 244.14Hz
// Output 2 (OC0A), initial frequency
// 16MHz / 64 (prescaler) / 256 (8-bit) = 976.56Hz
// Output 1, initial duty cycle: (0 + 1) / 256 = 0.39%
OCR2A = 0;
// Output 2, initial duty cycle: (255 + 1) / 256 = 100%
OCR0A = 255;
// Enable global interrupt
sei();
}